--- - name: Ensure mandatory variables are configured assert: that: "{{ item }} is defined" fail_msg: "You must define the '{{ item }}' variable" with_items: - new_hetzner_server_name - new_hetzner_server_type - new_hetzner_server_image - name: Include resource variables include_vars: "{{ role_path }}/../../resources/{{ lookup('env', 'MEMBERS_FILE') | default('members.yml', True) }}" # Note(decentral1se): gives root SSH access for all autonomic members - name: Ensure all Autonomic member SSH keys are registered hcloud_ssh_key: name: "{{ item.email }}" api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}" public_key: "{{ item.ssh_key }}" state: present with_items: "{{ members }}" - name: Create new hetzner cloud instance hcloud_server: api_token: "{{ lookup('env', 'HCLOUD_TOKEN') }}" image: "{{ new_hetzner_server_image }}" name: "{{ new_hetzner_server_name }}" server_type: "{{ new_hetzner_server_type }}" ssh_keys: "{{ members | map(attribute='email') | list }}" labels: managed: ansible backups: "{{ new_hetzner_backups_enabled }}" delete_protection: "{{ new_hetzner_delete_protection }}" rebuild_protection: "{{ new_hetzner_rebuild_protection }}" state: present register: new_instance async: 7200 poll: 0 - name: Wait for instance creation to complete async_status: jid: "{{ new_instance.ansible_job_id }}" register: hetzner_job until: hetzner_job.finished retries: 300 # Note(decentral1se): before user accounts are created we connect as root. This # is possible because we registered the SSH keys with Hetzner Cloud and when # the new instance is created, those keys are in /root/authorized_keys - name: Dynamically create root connection details for the new instance add_host: hostname: root-new-instance ansible_host: "{{ hetzner_job.hcloud_server.ipv4_address }}" ansible_ssh_extra_args: "-o StrictHostKeyChecking=no" ansible_user: root - name: "Wait for SSH on {{ new_hetzner_server_name }} to come up on port 22" wait_for: port: 22 host: "{{ hetzner_job.hcloud_server.ipv4_address }}" search_regex: SSH delay: 10 - name: Run the add-users role on the new instance vars: members: "../../../resources/members.yml" delegate_to: root-new-instance import_role: name: autonomic.add-users tags: - molecule-notest - name: Run the sshd role on the new instance delegate_to: root-new-instance import_role: name: autonomic.sshd tags: - molecule-notest - name: Run all service restart handlers delegate_to: root-new-instance meta: flush_handlers tags: - molecule-notest - name: "Wait for SSH to come up again on {{ sshd_port }}" wait_for: port: "{{ sshd_port }}" host: "{{ hetzner_job.hcloud_server.ipv4_address }}" search_regex: SSH delay: 10 tags: - molecule-notest # Note(decentral1se): At this point we're connecting with our own new user # account and using sudo based privilege escalation with the password generated # by pass from the passwords repository. Dog fooding our own connection setup ensures it # works - name: "Dynamically create {{ lookup('env', 'REMOTE_USER') }} connection details for the new instance" add_host: hostname: user-new-instance ansible_host: "{{ hetzner_job.hcloud_server.ipv4_address }}" ansible_ssh_extra_args: "-o StrictHostKeyChecking=no" ansible_user: "{{ ansible_user }}" ansible_port: "{{ sshd_port }}" # Note(decentral1se): Ansible refuses to use the correct password without specifying both of these ansible_sudo_pass: "{{ lookup('passwordstore', 'users/{{ ansible_user }}/sudo/{{ new_hetzner_server_name }}') }}" ansible_become_password: "{{ lookup('passwordstore', 'users/{{ ansible_user }}/sudo/{{ new_hetzner_server_name }}') }}" tags: - molecule-notest - name: Run the ufw role on the new instance delegate_to: user-new-instance become: true import_role: name: autonomic.ufw tags: - molecule-notest - name: Run the packages role on the new instance delegate_to: user-new-instance become: true import_role: name: autonomic.packages tags: - molecule-notest - name: Run the name role on the new instance delegate_to: user-new-instance become: true import_role: name: autonomic.name tags: - molecule-notest - name: Run the motd role on the new instance delegate_to: user-new-instance become: true import_role: name: autonomic.motd tags: - molecule-notest