← all posts

Managing GitHub secrets using terraform

Gordon Beeming
Gordon Beeming
On this page7 sections

#YouTube Video

In this video we'll take a look at Managing GitHub secrets using terraform as well as federated identities from GitHub into Azure.

You should only be storing secrets if you absolutely need to, in this demo although we are only accessing storage accounts the change from a storage connection string to Azure Federated Identity means that we can access any of resource the identity has access too using RBAC which is a much better overall approach.

Posted originally on 11 Aug 2022 on the @gordonbeeming YouTube channel.

Make sure you take a look in the description of the video on YouTube for shared links.

All code from this demo can be found on GitHub at https://github.com/GordonBeeming-org/Managing-GitHub-secrets-using-terraform.

Specific snippets created in the demo can also be found below for convenience

#main.tf

main.tf
provider "github" {
  token = var.github_token
  owner = "GordonBeeming-org"
}

data "github_user" "current" {
  username = "GordonBeeming"
}

#variables.tf

variables.tf
variable "github_token" {
  type = string
  sensitive = true
}

#gh-repo.tf

gh-repo.tf
data "github_repository" "main" {
  full_name = "GordonBeeming-org/Managing-GitHub-secrets-using-terraform"
}

resource "github_repository_environment" "main" {
  environment  = var.environment_name
  repository   = data.github_repository.main.id
  reviewers {
    users = var.environment_name == "production" ? [data.github_user.current.id] : null
  }
}

# STORAGE_CONNECTION
resource "github_actions_environment_secret" "STORAGE_CONNECTION" {
  repository       = data.github_repository.main.id
  environment      = github_repository_environment.main.environment
  secret_name      = "STORAGE_CONNECTION"
  plaintext_value  = azurerm_storage_account.main.primary_connection_string
}



# Change for federated identities used the below instead of storage connection above



# ARM_CLIENT_ID
resource "github_actions_environment_secret" "ARM_CLIENT_ID" {
  repository       = data.github_repository.main.id
  environment      = github_repository_environment.main.environment
  secret_name      = "ARM_CLIENT_ID"
  plaintext_value  = azuread_application.main.application_id
}

# ARM_TENANT_ID
resource "github_actions_environment_secret" "ARM_TENANT_ID" {
  repository       = data.github_repository.main.id
  environment      = github_repository_environment.main.environment
  secret_name      = "ARM_TENANT_ID"
  plaintext_value  = data.azurerm_client_config.current.tenant_id
}

# ARM_SUBSCRIPTION_ID
resource "github_actions_environment_secret" "ARM_SUBSCRIPTION_ID" {
  repository       = data.github_repository.main.id
  environment      = github_repository_environment.main.environment
  secret_name      = "ARM_SUBSCRIPTION_ID"
  plaintext_value  = data.azurerm_client_config.current.subscription_id
}

#publish.yml (1st)

publish.yml (connection string)
name: publish

on:
  push:
    branches: [ "main", "demo" ]

jobs:
  copy-files:
    continue-on-error: false
    strategy:
      matrix:
        environment: [local, test, production]
    runs-on: ubuntu-latest
    environment: ${{ matrix.environment }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Upload File
        uses: azure/CLI@v1
        env:
          STORAGE_CONNECTION: ${{ secrets.STORAGE_CONNECTION }}
        with:
          azcliversion: 2.36.0
          inlineScript: |
            az storage blob upload --account-name demo2${{ matrix.environment }}dso --file README.md --container-name demo --name README.md --overwrite --connection-string $STORAGE_CONNECTION

#publish.yml (2nd)

publish.yml (federated identity)
name: publish

on:
  push:
    branches: [ "main", "demo" ]

jobs:
  copy-files:
    continue-on-error: false
    strategy:
      matrix:
        environment: [local, test, production]
    runs-on: ubuntu-latest
    environment: ${{ matrix.environment }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - uses: azure/login@v1
        with:
          client-id: ${{ secrets.ARM_CLIENT_ID }}
          tenant-id: ${{ secrets.ARM_TENANT_ID }}
          subscription-id: ${{ secrets.ARM_SUBSCRIPTION_ID }}

      - name: Upload File
        uses: azure/CLI@v1
        with:
          azcliversion: 2.36.0
          inlineScript: |
            az storage blob upload --account-name demo2${{ matrix.environment }}dso --file README.md --container-name demo --name README.md --overwrite

      - name: logout
        uses: azure/CLI@v1
        with:
          azcliversion: 2.36.0
          inlineScript: |
            az logout

#storage.tf

storage.tf
resource "azurerm_storage_container" "demo" {
  name                  = "demo"
  storage_account_name  = azurerm_storage_account.main.name
  container_access_type = "private"

  lifecycle {
    prevent_destroy = true
  }
}
Gordon Beeming
Gordon Beeming

Father • Husband • Triathlete • SSW Solution Architect

Related posts