Prerequisites
Create an Azure Sandbox
Log into WhizLabs, navigate to the cloud sandbox, start an Azure sandbox environment, and log into the Azure Portal using the portal link and credentials provided. Note the limitations outlined by Whizlabs in the Sandbox Scope reference.
Create an Application Registration
Create an application registration with a client secret and NOT with Federated Credentials. If you create with a Federated Credential in this environment, anyone accessing this lab environment will have access to your private repository via the application registration. I recommend using a client secret with a short expiration date and time for security purposes.
Note that you can create an application registration with Federated Credentials, but do not forget to delete the application registration before your sandbox expires. WhizLabs highly Recommends deleting all resources created before your sandbox expires.
1. Open Microsoft Entra ID within the Azure Portal.
2. Select App registrations from the left menu bar.
3. Select New registration.
4. Give a name and press Register.
5. Select Certificates & secrets from the left menu, and add a client secret with a 24hr expiration date.
Assign the Application Registration Access Rights
Assigned the application registration Owner rights on one of the three resource groups provided within the sandbox. It's recommended to use the resource group with a region near you.
See, Grant Access
Create the Repository Secrets
With in your GitHub Private Repository create repository secrets using the values from the new application registration; ARM_CLIENT_ID, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID, and ARM_CLIENT_SECRET.
Create a GitHub Workflow
Within VSCode, clone your private repository locally and set up the following folder structure for the GitHub Actions workflow.
Create the following file structure.
.github |-- workflow |-- deploy-apply-demo.yml
The deploy-apply.yaml file
name: 'Plan and Apply' on: push: paths: - 'demo/**' - '.github/workflows/deploy-apply-demo.yml' permissions: id-token: write contents: read env: DEV_PATH: 'demo/environments/dev' # FOR GITHUB ACTIONS ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }} ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }} ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }} ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }} # FOR TERRAFORM TF_VAR_subscription_id: ${{ secrets.ARM_SUBSCRIPTION_ID }} TF_VAR_tenant_id: ${{ secrets.ARM_TENANT_ID }} TF_VAR_client_id: ${{ secrets.ARM_CLIENT_ID }} TF_VAR_client_secret: ${{ secrets.ARM_CLIENT_SECRET }} jobs: dev-plan: name: 'Running Development Plan' runs-on: ubuntu-latest steps: # Checkout the repository to the GitHub Actions runner - name: Checkout repository uses: actions/checkout@v4 # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token - name: Setup Terraform uses: hashicorp/setup-terraform@v3 # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. - name: Terraform Init run: terraform -chdir=${{ env.DEV_PATH }} init -backend=false # Format Terraform files to ensure they are properly formatted - name: Terraform Format Check run: terraform fmt -check # Generates an execution plan for Terraform - name: Terraform Plan run: terraform -chdir=${{ env.DEV_PATH }} plan -out=tfplandev # Upload the Terraform plan to the artifacts - name: Upload Terraform Plan uses: actions/upload-artifact@v4 with: name: tfplandev path: './${{ env.DEV_PATH }}/' dev-apply: name: 'Running Development Apply' runs-on: ubuntu-latest needs: dev-plan steps: # Checkout the repository to the GitHub Actions runner - name: Checkout uses: actions/checkout@v4 # Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token - name: Setup Terraform uses: hashicorp/setup-terraform@v3 # Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc. - name: Terraform Init run: terraform -chdir=${{ env.DEV_PATH }} init -upgrade -backend=false # Download saved plan from artifacts - name: Download Terraform Plan uses: actions/download-artifact@v4 with: name: tfplandev path: './${{ env.DEV_PATH }}/' # Terraform Apply - name: Terraform Apply run: terraform -chdir=${{ env.DEV_PATH }} apply -refresh-only -auto-approve tfplandev
Create the Terraform
Within VSCode, create the following file structure:
.github |-- workflow |-- deploy-apply-demo.yml |-- demo |-- main.tf |-- variables.tf
The main.tf file
Note: Replace the resource group name under locals with your Whizlabs-provided resource group name and replace the storage account name with your own.
locals { resource_group_name = "<ADD_RG_NAME" locations = { "primary" = "Central US" "secondary" = "East US 2" } tier = { "sandbox" = "sbox" "development" = "dev" "production" = "prod" } tags = { "managedby" = "terraform" } } # We strongly recommend using the required_providers block to set the # Azure Provider source and version being used terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "4.7.0" } } } # Configure the Microsoft Azure Provider provider "azurerm" { subscription_id = var.subscription_id tenant_id = var.tenant_id resource_provider_registrations = "none" # This is only required when the User, Service Principal, or Identity running Terraform lacks the permissions to register Azure Resource Providers. use_oidc = true features } # Get a resource group data "azurerm_resource_group" "rg_management" { name = local.resource_group_name } resource "azurerm_storage_account" "storage_account" { name = "<add_your_sa_name_here" resource_group_name="data.azurerm_resource_group.rg_management.name" location="data.azurerm_resource_group.rg_management.location" account_tier="Standard" account_replication_type="LRS" }<="" pre=""> <p>The variables.tf file</p> <pre>variable "subscription_id" { description = "The subscription ID for the Azure account" type = string } variable "tenant_id" { description = "The tenant ID for the Azure account" type = string }</pre></add_your_sa_name_here">
The variables.tf file
variable "subscription_id" { description = "The subscription ID for the Azure account" type = string } variable "tenant_id" { description = "The tenant ID for the Azure account" type = string }
Commit the Code
Once the above folder structure and files are in place, commit the code to push it to your repo and start the GitHub Action. Once finished, you should have a storage account in the specified resource group.