Skip to content

Commit

Permalink
feat: start part 4 draft
Browse files Browse the repository at this point in the history
  • Loading branch information
WayneGoosen committed Jul 16, 2024
1 parent 68fef60 commit 93d0319
Showing 1 changed file with 224 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
---
heroImage: /src/assets/images/Terraform.png
category: CICD
description: >-
A step-by-step guide to configure a GitHub Workflow that executes Terraform commands to provision Infrastructure on Azure.
pubDate: 2024-07-16
draft: true
tags:
- terraform
- azure
- iac
- github
title: >-
Streamlit Deployment Guide Part 4: GitHub Workflow for Terraform Apply & Destroy
---

This showcases a GitHub Workflow walkthrough of executing the necessary Terraform commands to provision and tear down the Azure resources for the Streamlit application. It continues a series detailing the process of deploying a Streamlit app to Azure, broken down into the following parts:

- [**Part 1**: Containerizing a Streamlit app.](https://blog.waynegoosen.com/post/streamlit-deployment-guide-part-1-containerization/)
- [**Part 2**: GitHub Workflow for Building and Publishing to ghcr.io](https://blog.waynegoosen.com/post/streamlit-deployment-guide-part-2-github-workflow/)
- [**Part 3**: Azure Infrastructure via Terraform](https://blog.waynegoosen.com/post/streamlit-deployment-guide-part-3-azure-infra/)
- **Part 4**: GitHub Workflow for Terraform Apply & Destroy **You are here** 😊

Do you want to deploy your Streamlit application on Azure right now? Use the [template repository](https://github.com/WayneGoosen/azure-streamlit-poc) 🚀

## TL;DR

See the [completed GitHub Workflow](#completed-workflow).

## Prerequisites

A basic understanding of GitHub Actions is required and the Workflow assumes you have the files from Part 3:

- /infra/main.tf
- /infra/providers.tf
- /infra/variables.tf
- /infra/locals.tf
- /infra/web-app.tf

If you have your own Terraform configuration, ensure all the dependent files are available and are stored within /infra folder for this Workflows to function correctly.

## Create a GitHub Workflow

The Workflow file should be stored within the following folder: `.github/workflows/`. A concise name could be `docker-image-build-and-push.yaml`.

### Completed Apply Workflow

```yaml
name: Terraform Plan & Apply Infrastructure

on:
push:
branches: ['main']
paths:
- 'infra/**'
tags:
- '*'
workflow_dispatch:

env:
TF_VAR_resource_group_name: 'rg-streamlit-poc'
WORKING_DIRECTORY: './infra'

jobs:
terraform:
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

# image name needs to be lowercase, some accounts have uppercase letters
- name: Get owner/repo name and convert to lowercase
id: get-image-name
run: echo "image-name=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT

- name: Extract image tag
id: extract-tag
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
TAG=${GITHUB_REF#refs/tags/}
else
TAG=$(git describe --tags --abbrev=0)
fi
echo "tag=$TAG" >> $GITHUB_OUTPUT
- name: Azure login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_ENTRA_ID_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_ENTRA_ID_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.8.4

- name: Terraform fmt
id: fmt
run: terraform fmt -check
continue-on-error: true

- name: Terraform Init
id: init
working-directory: ${{ env.WORKING_DIRECTORY }}
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_ENTRA_ID_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_ENTRA_ID_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_USE_OIDC: true
run: terraform init

- name: Terraform Validate
id: validate
working-directory: ${{ env.WORKING_DIRECTORY }}
run: terraform validate -no-color

- name: Terraform Plan
id: plan
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_ENTRA_ID_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_ENTRA_ID_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_USE_OIDC: true
TF_VAR_docker_image_name: '${{ steps.get-image-name.outputs.image-name }}:${{ steps.extract-tag.outputs.tag }}'
working-directory: ${{ env.WORKING_DIRECTORY }}
run: terraform plan -no-color
continue-on-error: false

- name: Terraform Apply (auto-approve)
working-directory: ${{ env.WORKING_DIRECTORY }}
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_ENTRA_ID_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_ENTRA_ID_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_USE_OIDC: true
TF_VAR_docker_image_name: '${{ steps.get-image-name.outputs.image-name }}:${{ steps.extract-tag.outputs.tag }}'
run: terraform apply -auto-approve
```
#### Workflow Walkthrough
##### Workflow Definition
```yaml
name: Docker Image Build and Push
```
The name of the workflow which is shown under the Actions tab. This allows you to set a readable name for your Workflow, if omitted the file name will be shown.
##### Triggers
```yaml
on:
push:
branches: ['main']
paths:
- 'app/**'
workflow_dispatch:
```
The workflow triggers on pushes to the "main" branch and only if the changes are made in the 'app' directory. The 'workflow_dispatch' allows the workflow to be triggered manually.
### Completed Destroy Workflow
```yaml
name: Terraform Destroy Inrastructure

on: workflow_dispatch

env:
TF_VAR_docker_image_name: 'waynegoosen/azure-streamlit-poc:0.1.2'
TF_VAR_resource_group_name: 'rg-streamlit-poc'
WORKING_DIRECTORY: './infra'

jobs:
terraform:
runs-on: ubuntu-latest
environment: production
permissions:
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Azure login
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_AD_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_AD_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.8.0

- name: Terraform Init
id: init
working-directory: ${{ env.WORKING_DIRECTORY }}
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
ARM_USE_OIDC: true
run: terraform init

- name: Terraform Destroy (auto-approve)
id: destroy
working-directory: ${{ env.WORKING_DIRECTORY }}
env:
ARM_CLIENT_ID: ${{ secrets.AZURE_AD_CLIENT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_AD_TENANT_ID }}
ARM_USE_OIDC: true
run: terraform destroy -auto-approve
```

0 comments on commit 93d0319

Please sign in to comment.