Skip to content

Commit

Permalink
Add config to externally provide private SSH key used for provision a…
Browse files Browse the repository at this point in the history
…nd destroy at EC2 (#5060)

* Using externally provided private SSH key for provision

The create_ssh_provision_key infra-role generates and store new SSH
key pair for each provisioning job. Plus setting following environment
variables:
- ssh_provision_pubkey_content
- ssh_provision_pubkey_path
- ssh_provision_key_path
- ssh_provision_key_name

In some cases this algorithm is not working well (e.g., the key pair can be lost
if not stored at persistent storage and destroy job will fail). This
change allow to bring your own permanent key by setting following
variables:
- ssh_provision_key_path
- ssh_provision_key_name
- ssh_provision_pubkey_content (optional)

And this provided key will be reused by provisioning and destroy jobs.

For example set following variables at AgnosticV:

ssh_provision_key_name: "my_private_ssh_key.pem"
ssh_provision_key_path: "/home/account/.ssh/{{ ssh_provision_key_name }}"
ssh_provision_pubkey_content: ssh-rsa AAAAB3NzaC1 ...rest of the key... JjQ==

* Removing checks

* Updating documentation

* Fixing linter errors
  • Loading branch information
makirill authored Jul 13, 2022
1 parent d0d9420 commit 7ef1a2c
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 6 deletions.
2 changes: 2 additions & 0 deletions ansible/cloud_providers/ec2_destroy_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- name: Set facts for ssh provision SSH key
include_role:
name: create_ssh_provision_key
when:
- ssh_provision_key_name is undefined

- name: Destroy infra ec2 keypair
include_role:
Expand Down
4 changes: 3 additions & 1 deletion ansible/cloud_providers/ec2_infrastructure_deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@
- name: Create ssh provision key
include_role:
name: create_ssh_provision_key
when: instances | default([]) | length > 0
when:
- instances | default([]) | length
- ssh_provision_key_name is undefined

- name: Locate environment SSH key
include_role:
Expand Down
2 changes: 2 additions & 0 deletions ansible/configs/hybrid-cloud/destroy_env_ec2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
- name: Create local ssh provision facts (key already exists)
include_role:
name: create_ssh_provision_key
when:
- ssh_provision_key_name is undefined

- name: SSH config setup
when:
Expand Down
2 changes: 2 additions & 0 deletions ansible/configs/ocp4-cluster/destroy_env_ec2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
- name: Create local ssh provision facts (key already exists)
include_role:
name: create_ssh_provision_key
when:
- ssh_provision_key_name is undefined

- name: SSH config setup
when:
Expand Down
12 changes: 12 additions & 0 deletions ansible/roles-infra/infra-ec2-ssh-key/tasks/create.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@

- when: stat_infra_ssh_key.stat.exists
block:
- when: ssh_provision_pubkey_content is not defined
block:
- name: Generate SSH pub key content
command: >-
ssh-keygen -y -f {{ ssh_provision_key_path | quote }}
changed_when: false
register: r_ssh_provision_pubkey

- name: Save all facts for SSH
set_fact:
ssh_provision_pubkey_content: "{{ r_ssh_provision_pubkey.stdout.strip() }}"

- name: Create infra key
environment:
AWS_ACCESS_KEY_ID: "{{ aws_access_key_id }}"
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/control-user/tasks/ssh-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

- name: copy the environment .pub key
copy:
src: "{{ hostvars.localhost.env_authorized_key_path_pub }}"
content: "{{ hostvars.localhost.env_authorized_key_content_pub }}"
dest: "/home/{{ control_user_name }}/.ssh/{{env_authorized_key}}.pub"
owner: "{{ control_user_name }}"
group: "{{ control_user_private_group }}"
Expand Down
2 changes: 1 addition & 1 deletion ansible/roles/locate_env_authorized_key/readme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The main reason is to facilitate the transition of all configs and roles to a co

This role, `locate_env_authorized_key`, will use the available keys if found, in order:

* `ssh_provision_key` - created by `create_ssh_provision_key`
* `ssh_provision_key` - created by `create_ssh_provision_key` or re-used existent one
* `infra_ssh_key` - created by OSP heat template
* defaults to `{{ output_dir }}/{{ env_authorized_key }}`
** generally the key is created directly in the config
Expand Down
11 changes: 9 additions & 2 deletions ansible/roles/locate_env_authorized_key/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
delegate_facts: true
set_fact:
env_authorized_key_path_pub: >-
{{ hostvars.localhost.env_authorized_key_path
| regex_replace('\.pem$', '') }}.pub
{%- if hostvars.localhost.ssh_provision_pubkey_path is defined -%}
{{ hostvars.localhost.ssh_provision_pubkey_path }}
{%- else -%}
{{ output_dir }}/{{ hostvars.localhost.ssh_provision_key_name | regex_replace('\.pem$', '') }}.pub
{%- endif -%}
- name: Generate SSH pub key content if it doesn't exist
shell: >-
Expand All @@ -37,4 +40,8 @@
become: false
set_fact:
env_authorized_key_content_pub: >-
{%- if hostvars.localhost.ssh_provision_pubkey_content is defined -%}
{{ hostvars.localhost.ssh_provision_pubkey_content }}
{%- else -%}
{{ lookup('file', hostvars.localhost.env_authorized_key_path_pub) }}
{%- endif -%}
2 changes: 1 addition & 1 deletion ansible/roles/set_env_authorized_key/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- name: copy the environment .pub key
become: true
copy:
src: "{{ hostvars.localhost.env_authorized_key_path_pub }}"
content: "{{ hostvars.localhost.env_authorized_key_content_pub }}"
dest: "/root/.ssh/{{ env_authorized_key }}.pub"
owner: root
group: root
Expand Down
16 changes: 16 additions & 0 deletions docs/SSH_keys_and_access.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@ all_ssh_authorized_keys:
----
. DESTROY role `infra-{{ cloud_provider }}-ssh-key` to delete the keypair in the cloud provider

== Bring your own provision key ==
In some cases the SSH key generation described above is not working well (e.g., the key pair can be lost if not stored at persistent storage and destroy job will fail).
It is possible to specify existed SSH key which will be used for the environment provisioning and destroy by setting following variables:

* `ssh_provision_key_path`
* `ssh_provision_key_name`
* `ssh_provision_pubkey_content` (optional)
+
[source,yaml]
.example setting `ssh_privision_*` variables
----
ssh_provision_key_name: "my_private_ssh_key.pem"
ssh_provision_key_path: "/home/account/.ssh/{{ ssh_provision_key_name }}"
ssh_provision_pubkey_content: ssh-rsa AAAAB3NzaC1 ...rest of the key... JjQ==
----

== Roles ==

* `create_ssh_provision_key`
Expand Down

0 comments on commit 7ef1a2c

Please sign in to comment.