feat: update deployment with terraform #25
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: Deploy Dockerized Nest.js App to GCP with Terraform Provisioning | |
on: | |
push: | |
branches: | |
- feat/deployment | |
paths-ignore: | |
- README.md | |
- .gitignore | |
pull_request_target: | |
branches: | |
- master | |
types: | |
- closed | |
jobs: | |
publish: | |
name: 'Publish' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
- name: Docker Hub Authentication | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ secrets.DOCKERHUB_USERNAME }} | |
password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
- name: Build Docker Image | |
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME }}:latest . | |
- name: Tag Docker Image | |
run: docker tag ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME }}:latest ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME }}:latest | |
- name: Push Docker Image to Docker Hub | |
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ vars.DOCKER_IMAGE_NAME }}:latest | |
terraform: | |
name: 'Terraform' | |
runs-on: ubuntu-latest | |
outputs: | |
external_ip: ${{ steps.store.outputs.vm_external_ip }} | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- name: Checkout Repository | |
uses: actions/checkout@v4 | |
- name: Google Auth | |
uses: 'google-github-actions/auth@v2' | |
with: | |
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' | |
- name: Set up Cloud SDK | |
uses: 'google-github-actions/setup-gcloud@v2' | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v1 | |
with: | |
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} | |
- name: Create Terraform Variables | |
id: vars | |
run: | | |
cat > terraform.tfvars <<EOF | |
project_id="${{ secrets.GCP_PROJECT_ID }}" | |
ssh_pub_key="${{ secrets.SSH_PUBLIC_KEY }}" | |
ssh_username="${{ secrets.GCP_USERNAME }}" | |
domain_name="${{ secrets.DOMAIN_NAME }}" | |
dns_record_name="${{ secrets.DNS_RECORD_NAME }}" | |
managed_zone_name="${{ secrets.MANAGED_ZONE_NAME }}" | |
EOF | |
- name: Terraform Init | |
run: terraform init | |
- name: Terraform Format | |
run: terraform fmt | |
- name: Terraform Plan | |
run: terraform plan -out=plan | |
- name: Terraform Apply | |
run: terraform apply "plan" | |
- name: Store Terraform Output | |
run: | | |
EXTERNAL_IP=$(terraform-bin output -raw vm_external_ip) | |
echo "VM_EXTERNAL_IP=$EXTERNAL_IP" >> $GITHUB_ENV | |
echo "not env: $EXTERNAL_IP" | |
echo "env: ${{ env.VM_EXTERNAL_IP }}" | |
- name: Echo Terraform Output | |
id: store | |
env: | |
EXTERNAL_IP: ${{ env.VM_EXTERNAL_IP }} | |
run: | | |
echo "env directly: ${{ env.VM_EXTERNAL_IP }}" | |
echo "env variable: $EXTERNAL_IP" | |
echo "vm_external_ip=$EXTERNAL_IP" >> "$GITHUB_OUTPUT" | |
- name: Terraform State | |
run: terraform show | |
# - name: Terraform Destroy | |
# if: ${{ always() }} | |
# run: terraform destroy -auto-approve | |
deploy: | |
name: 'Deploy' | |
runs-on: ubuntu-latest | |
needs: [publish, terraform] | |
steps: | |
- name: Google Auth | |
uses: 'google-github-actions/auth@v2' | |
with: | |
credentials_json: '${{ secrets.GOOGLE_CREDENTIALS }}' | |
- name: Set up Cloud SDK | |
uses: 'google-github-actions/setup-gcloud@v2' | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Copy docker-compose.yml into GCP Instance | |
uses: appleboy/scp-action@master | |
with: | |
host: ${{ needs.terraform.outputs.external_ip }} | |
username: ${{ secrets.GCP_USERNAME }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
source: 'docker-compose.yml' | |
target: '/home/${{ secrets.GCP_USERNAME }}/' | |
- name: SSH into GCP and Run Docker Container | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ needs.terraform.outputs.external_ip }} | |
username: ${{ secrets.GCP_USERNAME }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
script: | | |
echo "DATABASE_URL=postgresql://${{ vars.DATABASE_USERNAME }}:${{ vars.DATABASE_PASSWORD }}@${{ vars.DATABASE_HOST }}:5432/${{ vars.DATABASE_NAME }}?schema=public" >> .env | |
sed -i -e 's/iqbalpa\/backend-movies/${{ secrets.DOCKERHUB_USERNAME }}\/${{ vars.DOCKER_IMAGE_NAME }}/g' docker-compose.yml | |
docker compose -f /home/${{ secrets.GCP_USERNAME }}/docker-compose.yml down | |
docker compose -f /home/${{ secrets.GCP_USERNAME }}/docker-compose.yml up --pull always -d | |
docker image prune -f -a |