feat: Add passphrase capabilities for SSH key (#11)
All checks were successful
continuous-integration/drone/push Build is passing

We can now use encrypted SSH keys in the pipeline.
The new secret is `deploy_ssh_key_passphrase`

The documentation has been updated accordingly

Co-authored-by: Ereshkigal <ereshkigal@noreply.dev.sp-tarkov.com>
Reviewed-on: SPT-AKI/Website#11
Co-authored-by: shirito <shirito@noreply.dev.sp-tarkov.com>
Co-committed-by: shirito <shirito@noreply.dev.sp-tarkov.com>
This commit is contained in:
shirito 2021-11-04 01:21:44 +00:00
parent bdae2c47fb
commit 4bb11f731c
6 changed files with 95 additions and 62 deletions

View File

@ -1,2 +1,11 @@
[host] all:
{{ DEPLOYMENT_USER }}@{{ DEPLOY_HOSTNAME }} ansible_connection=ssh ansible_user={{ DEPLOYMENT_USER }} children:
sptarkov:
hosts:
sp-tarkov:
ansible_host: {{ DEPLOY_HOSTNAME }}
ansible_user: {{ DEPLOY_USER }}
ansible_connection: paramiko_ssh
ansible_ssh_pass: {{ DEPLOY_SSH_KEY_PASSPHRASE }}
ansible_ssh_user: {{ DEPLOY_USER }}
ansible_ssh_private_key_file: /drone/src/private.key # Hardcoded because created by the Drone plugin

View File

@ -1,6 +1,6 @@
--- ---
- name: install and configure PHP8 and composer - name: install and configure PHP8 and composer
hosts: host hosts: sptarkov
tasks: tasks:
- name: Delete spt-items-api before adding everything again - name: Delete spt-items-api before adding everything again
@ -36,8 +36,8 @@
- name: Reset files permissions - name: Reset files permissions
file: file:
path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}" path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}"
owner: "{{ lookup('env', 'DEPLOYMENT_USER') }}" owner: "{{ lookup('env', 'DEPLOY_USER') }}"
group: "{{ lookup('env', 'DEPLOYMENT_USER_GROUP') }}" group: "{{ lookup('env', 'DEPLOY_USER_GROUP') }}"
mode: 0774 mode: 0774
recurse: yes recurse: yes

View File

@ -21,13 +21,19 @@ steps:
from_secret: deploy_hostname from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOY_SSH_KEY_PASSPHRASE:
from_secret: deploy_ssh_key_passphrase
DEPLOY_PRIVATE_KEY:
from_secret: deploy_ssh_key
commands: commands:
- sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example - sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example
- mv ./items/frontend/.env.example ./items/frontend/.env - mv ./items/frontend/.env.example ./items/frontend/.env
- sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory - echo "$DEPLOY_PRIVATE_KEY" > private.key && chmod 600 private.key
- sed -i 's/{{ DEPLOYMENT_USER }}/'"$DEPLOYMENT_USER"'/g' ./.ansible-items/inventory - sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_SSH_KEY_PASSPHRASE }}/'"$DEPLOY_SSH_KEY_PASSPHRASE"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_USER }}/'"$DEPLOY_USER"'/g' ./.ansible-items/inventory
- name: build frontend - name: build frontend
image: node:lts-alpine3.14 image: node:lts-alpine3.14
@ -48,22 +54,26 @@ steps:
inventory: ./.ansible-items/inventory inventory: ./.ansible-items/inventory
galaxy: ./.ansible-items/requirements.yml galaxy: ./.ansible-items/requirements.yml
syntax_check: true syntax_check: true
when:
branch:
- development
- name: apply ansible playbook - name: apply ansible playbook
image: plugins/ansible:3 image: plugins/ansible:3
settings: settings:
playbook: ./.ansible-items/playbook.yml playbook: ./.ansible-items/playbook.yml
inventory: ./.ansible-items/inventory inventory: ./.ansible-items/inventory
galaxy: ./.ansible-items/requirements.yml galaxy: ./.ansible-items/requirements.yml
private_key: timeout: 60
from_secret: deploy_ssh_key verbose: 2
environment: environment:
DEPLOY_HOSTNAME: DEPLOY_HOSTNAME:
from_secret: deploy_hostname from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOYMENT_USER_GROUP: DEPLOY_USER_GROUP:
from_secret: deploy_user_group from_secret: deploy_user_group
SPT_ITEMS_PATH: SPT_ITEMS_PATH:
from_secret: deploy_path from_secret: deploy_path

View File

