If you are not familiar with modules, check out Ansible - Getting Started with Modules.
The authorized_key module can be used to append or remove public certificates from an authorized_keys file. Before using this module, you may want to use the openssh_keypair or openssh_cert modules to generate a public certificate.
--ask-pass flag
When using the ansible-playbook command, assuming the SSH server on the managed node is configured to accept password authentication and the authorized_keys file on the managed node does not already contain the users public certificate, you will have to include the --ask-pass flag to connect to the managed node. After the users public certificate has been appended to the authorized_keys file on the managed node, assuming the SSH server on the managed node is configured to accept publickey authentication, you should then no longer have to use the --ask-pass flag when using the ansible-playbook command to connect to the managed node.
Append a certificate
Let's say id_rsa.pub on the control node (that's the Ansible server) contains the following.
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqlNpcovu736RD0kiDno7+VB7rTS0jWJrbFEazgCKCYPtVb9bJ9A0tX42wQqsuzSqJ/+fkRJZcDapwZffuMEPZ4lLTS6vgyHI2o8NJk/lXggizOsHJFZyd7sGnnk/ynso86Rl4XA/dKkvwBS3ROrD3r8O1sPEoRKEgt5vwlwYMslSsL1qa0lL/20TuWx78GKEX0b9PI7ZRRMvC5wWS5CRwmvaL8U6N/FUcJYFPcNIy0dIh2mfhUwqnqfxEqYsddN1id8fUm46SwsGgWOTjMKA/OHi5y7gHvQ5wnNlk4c+/55cytwm9wBW5taDRc0ndPOPmWb/YMtMHY7obA+wV8/57
When the user parameter is used, the public certificate will be appended to /home/username/.ssh/authorized_keys on the managed node. In this example, the public certificate will be appended to /home/john.doe/.ssh/authorized_keys.
- name: Append /home/john.doe/.ssh/id_rsa.pub on the control node to /home/john.doe/.ssh/authorized_keys on the managed node
authorized_key:
user: john.doe
key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqlNpcovu736RD0kiDno7+VB7rTS0jWJrbFEazgCKCYPtVb9bJ9A0tX42wQqsuzSqJ/+fkRJZcDapwZffuMEPZ4lLTS6vgyHI2o8NJk/lXggizOsHJFZyd7sGnnk/ynso86Rl4XA/dKkvwBS3ROrD3r8O1sPEoRKEgt5vwlwYMslSsL1qa0lL/20TuWx78GKEX0b9PI7ZRRMvC5wWS5CRwmvaL8U6N/FUcJYFPcNIy0dIh2mfhUwqnqfxEqYsddN1id8fUm46SwsGgWOTjMKA/OHi5y7gHvQ5wnNlk4c+/55cytwm9wBW5taDRc0ndPOPmWb/YMtMHY7obA+wV8/57"
When the path parameter is used, the public certificate will be appended to whatever file is defined in path. In this example, the public certificate will be appended to /etc/ssh/authorized_keys.
- name: Append /home/john.doe/.ssh/id_rsa.pub on the control node to /etc/ssh/authorized_keys on the managed node
authorized_key:
path: /etc/ssh/authorized_keys
key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqlNpcovu736RD0kiDno7+VB7rTS0jWJrbFEazgCKCYPtVb9bJ9A0tX42wQqsuzSqJ/+fkRJZcDapwZffuMEPZ4lLTS6vgyHI2o8NJk/lXggizOsHJFZyd7sGnnk/ynso86Rl4XA/dKkvwBS3ROrD3r8O1sPEoRKEgt5vwlwYMslSsL1qa0lL/20TuWx78GKEX0b9PI7ZRRMvC5wWS5CRwmvaL8U6N/FUcJYFPcNIy0dIh2mfhUwqnqfxEqYsddN1id8fUm46SwsGgWOTjMKA/OHi5y7gHvQ5wnNlk4c+/55cytwm9wBW5taDRc0ndPOPmWb/YMtMHY7obA+wV8/57"
Instead of using the actual public certificate string, the lookup plugin can be used.
- name: Append /home/john.doe/.ssh/id_rsa.pub on the control node to /home/john.doe/.ssh/authorized_keys on the managed node
authorized_key:
user: john.doe
key: "{{ lookup('file', '/home/john.doe/.ssh/id_rsa.pub') }}"
Remove a certificate
When the state parameter has a value of absent, the certificate will be removed.
- name: Remove John Doe's public certificate from the authorized_keys file on the managed node
authorized_key:
path: /etc/ssh/authorized_keys
state: absent
key: "{{ lookup('file', '/home/john.doe/.ssh/id_rsa.pub') }}"
Permission Denied
Let's say the following is returned. Typically, this means you are invoking the playbook as a user that does not have permission to access John Doe's home directory (/home/john.doe).
[WARNING]: Unable to find '/home/john.doe/.ssh/id_rsa.pub' in expected paths.
Register / Debug
The register parameter and debug module can then be used to output the results. In the scenario where id_rsa.pub is successfully appended to the authorized_keys file, something like this should be returned.
TASK [print the 'out' variable]
ok: [server1.example.com => {
"out": {
"changed": true,
"comment": null,
"exclusive": false,
"failed": false,
"follow": false,
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDD9Kkwp0hH4dfDrhmyy9aXfpAykF5eZR9DvUpSj7p0cJ89Npul7sBhTE5ILV/cZOXnPcQmRNROIGFczv3Io9qHK/V4jNhGM+W+tL9QhiWF4FTqyO8cE8LyExV2WbmeJRTijY7DSXxL69vczYLhSptEFIh5+uHsdjbLN8AhZJ5mJwLcDA32vwav5X5QaSwUja3gIzLwHDfkREef+53l4B8XSQoVcgmxiAcNcIydfzZGmWHT2icwNujDYWLgyu/uu3HkV1E3ACxJuk8pkh3fPWNCuBu1cincd0z270OlbByj2ocobnUtXKDw8DT34Oz1NHMsnIFuG6ho1inp0eQ1yY7v john.doe@ansible.example.com",
"key_options": null,
"keyfile": "/home/john.doe/.ssh/authorized_keys",
"manage_dir": true,
"path": null,
"state": "present",
"user": "john.doe",
"validate_certs": true
}
}