Skip to content

Commit

Permalink
Merge pull request #36 from Lucioschenkel/main
Browse files Browse the repository at this point in the history
#25 - Creates a Terraform Github Workflow
  • Loading branch information
mischavandenburg authored Jan 2, 2025
2 parents 536e13f + 837e900 commit 68c21e1
Show file tree
Hide file tree
Showing 3 changed files with 215 additions and 0 deletions.
141 changes: 141 additions & 0 deletions .github/workflows/terraform-pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Terraform pipeline

on:
workflow_dispatch:
push:
paths:
- 'terraform/**'
branches:
- main

permissions:
id-token: write
contents: read

env:
ARM_ACCESS_KEY: ${{ secrets.ARM_ACCESS_KEY }}
ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}

jobs:
plan:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./terraform
name: Plan
steps:
- name: Checkout
uses: actions/checkout@v4

- 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 terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform format check
continue-on-error: true
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
id: plan
run: terraform plan -no-color -out terraform-plan

- uses: WcAServices/markdown-template-action@v1
continue-on-error: true
with:
# These will be injected into the below template, in addition to GitHub's standard
# variables. You can perform string operations here as well.
variables: >-
FMT_OUTCOME="${{ steps.fmt.outcome }}"
INIT_OUTCOME="${{ steps.init.outcome }}"
VALIDATE_OUTCOME="${{ steps.validate.outcome }}"
VALIDATE_OUTPUT="${{ steps.validate.outputs.stdout }}"
PLAN_OUTCOME="${{ steps.plan.outcome }}"
PLAN_OUTPUT="${{ steps.plan.outputs.stdout }}"
template: |
#### Terraform Format and Style 🖌`$FMT_OUTCOME`
#### Terraform Initialization ⚙️`$INIT_OUTCOME`
#### Terraform Validation 🤖`$VALIDATE_OUTCOME`
<details>
<summary>Validation Output</summary>
```
$VALIDATE_OUTPUT
```
</details>
#### Terraform Plan 📖`$PLAN_OUTCOME`
<details>
<summary>Show Plan</summary>
```terraform
$PLAN_OUTPUT
```
</details>
*Actor: @$GITHUB_ACTOR, Action: `$GITHUB_EVENT_NAME`*
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: plan
path: ./terraform

apply:
runs-on: ubuntu-latest
environment: staging
needs: plan
name: Apply
defaults:
run:
working-directory: ./terraform
steps:
- name: Checkout
uses: actions/checkout@v4

- 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 terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform init
run: terraform init

- name: Download artifact
uses: actions/download-artifact@v4
with:
name: plan
path: ./terraform

- name: Terraform apply
run: terraform apply -auto-approve terraform-plan

61 changes: 61 additions & 0 deletions docs/terraform-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# How to setup and use the terraform pipeline

## Intro

This document explains how to use the workflow located at `.github/workflows/terraform-pipeline.yml`. You might want to use this workflow to provision the [`kubecraft`](https://github.com/mischavandenburg/kubecraft) community project on your own infrastructure on Azure.

## Pre-requisites

To follow along, you will need:

- A fork of [`mischavandenburg/kubecraft`](https://github.com/mischavandenburg/kubecraft) on your Github account.
- An Azure account with an active subscription.

## Azure setup

Before executing the pipeline on your Github account, we need to configure the remote backend (`azurerm` provider on Azure Blob Storage) and obtain the details for OIDC authentication.

### Service Principal and Federated Identity

Follow these documents in order for a complete walk-through to setup a service principal with a federated identity for OIDC authentication from Github actions:

- [Create a service principal](https://learn.microsoft.com/en-us/entra/identity-platform/howto-create-service-principal-portal)
- [Configure a federated identity](https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azp#github-actions)

**Note:** You will need to create credentials valid for a `push` to the `main` branch, and for the `staging` environment.

### Remote backend configuration

For the remote backend configuration, we will need to configure a resource group, storage account, and container on Azure Blob Storage. You can use the following script to provision these resources:

```bash
#!/bin/bash

RESOURCE_GROUP_NAME=tfstate
STORAGE_ACCOUNT_NAME=tfstate$RANDOM
CONTAINER_NAME=tfstate

# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location eastus

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob

# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME

ACCOUNT_KEY=$(az storage account keys list --resource-group tfstate --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
```

Now, take note of your `$STORAGE_ACCOUNT_NAME`. You will need to specify its value under the `storage_account_name` property of the `backend` configuration on `terraform/providers`.

Also, copy your `ACCOUNT_KEY` and store it on Github Actions secrets under a secret named `ARM_ACCESS_KEY`.

### Github environment

The Terraform pipeline leverages environment protection rules to enable manual approvals for the `terraform apply` command. In order to use this workflow, you will need to create a `staging` environment from your repository settings page (on your own fork). You don't need to add any environment protection rules if you don't want to, but if you do, simply check the "require approvals" checkbox and add yourself as a required reviewer.

### Push and Test

Once you've created the secrets on Github Actions for OIDC authentication, adjusted the backend provider configuration to your own Azure storage account, and created the `staging` environment on your repository, commit your changes and push the code to your `main` branch. This will trigger the pipeline automatically. Alternatively, you can navigate to `https://github.com/your-username/kubecraft/actions`, select the Terraform pipeline workflow on the left hand side menu, and use the "Run workflow" button to manually trigger the workflow execution.

13 changes: 13 additions & 0 deletions terraform/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,21 @@ terraform {
version = "~>3.0"
}
}

backend "azurerm" {
resource_group_name = "tfstate"
# TODO: use your own storage_account_name
storage_account_name = "tfstate1028"
container_name = "tfstate"
key = "terraform.tfstate"
}
}

provider "azurerm" {
features {}
}

provider "azapi" {
use_oidc = true
}

0 comments on commit 68c21e1

Please sign in to comment.