Infrastructure CI and CD #145
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Infrastructure CI and CD | |
on: | |
workflow_run: | |
workflows: | |
- Frontend CI and CD | |
- Backend CI and CD | |
types: | |
- completed | |
defaults: | |
run: | |
working-directory: ./infrastructure | |
env: | |
TF_VAR_project_name: tarhche | |
TF_VAR_instance_name: backend | |
DOCKER_REGISTRY: ghcr.io | |
PROXY_IMAGE_NAME: proxy | |
EC2_SSH_ADDRESS: ${{ secrets.EC2_SSH_ADDRESS }} | |
EC2_SSH_ENDPOINT: ${{ secrets.EC2_SSH_USER }}@${{ secrets.EC2_SSH_ADDRESS }} | |
jobs: | |
ci: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Set up AWS credentials | |
uses: aws-actions/configure-aws-credentials@v1 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ secrets.AWS_REGION }} | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v3 | |
- name: Terraform Format | |
id: fmt | |
run: terraform fmt -check | |
- name: Terraform Init | |
id: init | |
run: terraform init | |
- name: Terraform Validate | |
id: validate | |
run: terraform validate -no-color | |
- name: Terraform Plan | |
run: terraform plan -no-color -input=false | |
continue-on-error: false | |
cd: | |
runs-on: ubuntu-latest | |
if: ${{ format('refs/heads/{0}', github.event.repository.default_branch) == github.ref }} | |
permissions: | |
packages: write | |
contents: read | |
needs: | |
- ci | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Set up AWS credentials | |
uses: aws-actions/configure-aws-credentials@v1 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ secrets.AWS_REGION }} | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v3 | |
- name: Terraform Init | |
id: init | |
run: terraform init | |
- name: Terraform Validate | |
id: validate | |
run: terraform validate -no-color | |
- name: Terraform Apply | |
run: terraform apply -auto-approve -input=false | |
continue-on-error: false | |
- name: Build images | |
run: | | |
PROXY_IMAGE_ID=$(echo $DOCKER_REGISTRY/${{ github.repository_owner }}/$PROXY_IMAGE_NAME | tr '[A-Z]' '[a-z]') | |
PROXY_IMAGE_VERSION=${{ github.sha }} | |
echo "PROXY_IMAGE_ID=$PROXY_IMAGE_ID" >> "$GITHUB_ENV" | |
echo "PROXY_IMAGE_VERSION=$PROXY_IMAGE_VERSION" >> "$GITHUB_ENV" | |
docker build ./proxy --file ./proxy/Dockerfile --tag $PROXY_IMAGE_ID:$PROXY_IMAGE_VERSION --tag $PROXY_IMAGE_ID:latest | |
- name: Log in to registry | |
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin | |
- name: Push images | |
run: | | |
docker push $PROXY_IMAGE_ID:$PROXY_IMAGE_VERSION | |
docker push $PROXY_IMAGE_ID:latest | |
- name: Deploy services | |
run: | | |
# Setup ssh key | |
echo "${{ secrets.EC2_SSH_PRIVATE_KEY }}" > ~/ec2-key.pem | |
chmod 400 ~/ec2-key.pem | |
mkdir -p ~/.ssh | |
ssh-keyscan -H $EC2_SSH_ADDRESS >> ~/.ssh/known_hosts | |
# Ensure remote directory exists | |
ssh -q -i ~/ec2-key.pem -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $EC2_SSH_ENDPOINT > /dev/null 2>&1 << 'EOF' | |
export VOLUME_PATH="${{ secrets.VOLUME_PATH }}" | |
sudo mkdir -p /opt/deployment | |
sudo chown ${{ secrets.EC2_SSH_USER }}:${{ secrets.EC2_SSH_USER }} /opt/deployment | |
# create volumes directories | |
sudo mkdir -p $VOLUME_PATH/mongodb/db | |
sudo mkdir -p $VOLUME_PATH/mongodb/configdb | |
sudo mkdir -p $VOLUME_PATH/nats | |
EOF | |
# Copy files | |
scp -q -i ~/ec2-key.pem -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -r ./* $EC2_SSH_ENDPOINT:/opt/deployment/ > /dev/null 2>&1 | |
# Connect and deploy services | |
ssh -q -i ~/ec2-key.pem -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $EC2_SSH_ENDPOINT > /dev/null 2>&1 << 'EOF' | |
export VOLUME_PATH="${{ secrets.VOLUME_PATH }}" | |
export MONGO_USERNAME="${{ secrets.MONGO_USERNAME }}" | |
export MONGO_PASSWORD="${{ secrets.MONGO_PASSWORD }}" | |
export DASHBOARD_MONGO_USERNAME="${{ secrets.DASHBOARD_MONGO_USERNAME }}" | |
export DASHBOARD_MONGO_PASSWORD="${{ secrets.DASHBOARD_MONGO_PASSWORD }}" | |
export DASHBOARD_MONGO_MONGODB_URL="mongodb://${{ secrets.MONGO_USERNAME }}:${{ secrets.MONGO_PASSWORD }}@mongodb:27017" | |
export BACKEND_NATS_URL="${{ secrets.BACKEND_NATS_URL }}" | |
export BACKEND_PRIVATE_KEY="${{ secrets.BACKEND_PRIVATE_KEY }}" | |
export BACKEND_MONGO_HOST="mongodb" | |
export BACKEND_MONGO_PORT="27017" | |
export BACKEND_MONGO_SCHEME="mongodb" | |
export BACKEND_MONGO_DATABASE_NAME="${{ secrets.BACKEND_MONGO_DATABASE_NAME }}" | |
export BACKEND_MONGO_USERNAME="${{ secrets.MONGO_USERNAME }}" | |
export BACKEND_MONGO_PASSWORD="${{ secrets.MONGO_PASSWORD }}" | |
export BACKEND_MAIL_SMTP_PASSWORD="${{ secrets.BACKEND_MAIL_SMTP_PASSWORD }}" | |
export BACKEND_MAIL_SMTP_HOST="${{ secrets.BACKEND_MAIL_SMTP_HOST }}" | |
export BACKEND_MAIL_SMTP_FROM="${{ secrets.BACKEND_MAIL_SMTP_FROM }}" | |
export BACKEND_MAIL_SMTP_USERNAME="${{ secrets.BACKEND_MAIL_SMTP_USERNAME }}" | |
export BACKEND_MAIL_SMTP_PORT="${{ secrets.BACKEND_MAIL_SMTP_PORT }}" | |
export BACKEND_S3_ENDPOINT="${{ secrets.BACKEND_S3_ENDPOINT }}" | |
export BACKEND_S3_SECRET_KEY="${{ secrets.BACKEND_S3_SECRET_KEY }}" | |
export BACKEND_S3_ACCESS_KEY="${{ secrets.BACKEND_S3_ACCESS_KEY }}" | |
export BACKEND_S3_USE_SSL="${{ secrets.BACKEND_S3_USE_SSL }}" | |
export BACKEND_S3_BUCKET_NAME="${{ secrets.BACKEND_S3_BUCKET_NAME }}" | |
export PROXY_IMAGE=${{ secrets.PROXY_IMAGE }} | |
export APP_IMAGE="${{ secrets.APP_IMAGE }}" | |
export PORTAINER_ADMIN_PASSWORD='${{ secrets.PORTAINER_ADMIN_PASSWORD }}' | |
export FRONTEND_IMAGE="${{ secrets.FRONTEND_IMAGE }}" | |
export NEXT_PUBLIC_EXTERNAL_BACKEND_BASE_URL="${{ secrets.NEXT_PUBLIC_EXTERNAL_BACKEND_BASE_URL }}" | |
export INTERNAL_BACKEND_BASE_URL="${{ secrets.INTERNAL_BACKEND_BASE_URL }}" | |
export NEXT_PUBLIC_FILES_BASE_URL="${{ secrets.NEXT_PUBLIC_FILES_BASE_URL }}" | |
# Run Docker Compose | |
cd /opt/deployment/ | |
docker stack deploy -c compose.mongodb.yaml mongodb --detach=true | |
docker stack deploy -c compose.mongodb_dashboard.yaml mongodb_dashboard --detach=true | |
docker stack deploy -c compose.nats.yaml nats --detach=true | |
docker stack deploy -c compose.docker.yaml docker --detach=true | |
docker stack deploy -c compose.docker_dashboard.yaml docker_dashboard --detach=true | |
docker stack deploy -c compose.backend.yaml backend --detach=true | |
docker stack deploy -c compose.frontend.yaml frontend --detach=true | |
docker stack deploy -c compose.proxy.yaml proxy --detach=true | |
EOF |