Skip to content

Commit

Permalink
Read backup server ssh key from its environment variables, use for an…
Browse files Browse the repository at this point in the history
…sible provisioning
  • Loading branch information
rikukissa committed May 29, 2024
1 parent 79b7f00 commit b3defd2
Show file tree
Hide file tree
Showing 12 changed files with 400 additions and 223 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/get-secret-from-env.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Reusable Fetch Secret Workflow

on:
workflow_call:
inputs:
secret_name:
required: true
type: string
env_name:
required: true
type: string
secrets:
github_token:
required: true
encryption_key:
required: true

jobs:
check-environment:
name: Check if Environment Exists
runs-on: ubuntu-22.04
outputs:
environment_exists: ${{ steps.check-env.outputs.exists }}
steps:
- name: Check if GITHUB_TOKEN is set
id: check-token
run: |
if [ -z "${{ secrets.github_token }}" ]; then
echo "Environment secret GITHUB_TOKEN is not set. Make sure you add a correct Github API token before running this pipeline."
exit 1
fi
- name: Check if environment exists
id: check-env
run: |
ENV_NAME="${{ inputs.env_name }}"
RESPONSE=$(curl -s -H "Authorization: Bearer ${{ secrets.github_token }}" \
"https://api.github.com/repos/${{ github.repository }}/environments/$ENV_NAME")
if echo "$RESPONSE" | grep -q '"name": "'$ENV_NAME'"'; then
echo "Environment $ENV_NAME exists."
echo "::set-output name=exists::true"
else
echo "Environment $ENV_NAME does not exist."
echo "::set-output name=exists::false"
fi
fetch-credentials:
name: Fetch Secret
needs: check-environment
runs-on: ubuntu-22.04
if: needs.check-environment.outputs.environment_exists == 'true'
outputs:
secret_value: ${{ steps.fetch-credentials.outputs.secret_value }}
environment_exists: ${{ needs.check-environment.outputs.environment_exists }}
steps:
- name: Fetch the secret
id: fetch-credentials
run: |
SECRET_VALUE="${{ secrets[inputs.secret_name] }}"
echo -n "$SECRET_VALUE" | openssl enc -aes-256-cbc -pbkdf2 -salt -k "${{ secrets.encryption_key }}" -out encrypted_key.bin
ENCODED_ENCRYPTED_SECRET=$(base64 < encrypted_key.bin)
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "secret_value<<$EOF" >> $GITHUB_OUTPUT
echo "$ENCODED_ENCRYPTED_SECRET" >> $GITHUB_OUTPUT
echo "$EOF" >> $GITHUB_OUTPUT
60 changes: 55 additions & 5 deletions .github/workflows/provision.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,28 @@ on:
description: Open SSH session to the runner after deployment
default: false
jobs:
get-backup-ssh-key:
uses: ./.github/workflows/get-secret-from-env.yml
with:
secret_name: 'SSH_KEY'
env_name: 'backup'
secrets:
github_token: ${{ secrets.GH_TOKEN }}
encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }}
get-production-encryption-key:
uses: ./.github/workflows/get-secret-from-env.yml
with:
secret_name: 'BACKUP_ENCRYPTION_PASSPHRASE'
env_name: 'production'
secrets:
github_token: ${{ secrets.GH_TOKEN }}
encryption_key: ${{ secrets.GH_ENCRYPTION_PASSWORD }}

provision:
name: Provision ${{ github.event.inputs.environment }}
environment: ${{ github.event.inputs.environment }}
needs: [get-backup-ssh-key, get-production-encryption-key]
if: always()
runs-on: ubuntu-22.04
outputs:
outcome: ${{ steps.deploy.outcome }}
Expand All @@ -56,7 +76,16 @@ jobs:
fetch-depth: 0
path: './${{ github.event.repository.name }}'

- name: Set variables for ansible in production environments
- name: Insert production encryption key to environment variables
if: github.event.inputs.environment == 'staging'
run: |
echo "${{ needs.get-production-encryption-key.outputs.secret_value }}" | base64 --decode | \
openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_encryption_key
BACKUP_RESTORE_ENCRYPTION_PASSPHRASE=$(cat /tmp/backup_encryption_key)
echo "backup_restore_encryption_passphrase=$BACKUP_RESTORE_ENCRYPTION_PASSPHRASE" >> $GITHUB_ENV
echo "::add-mask::$BACKUP_RESTORE_ENCRYPTION_PASSPHRASE"
- name: Set variables for ansible
id: ansible-variables
run: |
JSON_WITH_NEWLINES=$(cat<<EOF
Expand All @@ -73,8 +102,8 @@ jobs:
mongodb_admin_password: ${{ secrets.MONGODB_ADMIN_PASSWORD }}
backup_encryption_passphrase: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }}
elasticsearch_superuser_password: ${{ secrets.ELASTICSEARCH_SUPERUSER_PASSWORD }}
external_backup_server_ssh_port: 22
external_backup_server_ip: ${{ secrets.BACKUP_HOST }}
# SSH_HOST was moved from a secret to a variable in OpenCRVS 1.5.0
# @todo @deprecated remove the fallback to secrets.SSH_HOST in OpenCRVS 1.7.0
manager_production_server_ip: ${{ vars.SSH_HOST || secrets.SSH_HOST }}
ansible_user: ${{ secrets.SSH_USER }}

Expand All @@ -92,6 +121,27 @@ jobs:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ env.KNOWN_HOSTS }}

- name: Write backup SSH key to file
if: needs.get-backup-ssh-key.outputs.environment_exists == 'true'
run: |
echo "${{ needs.get-production-encryption-key.outputs.backup-ssh-key }}" | base64 --decode | \
openssl enc -aes-256-cbc -pbkdf2 -d -salt -k "${{ secrets.GH_ENCRYPTION_PASSWORD }}" -out /tmp/backup_ssh_private_key
chmod 600 /tmp/backup_ssh_private_key
- name: Check if backup environment if configured in inventory file
if: needs.get-backup-ssh-key.outputs.environment_exists != 'true'
run: |
FILE=./${{ github.event.repository.name }}/infrastructure/server-setup/inventory/${{ github.event.inputs.environment }}.yml
if grep -q "backups: " "$FILE"; then
echo "Your inventory contains configuration for either a backup target or backup source."
echo "If you are upgrading OpenCRVS, please start by running environment creator script for the backup server"
echo ""
echo "yarn environment:init --environment=backup"
echo ""
echo "And after that, run this provisioning pipeline again but first to your backup server"
echo "After that you can proceed with (re)provisioning your staging and production servers."
exit 1
fi
- name: Setup tmate session
if: ${{ github.event.inputs.debug == 'true' }}
uses: mxschmitt/action-tmate@v3
Expand All @@ -104,8 +154,8 @@ jobs:
mongodb_admin_password: ${{ secrets.MONGODB_ADMIN_PASSWORD }}
backup_encryption_passphrase: ${{ secrets.BACKUP_ENCRYPTION_PASSPHRASE }}
elasticsearch_superuser_password: ${{ secrets.ELASTICSEARCH_SUPERUSER_PASSWORD }}
external_backup_server_ssh_port: 22
external_backup_server_ip: ${{ secrets.BACKUP_HOST }}
# SSH_HOST was moved from a secret to a variable in OpenCRVS 1.5.0
# @todo @deprecated remove the fallback to secrets.SSH_HOST in OpenCRVS 1.7.0
manager_production_server_ip: ${{ vars.SSH_HOST || secrets.SSH_HOST }}
ansible_user: ${{ secrets.SSH_USER }}

Expand Down
Loading

0 comments on commit b3defd2

Please sign in to comment.