Deploy Serverless Financial Transactions Processing App #126
This file contains hidden or 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 Serverless Financial Transactions Processing App | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| deploy_infrastructure: | |
| description: "Deploy infrastructure (y/n) ?" | |
| required: true | |
| type: choice | |
| options: | |
| - "yes" | |
| - "no" | |
| default: "yes" | |
| db_migration: | |
| description: "Perform database migration (y/n) ?" | |
| required: true | |
| type: choice | |
| options: | |
| - "no" | |
| - "yes" | |
| default: "no" | |
| permissions: | |
| contents: read | |
| id-token: write | |
| pull-requests: write | |
| env: | |
| ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }} | |
| ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }} | |
| ARM_USE_OIDC: true | |
| TERRAFORM_WORKING_DIR: ./iac | |
| BACKEND_RESOURCE_GROUP: rg-sp-txn-tf-backend | |
| BACKEND_STORAGE_ACCOUNT: ${{ secrets.STORAGE_ACCOUNT_NAME }} | |
| BACKEND_CONTAINER: tfstate | |
| PYTHON_VERSION: "3.12" | |
| ENVIRONMENT: dev | |
| AZURE_FUNCTIONAPP_PACKAGE_PATH: "./function_apps/ingest_sharepoint_files" | |
| jobs: | |
| infrastructure: | |
| name: Deploy Infrastructure | |
| runs-on: ubuntu-latest | |
| if: github.event.inputs.deploy_infrastructure == 'yes' | |
| env: | |
| TF_VAR_kv_name_base: ${{ secrets.KV_NAME }} | |
| TF_VAR_alert_config: ${{ secrets.ALERT_CONFIG }} | |
| TF_VAR_psql_admin_sg_object_id: ${{ secrets.POSTGRESQL_ADMINS_OBJECT_ID }} | |
| TF_VAR_ip_address: ${{ secrets.IP_ADDRESS }} | |
| TF_VAR_psql_server_name: ${{ secrets.PSQL_SERVER_NAME }} | |
| TF_VAR_vault_url_dev: ${{ secrets.VAULT_URL_DEV }} | |
| TF_VAR_db_host: ${{ secrets.DB_HOST }} | |
| TF_VAR_tenant_id: ${{ secrets.AZURE_TENANT_ID }} | |
| TF_VAR_kv_name: ${{ secrets.KV_NAME }} | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Azure Login (OIDC) | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@v2 | |
| with: | |
| terraform_version: latest | |
| - name: Terraform Init | |
| run: terraform init | |
| working-directory: ${{ env.TERRAFORM_WORKING_DIR }} | |
| - name: Terraform Plan | |
| run: | | |
| terraform plan \ | |
| -var="environment=${{ env.ENVIRONMENT }}" \ | |
| -var-file="terraform.tfvars" \ | |
| -input=false | |
| working-directory: ${{ env.TERRAFORM_WORKING_DIR }} | |
| - name: Terraform Apply | |
| run: | | |
| echo "::add-mask::$ARM_SUBSCRIPTION_ID" | |
| terraform apply \ | |
| -var="environment=${{ env.ENVIRONMENT }}" \ | |
| -var-file="terraform.tfvars" \ | |
| -auto-approve \ | |
| -input=false | |
| working-directory: ${{ env.TERRAFORM_WORKING_DIR }} | |
| build: | |
| name: Build Function | |
| runs-on: ubuntu-latest | |
| needs: infrastructure | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v5 | |
| - name: Setup Python version | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| cache: "pip" | |
| - name: Create and start virtual environment | |
| run: python -m venv venv | |
| working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} | |
| - name: Install dependencies | |
| run: | | |
| source venv/bin/activate | |
| pip install --target="./.python_packages/lib/site-packages" -r requirements.txt | |
| working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} | |
| - name: Zip artifact for deployment | |
| run: | | |
| zip -r release.zip . -x "*.git*" -x "*venv*" -x "*__pycache__*" -x "*.pyc" | |
| working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }} | |
| - name: Upload artifact for deployment job | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-app | |
| path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/release.zip | |
| deploy: | |
| name: Deploy Function | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Download artifact from build job | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: python-app | |
| - name: Unzip artifact for deployment | |
| run: unzip release.zip | |
| - name: Login to Azure | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Deploy to Azure Functions | |
| uses: Azure/functions-action@v1 | |
| id: deploy-to-function | |
| with: | |
| app-name: sptxn-fn-app-${{ env.ENVIRONMENT }} | |
| slot-name: "Production" | |
| sku: "flexconsumption" | |
| remote-build: false | |
| package: "." | |
| db_migration: | |
| name: Database Migration | |
| runs-on: ubuntu-latest | |
| if: github.event.inputs.db_migration == 'yes' | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Azure login | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.13" | |
| cache: "pip" | |
| - name: Install Python dependencies | |
| working-directory: ./database | |
| run: | | |
| python -m venv venv | |
| source venv/bin/activate | |
| pip install -r requirements.txt | |
| - name: Create GitHub Runner FW rule | |
| env: | |
| DB_NAME: ${{ secrets.PSQL_SERVER_NAME }} | |
| run: | | |
| echo "::add-mask::$DB_NAME" | |
| RUNNER_IP=$(curl -s https://api.ipify.org?format=json | jq -r '.ip') | |
| echo "Runner IP: $RUNNER_IP" | |
| az postgres flexible-server firewall-rule create \ | |
| --resource-group rg-sp-txn-dev \ | |
| --name $DB_NAME \ | |
| --rule-name github-runner-ip \ | |
| --start-ip-address $RUNNER_IP | |
| - name: Database migration | |
| working-directory: ./database | |
| env: | |
| DB_HOST: ${{ secrets.DB_HOST }} | |
| environment: "azure-dev" | |
| run: | | |
| echo "::add-mask::$DB_HOST" | |
| source venv/bin/activate | |
| export environment=${{ env.environment }} | |
| export DB_PASSWORD=$(az account get-access-token --resource-type oss-rdbms --query accessToken --output tsv) | |
| alembic upgrade head | |
| - name: Delete GitHub Runner FW rule | |
| env: | |
| DB_NAME: ${{ secrets.PSQL_SERVER_NAME }} | |
| run: | | |
| echo "::add-mask::$DB_NAME" | |
| RUNNER_IP=$(curl -s https://api.ipify.org?format=json | jq -r '.ip') | |
| echo "Runner IP: $RUNNER_IP" | |
| az postgres flexible-server firewall-rule delete \ | |
| --rule-name github-runner-ip \ | |
| --resource-group rg-sp-txn-dev \ | |
| --name $DB_NAME \ | |
| --yes |