Managing GitHub secrets using terraform
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
provider "github" {
token = var.github_token
owner = "GordonBeeming-org"
}
data "github_user" "current" {
username = "GordonBeeming"
}#variables.tf
variable "github_token" {
type = string
sensitive = true
}#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)
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)
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
resource "azurerm_storage_container" "demo" {
name = "demo"
storage_account_name = azurerm_storage_account.main.name
container_access_type = "private"
lifecycle {
prevent_destroy = true
}
}