Skip to content

CD & Terraform

CD & Terraform #123

Workflow file for this run

# CD pipeline with timeout based cancellation logic to deploy the code on a brand new Scaleway instance
name: CD pipeline
on:
workflow_dispatch: # manual trigger
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
check-condition:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/[email protected]
- name: Run condition check
uses: ./.github/actions/deployment
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
approval-timeout:
runs-on: ubuntu-latest
needs: check-condition
if: ${{ needs.check-condition.outputs.RUN_DEPLOYMENT }} == 'true'
steps:
- name: Wait for approval or timeout
run: |
ENVIRONMENT_NAME="production"
TIMEOUT_MINUTES=15
echo "Waiting $TIMEOUT_MINUTES minutes for approval ..."
# iterative checks every minute
for ((i=1; i<=$TIMEOUT_MINUTES; i++)); do
if [[ $i -gt 1 ]]; then
MINUTE_STRING="minutes"
else
MINUTE_STRING="minute"
fi
sleep 60
echo "Checking status after $i $MINUTE_STRING ..."
DEPLOYMENT_RESPONSE=$(curl -s \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/deployments?environment=$ENVIRONMENT_NAME&per_page=1")
DEPLOYMENT_ID=$(echo "$DEPLOYMENT_RESPONSE" | jq -r '.[0].id')
STATUS_RESPONSE=$(curl -s \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${{ github.repository }}/deployments/$DEPLOYMENT_ID/statuses")
STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.[0].state')
if [[ ($STATUS == "error" || "$STATUS" == "waiting") && $i -lt $TIMEOUT_MINUTES ]]; then
echo "Approval not received yet - keep waiting for it"
else
break
fi
done
# tags: error, failure, inactive, in_progress, queued, pending, success
echo "Current deployment status is '$STATUS'"
if [[ $STATUS != "error" && "$STATUS" != "waiting" ]]; then
echo "--> Approval received"
exit 0
else
echo "--> No approval found - cancelling workflow ..."
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/cancel"
echo "Workflow cancelled"
exit 1
fi
deployment:
runs-on: ubuntu-latest
environment:
name: production
url: https://bctk.fullofstack.eu
env:
TF_LOG: DEBUG
# Scaleway credentials
TF_VAR_scaleway_access_key: ${{ secrets.SCALEWAY_ACCESS_KEY }}
TF_VAR_scaleway_secret_key: ${{ secrets.SCALEWAY_SECRET_KEY }}
TF_VAR_scaleway_organization_id: ${{ secrets.SCALEWAY_ORGANIZATION_ID }}
TF_VAR_scaleway_project_id: ${{ secrets.SCALEWAY_PROJECT_ID }}
TF_VAR_scaleway_server_user: ${{ secrets.SCALEWAY_SERVER_USER }}
TF_VAR_scaleway_ssh_pub_key_name: ${{ secrets.SCALEWAY_SSH_PUB_KEY_NAME }}
TF_VAR_scaleway_ssh_private_key: ${{ secrets.SCALEWAY_SSH_PRIVATE_KEY }}
TF_VAR_scaleway_zone: ${{ secrets.SCALEWAY_ZONE }}
# Data stored in Scaleway
TF_VAR_scaleway_awscli_config: ${{ secrets.SCALEWAY_AWSCLI_CONFIG }}
TF_VAR_data_bucket: ${{ secrets.DATA_BUCKET }}
TF_VAR_data_source: ${{ secrets.DATA_SOURCE }}
# Github secrets
TF_VAR_github_token: ${{ secrets.BCTK_GITHUB_TOKEN }}
TF_VAR_github_workspace: ${{ github.workspace }}
TF_VAR_github_repo_name: ${{ github.repository }}
# Terraform variables from variables.tf
TF_VAR_bctk_domain: ${{ secrets.BCTK_DOMAIN }}
TF_VAR_clickhouse_ip: ${{ secrets.CLICKHOUSE_IP }}
TF_VAR_clickhouse_port: ${{ secrets.CLICKHOUSE_PORT }}
TF_VAR_clickhouse_db: ${{ secrets.CLICKHOUSE_DB }}
TF_VAR_clickhouse_user: ${{ secrets.CLICKHOUSE_USER }}
TF_VAR_clickhouse_password: ${{ secrets.CLICKHOUSE_PASSWORD }}
TF_VAR_clickhouse_admin_user: ${{ secrets.CLICKHOUSE_ADMIN_USER }}
TF_VAR_clickhouse_admin_password: ${{ secrets.CLICKHOUSE_ADMIN_PASSWORD }}
TF_VAR_clickhouse_app_user: ${{ secrets.CLICKHOUSE_APP_USER }}
TF_VAR_clickhouse_app_password: ${{ secrets.CLICKHOUSE_APP_PASSWORD }}
# TF_VAR_data_path: "../data"
TF_VAR_avalanche_rpc_url: ${{ secrets.AVALANCHE_RPC_URL }}
needs: check-condition
if: ${{ needs.check-condition.outputs.RUN_DEPLOYMENT }} == 'true'
steps:
- name: Set Secrets for Pull Request
if: github.event_name == 'pull_request'
run: echo "TF_VAR_github_repo_branch=${{ github.head_ref }}" >> $GITHUB_ENV
- name: Set repository branch environment variable
run: |
if [ -z "${{ env.TF_VAR_github_repo_branch }}" ]; then
echo "TF_VAR_github_repo_branch is not set"
echo "TF_VAR_github_repo_branch=${{ github.ref_name }}" >> $GITHUB_ENV
fi
echo "TF_VAR_github_repo_branch is set to: ${{ env.TF_VAR_github_repo_branch }}"
- name: Checkout repository
uses: actions/[email protected]
- name: Delete deprecated Scaleway resources (DNS records & instance)
continue-on-error: true # when there is no instance to delete
run: |
# Install Scaleway CLI
ZONE=${{ secrets.SCALEWAY_ZONE }}
REGION="${ZONE:0:-2}"
echo 'Installing Scaleway CLI ...'
curl -s https://raw.githubusercontent.com/scaleway/scaleway-cli/master/scripts/get.sh | sh
mkdir -p ~/.config/scw
tee ~/.config/scw/config.yaml << EOF
access_key: ${{ secrets.SCALEWAY_ACCESS_KEY }}
secret_key: ${{ secrets.SCALEWAY_SECRET_KEY }}
default_organization_id: ${{ secrets.SCALEWAY_ORGANIZATION_ID }}
default_project_id: ${{ secrets.SCALEWAY_PROJECT_ID }}
default_zone: ${{ secrets.SCALEWAY_ZONE }}
default_region: $REGION
api_url: https://api.scaleway.com
EOF
# Delete previous DNS records
ROOT_DOMAIN=$(echo "$(echo ${{ secrets.BCTK_DOMAIN }} | cut -d'.' -f2).$(echo ${{ secrets.BCTK_DOMAIN }} | cut -d'.' -f3)")
SUB_DOMAIN=$(echo ${{ secrets.BCTK_DOMAIN }} | cut -d'.' -f1)
echo 'Deleting previous DNS records for '$SUB_DOMAIN' in '$ROOT_DOMAIN' ...'
scw dns record delete $ROOT_DOMAIN name=$SUB_DOMAIN type=A
scw dns record delete $ROOT_DOMAIN name=$SUB_DOMAIN type=AAAA
# Delete previous instance
scw instance server list project-id=${{ secrets.SCALEWAY_PROJECT_ID }}
INSTANCE_META=$(scw instance server list project-id=${{ secrets.SCALEWAY_PROJECT_ID }})
INSTANCE_ID=$(echo "$INSTANCE_META" | awk 'NR==2 {print $1}')
INSTANCE_NAME=$(echo "$INSTANCE_META" | awk 'NR==2 {print $2}')
echo "Deleting instance '$INSTANCE_NAME' ..."
scw instance server stop "$INSTANCE_ID"
scw instance server wait "$INSTANCE_ID"
scw instance server delete "$INSTANCE_ID" with-volumes=all with-ip
- name: Set up Terraform
uses: hashicorp/[email protected]
- name: Initialize Terraform
uses: ./.github/actions/terraform
with:
command: init
- name: Terraform Format
uses: ./.github/actions/terraform
with:
command: fmt -check
- name: Terraform Plan
uses: ./.github/actions/terraform
with:
command: plan
- name: Apply Terraform configuration
uses: ./.github/actions/terraform
with:
command: apply -auto-approve