@ -17,17 +17,23 @@ steps:
- name: replace hosts and user variables - name: replace hosts and user variables
image: ubuntu:impish image: ubuntu:impish
environment: environment:
DEPLOY_HOSTNAME:
from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_HOSTNAME:
from_secret: deploy_hostname
DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOY_PRIVATE_KEY:
from_secret: deploy_ssh_key
DEPLOY_SSH_KEY_PASSPHRASE:
from_secret: deploy_ssh_key_passphrase
commands: commands:
- sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example - sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example
- mv ./items/frontend/.env.example ./items/frontend/.env - mv ./items/frontend/.env.example ./items/frontend/.env
- sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory - echo "$DEPLOY_PRIVATE_KEY" > private.key && chmod 600 private.key
- sed -i 's/{{ DEPLOYMENT_USER }}/'"$DEPLOYMENT_USER"'/g' ./.ansible-items/inventory - sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_SSH_KEY_PASSPHRASE }}/'"$DEPLOY_SSH_KEY_PASSPHRASE"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_USER }}/'"$DEPLOY_USER"'/g' ./.ansible-items/inventory
- name: build frontend - name: build frontend
image: node:lts-alpine3.14 image: node:lts-alpine3.14
@ -48,22 +54,26 @@ steps:
inventory: ./.ansible-items/inventory inventory: ./.ansible-items/inventory
galaxy: ./.ansible-items/requirements.yml galaxy: ./.ansible-items/requirements.yml
syntax_check: true syntax_check: true
when:
branch:
- development
- name: apply ansible playbook - name: apply ansible playbook
image: plugins/ansible:3 image: plugins/ansible:3
settings: settings:
playbook: ./.ansible-items/playbook.yml playbook: ./.ansible-items/playbook.yml
inventory: ./.ansible-items/inventory inventory: ./.ansible-items/inventory
galaxy: ./.ansible-items/requirements.yml galaxy: ./.ansible-items/requirements.yml
private_key: timeout: 60
from_secret: deploy_ssh_key verbose: 2
environment: environment:
DEPLOY_HOSTNAME:
from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_HOSTNAME:
from_secret: deploy_hostname
DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOYMENT_USER_GROUP: DEPLOY_USER_GROUP:
from_secret: deploy_user_group from_secret: deploy_user_group
SPT_ITEMS_PATH: SPT_ITEMS_PATH:
from_secret: deploy_path from_secret: deploy_path

View File

@ -14,6 +14,7 @@
| deploy_username | The default username to use on the remote server <br> used by Ansible SSH | www-data | | deploy_username | The default username to use on the remote server <br> used by Ansible SSH | www-data |
| deploy_user_group | The default user group to use on the remote server <br> used to set permission on the website folder | www-data | | deploy_user_group | The default user group to use on the remote server <br> used to set permission on the website folder | www-data |
| deploy_ssh_key | The **content** of the ssh private key used to connect to the remote server <br> The key needs to be in RSA in "RSA PRIVATE KEY" format <br> The ssh publick key needs to already be in the user used in the remote server ~/.ssh/authorized_keys | -----BEGIN RSA PRIVATE KEY----- <br> The key <br> -----END RSA PRIVATE KEY----- | | deploy_ssh_key | The **content** of the ssh private key used to connect to the remote server <br> The key needs to be in RSA in "RSA PRIVATE KEY" format <br> The ssh publick key needs to already be in the user used in the remote server ~/.ssh/authorized_keys | -----BEGIN RSA PRIVATE KEY----- <br> The key <br> -----END RSA PRIVATE KEY----- |
| deploy_ssh_key_passphrase | The passphrase to decrypt the SSH private key | test |
## ⚠ Important notes for the deployment ⚠ ## ⚠ Important notes for the deployment ⚠
* Add all required secrets in Drone * Add all required secrets in Drone

View File

