Add/remove pub key with

Hello!
Im testing to use files with multiple keys in the.keys file.
My playbook successfully copies the keys, but in a single line.
Is it possible to use comments so you could see which key belongs to whom.
Playbook:

---
- name: Set authorized keys from gitlab
  hosts: all
  gather_facts: false
  vars:
    key_url: "http://192.168.151.237/awx/playbooks_pub/-/raw/main/ssh/granted_keys/granted.keys"
    key_content: "{{ lookup('url', key_url, split_lines=true) }}"
    
  tasks:
    - name: Set authorized keys taken from url
      ansible.posix.authorized_key:
        user: root
        state: present
        key: "{{ key_content }}"
        path: /root/.ssh/authorized_keys

The key are one in each line like you would do in a authorized_keys file.

Thank you very much again!

ansible.posix.authorized_key supports a comment parameter. The comment appears at the right (vs. “left”, not vs. “wrong”) end of the line.

If your want comments on their own lines, then you could follow the authorized_key task with an ansible.builtin.lineinfile task and use its insertbefore parameter, but that could get more tedious than it’s worth.

Yeah i got one with newline for adding a single key, but changing it would be quite miserable and then remove would be even more exhausting. I think it would be better to just copy an inital authorized hosts file with the comments.

The guide means the diffrent keys should be seperated by a newline separator, but i have no idea whats that.
Adding \n after each line doesnt do the job.

That would mean if you have a list of keys, then you can say

    key: "{{ list_of_keys | join('\n') }}"

BTW, note the quoting above. That “\n” is in a double-quoted string – as are the single quotes on either side of it. So it becomes a literal new-line character in a single-quoted string parameter to join(). You can do it other ways, but run tests to make sure you’re doing what you mean to do. I suspect that’s what sank your attempt at adding \n after each line.

1 Like

I thought i could use from here this :

- name: Set authorized keys taken from url using lookup
  ansible.posix.authorized_key:
    user: charlie
    state: present
    key: "{{ lookup('url', 'https://github.com/charlie.keys', split_lines=False) }}"

to add ultiple keyys from my gl:


and can add/ remove multiple ones in one go or do i have do download the file to temp like a regular txt file and add them from local, but how do i get it to correctly inserted in 3 row again but not like now in a single one.
Copying would be useless because then you loose the feature to see if one of those aleready exist in the authorized_keyes file.
Thank you!

If you want those three and only those three, then put the three keys in a “\n”-joined string and use the exclusive parameter. This will remove any other keys from the file and ensure those three remain. It makes no guarantees about the order.

Wenn i want to rverse the Playbook to remove mthe keys in the file i cant use the /n at the keys because i think whey wont be recognised then from the open ssh service.
I thought it could be easier just to tell to look in each row without manually setting a seperator.

My bot suggests me to use a loop all the time:

---
- name: Set authorized keys from gitlab
  hosts: all
  become: true
  vars:
    key_url: "http://192.168.151.237/awx/playbooks_pub/-/raw/main/ssh/granted_keys/granted.keys"

  tasks:
    - name: Fetch SSH keys from URL
      ansible.builtin.uri:
        url: "{{ key_url }}"
        return_content: yes
        validate_certs: no 
      register: downloaded_keys
      delegate_to: localhost
      run_once: true

    - name: Set authorized keys taken from URL
      ansible.posix.authorized_key:
        user: root
        state: present
        key: "{{ item }}"
        path: /root/.ssh/authorized_keys
      loop: "{{ downloaded_keys.content.splitlines() }}"
      when: downloaded_keys.content is defined and downloaded_keys.content | length > 0

But the example in the guide with the .keys file mage me believe that you could either use a single public key or a list with keys in each row without any other changes to the playbook.

I found a method for ansible:

 roles/users/vars/main.yaml

---
users:
  - username: foo
    public_key: ssh-rsa IKUJHYFGukjyFUKtyfUKYTVkUYVukyGVkjyhGjkhgKjh
    active: true
  - username: bar
    public_key: ssh-rsa klJHGJKfghjktRYKrKJhGjklYgkJhgKjhGjkHbKjhgJK
    active: false

roles/users/tasks/main.yaml

---
- name: Copy public keys to the hosts
  ansible.posix.authorized_key:
    user: "{{ item.username }}"
    key: "{{ item.public_key }}"
    state: present
  with_items: "{{ users }}"
  when: item.active
  loop_control:
    label: "{{ item.username }}"

Can i use this in AWX like this too without including the var main file?

Thank you!

i cnt use a folder with the name roles in my gitlab - the playbooks wont be shown in the templates - dont know why

Yes you can, but users will need to be initialized somehow.

I’m not at all sure what you’re trying to say here. We use on-prim gitlab and practically every project has a folder named roles. I’m not saying you’re wrong, but I’ll need more evidence to be persuaded.

It’s the next bit that makes me wonder which one of us is more confused. Playbooks don’t go in templates because … they aren’t templates. (?) Maybe the output of tree -d would help clarify how you’re structuring things. We typically structure our projects like this:

playbook1.yml
playbook2.yml
playbook3.yml
group_vars
├── all
├── admin
└── swing
roles/
├── role1
│   ├── files
│   ├── handlers
│   └── tasks
├── role2
│   ├── files
│   │   ├── apache
│   │   │   └── ssl
│   │   └── shibboleth
│   ├── handlers
│   ├── tasks
│   └── templates
│       └── apache
└── role3
    ├── defaults
    ├── files
    ├── filter_plugins
    ├── tasks
    └── templates
1 Like

When i named a folder in gitlab Roles or vars the files they contained would not be listed if i look through the playbooks in a template - i changed the name in functions and everything was visible again:

I have a solution for multiple keys:

---
- name: Copy public keys to the hosts
  hosts: all
  gather_facts: false
  tasks:
    - name: Download allowed.yaml from GitLab
      ansible.builtin.uri:
        url: "http://192.168.151.237/awx/playbooks_pub/-/raw/main/functions/public_key/variables/allowed.yaml"
        dest: "/tmp/allowed.yaml"
        method: GET
        return_content: yes
      delegate_to: localhost
      run_once: true

    - name: Include vars from the allowed.yaml file
      ansible.builtin.include_vars:
        file: "/tmp/allowed.yaml"
        name: "users"

    - name: Copy public keys with comments to the authorized_keys of the user
      ansible.posix.authorized_key:
        user: "{{ item.username }}"
        key: "{{ item.public_key }} {{ item.comment }}"
        state: present
      loop: "{{ users.users }}"
      when: item.active
      loop_control:
        label: "{{ item.username }}"

Like this the comment seems to be part of the public key and will be removed with the key if necessary

Ah, when you say “look through the playbooks in a template”, you’re speaking about a “playbooks” pull-down in an AWX job template’s web-ui. I thought you meant the templates directory in an Ansible project root or a roles/rolename/templates sub-directory of an Ansible project. Totally different kind of template! Of course it wouldn’t make sense to put playbooks in a templates directory.

AWX will only search for playbooks in those places that are valid for holding playbooks. Playbooks can’t go in or under a roles directory, so that’s why AWX wasn’t listing any YAML files in your roles directory as playbooks in your AWX job template’s “playbook” pull-down.

You have an, um, interesting project structure. Do you have any guidelines to follow when deciding whether something should go in a playbook vs. in some task file in a role?

1 Like

The Folder structure is not final.
I have to clean up a little more :laughing:

1 Like