@ -4,7 +4,6 @@
* [Overview](#overview) * [Overview](#overview)
* [Pipeline definition](#pipeline-definition) * [Pipeline definition](#pipeline-definition)
* [Pipeline concurrency](#pipeline-concurrency) * [Pipeline concurrency](#pipeline-concurrency)
* [Environment variables](#environment-variables)
* [Triggers](#triggers) * [Triggers](#triggers)
* [Steps](#steps) * [Steps](#steps)
* [Fetch and update submodules](#Fetch-and-update-submodules) * [Fetch and update submodules](#Fetch-and-update-submodules)
@ -46,13 +45,6 @@ concurrency:
``` ```
The pipeline is set to only one build at a time (every subsequent build with be pending). The pipeline is set to only one build at a time (every subsequent build with be pending).
## Environment variables
```yml
environment:
SPT_ITEMS_PATH: /var/www/html/aki/spt-items-api
```
Here are the environment variables. They are automatically injected in every step.
## Triggers ## Triggers
```yml ```yml
trigger: trigger:
@ -70,24 +62,31 @@ The pipeline is run on every push only on branches `master`, `main` and `develop
- name: replace hosts and user variables - name: replace hosts and user variables
image: ubuntu:impish image: ubuntu:impish
environment: environment:
DEPLOY_HOSTNAME:
from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_HOSTNAME:
from_secret: deploy_hostname
DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOY_PRIVATE_KEY:
from_secret: deploy_ssh_key
DEPLOY_SSH_KEY_PASSPHRASE:
from_secret: deploy_ssh_key_passphrase
commands: commands:
- sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example - sed -i 's/{{ SPT_ITEMS_HOSTNAME }}/'"$SPT_ITEMS_HOSTNAME"'/g' ./items/frontend/.env.example
- mv ./items/frontend/.env.example ./items/frontend/.env - mv ./items/frontend/.env.example ./items/frontend/.env
- sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory - echo "$DEPLOY_PRIVATE_KEY" > private.key && chmod 600 private.key
- sed -i 's/{{ DEPLOYMENT_USER }}/'"$DEPLOYMENT_USER"'/g' ./.ansible-items/inventory - sed -i 's/{{ DEPLOY_HOSTNAME }}/'"$DEPLOY_HOSTNAME"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_SSH_KEY_PASSPHRASE }}/'"$DEPLOY_SSH_KEY_PASSPHRASE"'/g' ./.ansible-items/inventory
- sed -i 's/{{ DEPLOY_USER }}/'"$DEPLOY_USER"'/g' ./.ansible-items/inventory
``` ```
Executed on every push. \ Executed on every push. \
The following environment variables are injected using Drone secrets: The following environment variables are injected using Drone secrets:
* `SPT_ITEMS_HOSTNAME` is used by the frontend to call the backend. * `SPT_ITEMS_HOSTNAME` is used by the frontend to call the backend.
* `DEPLOY_HOSTNAME` is used by Ansible to connect to the remote server via SSH. * `DEPLOY_HOSTNAME` is used by Ansible to connect to the remote server via SSH.
* `DEPLOYMENT_USER` is used by Ansible to connect to the remote server via SSH. * `DEPLOY_USER` is used by Ansible to connect to the remote server via SSH.
* all environment variables at the pipeline level (see [Environment variables](#environment-variables)) * `DEPLOY_PRIVATE_KEY` is the SSH key used to connect to the remote server via SSH
* `DEPLOY_SSH_KEY_PASSPHRASE` is the SSH key passphrase
Using `sed` makes temporary changes in the container/pod instead of commiting secrets in the repo in plain text. \ Using `sed` makes temporary changes in the container/pod instead of commiting secrets in the repo in plain text. \
The changes are never pushed and are discarded when the container/pod is terminated. The changes are never pushed and are discarded when the container/pod is terminated.
@ -133,15 +132,19 @@ Check the Ansible syntax in [playbook.yml](../.ansible/playbook.yml), [inventory
playbook: ./.ansible-items/playbook.yml playbook: ./.ansible-items/playbook.yml
inventory: ./.ansible-items/inventory inventory: ./.ansible-items/inventory
galaxy: ./.ansible-items/requirements.yml galaxy: ./.ansible-items/requirements.yml
private_key: timeout: 60
from_secret: deploy_ssh_key verbose: 2
environment: environment:
DEPLOY_HOSTNAME:
from_secret: deploy_hostname
SPT_ITEMS_HOSTNAME: SPT_ITEMS_HOSTNAME:
from_secret: spt_items_hostname from_secret: spt_items_hostname
DEPLOYMENT_USER: DEPLOY_HOSTNAME:
from_secret: deploy_hostname
DEPLOY_USER:
from_secret: deploy_username from_secret: deploy_username
DEPLOY_USER_GROUP:
from_secret: deploy_user_group
SPT_ITEMS_PATH:
from_secret: deploy_path
when: when:
branch: branch:
- master - master
@ -153,14 +156,15 @@ This step is [idempotent](https://en.wikipedia.org/wiki/Idempotence). \
The following environment variables are injected using Drone secrets: The following environment variables are injected using Drone secrets:
* `SPT_ITEMS_HOSTNAME` is used by the PHP env file. * `SPT_ITEMS_HOSTNAME` is used by the PHP env file.
* `DEPLOY_HOSTNAME` is used to connect to the remote server via SSH. * `DEPLOY_HOSTNAME` is used to connect to the remote server via SSH.
* `DEPLOYMENT_USER` is used to connect to the remote server via SSH. * `DEPLOY_USER` is used to connect to the remote server via SSH.
* all environment variables at the pipeline level (see [Environment variables](#environment-variables)) * `DEPLOY_USER_GROUP` is the user group, used to give read/write/execute permissions to the whole group. It must be the same as Nginx's user.
* `SPT_ITEMS_PATH` is the path on the remote server where the files will be copyed to.
#### Playbook definition #### Playbook definition
```yml ```yml
hosts: host hosts: sptarkov
``` ```
Uses the host defined in [inventory](../.ansible/inventory). Remember, the step [Replace hosts and user variables](#replace-hosts-and-user-variables) already replaced the variables at this point. The playbook will be executed as `root` user using `sudo`. Uses the host defined in [inventory](../.ansible/inventory). Remember, the step [Replace hosts and user variables](#replace-hosts-and-user-variables) already replaced the variables at this point.
#### Delete old spt-items-api #### Delete old spt-items-api
```yml ```yml
@ -170,7 +174,7 @@ Uses the host defined in [inventory](../.ansible/inventory). Remember, the step
path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}" path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}"
``` ```
Since the copy does not override the folder, this step takes care of it. \ Since the copy does not override the folder, this step takes care of it. \
`SPT_ITEMS_PATH` is injected thanks to the pipeline level environment variables (see [Environment variables](#environment-variables)) `SPT_ITEMS_PATH` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook))
#### Copy the project #### Copy the project
```yml ```yml
@ -189,7 +193,7 @@ Copies the whole project (frontend and backend) from the [api](../api) folder in
dest: "{{ lookup('env', 'SPT_ITEMS_PATH') }}/.env" dest: "{{ lookup('env', 'SPT_ITEMS_PATH') }}/.env"
``` ```
Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [template for the PHP .env file](../.ansible/templates/.php_env.j2). \ Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [template for the PHP .env file](../.ansible/templates/.php_env.j2). \
`SPT_ITEMS_PATH` is injected thanks to the pipeline level environment variables (see [Environment variables](#environment-variables)). \ `SPT_ITEMS_PATH` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook)) \
`SPT_ITEMS_HOSTNAME` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook)) `SPT_ITEMS_HOSTNAME` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook))
#### Get JavaScript chunks name #### Get JavaScript chunks name
@ -200,7 +204,7 @@ Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [temp
register: find_output register: find_output
``` ```
Prepare a find of all JavaScript chunk files for the [app.blade.php.j2](../.ansible/templates/app.blade.php.j2) template. \ Prepare a find of all JavaScript chunk files for the [app.blade.php.j2](../.ansible/templates/app.blade.php.j2) template. \
`SPT_ITEMS_PATH` is injected thanks to the pipeline level environment variables (see [Environment variables](#environment-variables)). `SPT_ITEMS_PATH` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook))
#### Get file names from find output #### Get file names from find output
```yml ```yml
@ -218,7 +222,7 @@ Splits the string containing the list of all JavaScript chunk files for the [app
dest: "{{ lookup('env', 'SPT_ITEMS_PATH') }}/resources/views/app.blade.php" dest: "{{ lookup('env', 'SPT_ITEMS_PATH') }}/resources/views/app.blade.php"
``` ```
Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [template for the PHP app.blade.php file](../.ansible/templates/app.blade.php.j2). \ Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [template for the PHP app.blade.php file](../.ansible/templates/app.blade.php.j2). \
`SPT_ITEMS_PATH` is injected thanks to the pipeline level environment variables (see [Environment variables](#environment-variables)). `SPT_ITEMS_PATH` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook)).
#### Download and install composer dependencies #### Download and install composer dependencies
```yml ```yml
@ -233,17 +237,16 @@ Uses [Jinja2](https://jinja2docs.readthedocs.io/en/stable/) to resolve the [temp
- name: Reset files permissions - name: Reset files permissions
file: file:
path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}" path: "{{ lookup('env', 'SPT_ITEMS_PATH') }}"
owner: "{{ lookup('env', 'DEPLOYMENT_USER') }}" owner: "{{ lookup('env', 'DEPLOY_USER') }}"
group: www-data group: "{{ lookup('env', 'DEPLOY_USER_GROUP') }}"
mode: 0774 mode: 0774
recurse: yes recurse: yes
``` ```
Permissions 0644: Permissions 0644:
* user: read/write/execute * user: read/write/execute
* group: read * group: read/write/execute (for Nginx to execute the php as well as write in the Laravel logs)
* other: read * other: read
`www-data` is hardcoded here but it should be the standard user for Apache and Nginx. \ `SPT_ITEMS_PATH` is injected in the environments properties (see [Apply ansible playbook](#apply-ansible-playbook)).
`SPT_ITEMS_PATH` is injected thanks to the pipeline level environment variables (see [Environment variables](#environment-variables)).
#### Initialize database #### Initialize database
```yml ```yml