From 468714e8a0d89931e4d830a5d7163b1cc076e2d9 Mon Sep 17 00:00:00 2001 From: Luca Cavallin <14332663+lucavallin@users.noreply.github.com> Date: Tue, 5 Dec 2023 13:13:46 +0000 Subject: [PATCH] implement resources for azure --- src/.terraform.lock.hcl | 39 +++++++++++++++++++++++++++ src/azure.tf | 52 ++++++++++++++++++++++++++++++++++++ src/gcp.tf | 18 +++++-------- src/main.tf | 10 +++++++ src/outputs.tf | 18 ++++++++++--- src/provider.tf | 5 +++- src/terraform.tfvars.example | 2 +- src/variables.tf | 2 +- src/versions.tf | 4 +++ 9 files changed, 131 insertions(+), 19 deletions(-) diff --git a/src/.terraform.lock.hcl b/src/.terraform.lock.hcl index 72edd6e..6ef7cd8 100644 --- a/src/.terraform.lock.hcl +++ b/src/.terraform.lock.hcl @@ -24,6 +24,26 @@ provider "registry.terraform.io/hashicorp/aws" { ] } +provider "registry.terraform.io/hashicorp/azuread" { + version = "2.46.0" + constraints = "2.46.0" + hashes = [ + "h1:8cUf14zX4TJTPQAhE9c1oW0k4v+pdx3QLlsNLXivorw=", + "zh:1b9bfe88b02684dca86591ed595d2d9e2ca4fdd146812cbf2baea4260aa1cf45", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:1d13a97907cab6cbc104686f2c50b9d9f90baf3f0aaf767dc7b09e2d6890c519", + "zh:2295c497feb55bd614b7ec81944c62f615dbea14bbab13fa5bc942a172435601", + "zh:30b289c45f2917c48d3b299ca57fe3c60f1d23c711db1ad02eb1c3397ead6cfc", + "zh:3c8f8c95e05c8bf20f54db4d8e69c4a50256547440fec951afabe405cf9732bd", + "zh:47a643662a336e35015e9582bd0ceb75980ba229f75a3dc45b7819c3b831c9a4", + "zh:82cd21a53d40967e83789fa0cb2d6853b8b2f76aab13fad7a859dc50f2e7101c", + "zh:aded4409a899d4f4be43021f672f762ecf99e90c852f1d58886edcbbf0d7200e", + "zh:d089206976d986a44ef6d43d883a1aba9828f64db6f7a9427c74152d0a8ea8dc", + "zh:e40e35454c5f1074b7642de11069ad1221b6ddba3d56e1d1e24fc459481f7ea3", + "zh:eabea628fe8062c912626d33d221b261f2e657a0423d45f09ea2e36119201a17", + ] +} + provider "registry.terraform.io/hashicorp/azurerm" { version = "3.83.0" constraints = "3.83.0" @@ -63,3 +83,22 @@ provider "registry.terraform.io/hashicorp/google" { "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", ] } + +provider "registry.terraform.io/hashicorp/random" { + version = "3.6.0" + hashes = [ + "h1:R5Ucn26riKIEijcsiOMBR3uOAjuOMfI1x7XvH4P6B1w=", + "zh:03360ed3ecd31e8c5dac9c95fe0858be50f3e9a0d0c654b5e504109c2159287d", + "zh:1c67ac51254ba2a2bb53a25e8ae7e4d076103483f55f39b426ec55e47d1fe211", + "zh:24a17bba7f6d679538ff51b3a2f378cedadede97af8a1db7dad4fd8d6d50f829", + "zh:30ffb297ffd1633175d6545d37c2217e2cef9545a6e03946e514c59c0859b77d", + "zh:454ce4b3dbc73e6775f2f6605d45cee6e16c3872a2e66a2c97993d6e5cbd7055", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:91df0a9fab329aff2ff4cf26797592eb7a3a90b4a0c04d64ce186654e0cc6e17", + "zh:aa57384b85622a9f7bfb5d4512ca88e61f22a9cea9f30febaa4c98c68ff0dc21", + "zh:c4a3e329ba786ffb6f2b694e1fd41d413a7010f3a53c20b432325a94fa71e839", + "zh:e2699bc9116447f96c53d55f2a00570f982e6f9935038c3810603572693712d0", + "zh:e747c0fd5d7684e5bfad8aa0ca441903f15ae7a98a737ff6aca24ba223207e2c", + "zh:f1ca75f417ce490368f047b63ec09fd003711ae48487fba90b4aba2ccf71920e", + ] +} diff --git a/src/azure.tf b/src/azure.tf index e69de29..3a29f57 100644 --- a/src/azure.tf +++ b/src/azure.tf @@ -0,0 +1,52 @@ +data "azurerm_subscription" "this" {} + +data "azuread_client_config" "this" {} + +# Resource group to contain resources for Actions on GHES with OIDC +resource "azurerm_resource_group" "this" { + name = local.ghes_instance_name + location = "West Europe" +} + +resource "random_string" "az_storage_account_name" { + length = 24 + lower = true + numeric = true + special = false + upper = false +} + +# Storage Account for Actions data +resource "azurerm_storage_account" "this" { + name = random_string.az_storage_account_name.result + resource_group_name = azurerm_resource_group.this.name + location = azurerm_resource_group.this.location + account_tier = "Standard" + # Locally redundant storage (cheapest) + account_replication_type = "LRS" +} + +# Azure Active Directory (AAD) application for OIDC +resource "azuread_application" "this" { + display_name = local.ghes_instance_name +} + +resource "azuread_application_federated_identity_credential" "this" { + application_id = azuread_application.this.id + display_name = local.ghes_instance_name + description = "OIDC for Actions on GHES" + audiences = ["api://AzureADTokenExchange"] + issuer = local.issuer_uri + subject = local.ghes_url +} + +# Grant the AAD Application access to the Storage Account +resource "azuread_service_principal" "this" { + client_id = azuread_application.this.client_id +} + +resource "azurerm_role_assignment" "this" { + scope = data.azurerm_subscription.this.id + role_definition_name = "Storage Blob Data Owner" + principal_id = azuread_service_principal.this.id +} diff --git a/src/gcp.tf b/src/gcp.tf index e07432d..1caa52b 100644 --- a/src/gcp.tf +++ b/src/gcp.tf @@ -1,9 +1,3 @@ -locals { - gcp_project_id = var.GCP_PROJECT_ID - ghes_hostname = var.GHES_HOSTNAME - ghes_url = var.GHES_URL -} - data "google_project" "this" { project_id = local.gcp_project_id } @@ -22,14 +16,14 @@ resource "google_project_service" "iam_credentials" { resource "google_iam_workload_identity_pool" "this" { project = data.google_project.this.project_id workload_identity_pool_id = "wip-ghes" - description = "Identity Pool for GHES instance ${local.ghes_hostname}." + description = "Identity Pool for GHES instance ${local.ghes_instance_name}." } resource "google_iam_workload_identity_pool_provider" "this" { project = data.google_project.this.project_id workload_identity_pool_id = google_iam_workload_identity_pool.this.workload_identity_pool_id workload_identity_pool_provider_id = "wipp-ghes-oidc" - description = "Identity Pool Provider for OIDC on GHES instance ${local.ghes_hostname}." + description = "Identity Pool Provider for OIDC on GHES instance ${local.ghes_instance_name}." attribute_condition = "google.subject == \"${local.ghes_url}\"" attribute_mapping = { @@ -37,16 +31,16 @@ resource "google_iam_workload_identity_pool_provider" "this" { } oidc { - issuer_uri = "https://${local.ghes_url}/_services/token" + issuer_uri = local.issuer_uri } } # Create service account and assign required permissions resource "google_service_account" "this" { project = data.google_project.this.project_id - account_id = "sa-${substr(local.ghes_hostname, 0, 20)}-oidc" + account_id = "sa-${substr(local.ghes_instance_name, 0, 20)}-oidc" display_name = "Service Account for OIDC on GHES" - description = "Service Account for OIDC on GHES instance ${local.ghes_hostname}." + description = "Service Account for OIDC on GHES instance ${local.ghes_instance_name}." } resource "google_project_iam_binding" "sa_storage" { @@ -71,7 +65,7 @@ resource "google_service_account_iam_binding" "sa_workload_identity" { # Storage bucket for Actions data resource "google_storage_bucket" "this" { project = data.google_project.this.project_id - name = "sb-${local.ghes_hostname}" + name = "sb-${local.ghes_instance_name}" location = "EUROPE-WEST4" storage_class = "STANDARD" diff --git a/src/main.tf b/src/main.tf index e69de29..57dec54 100644 --- a/src/main.tf +++ b/src/main.tf @@ -0,0 +1,10 @@ +locals { + ghes_instance_name = var.GHES_INSTANCE_NAME + ghes_url = var.GHES_URL + issuer_uri = "https://${local.ghes_url}/_services/token" + + azure_blob_endpoint_suffix = "core.windows.net" + + gcp_project_id = var.GCP_PROJECT_ID + gcp_service_url = "storage.googleapis.com" +} diff --git a/src/outputs.tf b/src/outputs.tf index 7c99dd5..d1899f3 100644 --- a/src/outputs.tf +++ b/src/outputs.tf @@ -1,12 +1,22 @@ -locals { - gcp_service_url = "storage.googleapis.com" -} - # GitHub Enterprise Server URL output "ghes_settings_url" { value = "https://${local.ghes_url}:8443" } +# Azure Configuration for OIDC +output "azure_tenant_id" { + value = data.azuread_client_config.this.tenant_id +} +output "azure_client_id" { + value = azuread_application.this.client_id +} +output "azure_storage_account_name" { + value = azurerm_storage_account.this.name +} +output "azure_blob_endpoint_suffix" { + value = local.azure_blob_endpoint_suffix +} + # Google Cloud Configuration for OIDC output "gcp_service_url" { value = "https://${local.gcp_service_url}" diff --git a/src/provider.tf b/src/provider.tf index fe0a3bf..29ef225 100644 --- a/src/provider.tf +++ b/src/provider.tf @@ -1,3 +1,6 @@ -provider "azurerm" {} +provider "azurerm" { + features {} +} +provider "azuread" {} provider "aws" {} provider "google" {} diff --git a/src/terraform.tfvars.example b/src/terraform.tfvars.example index a9849a2..e1d2905 100644 --- a/src/terraform.tfvars.example +++ b/src/terraform.tfvars.example @@ -1,3 +1,3 @@ -GHES_HOSTNAME = "" +GHES_INSTANCE_NAME = "" GHES_URL = "" GCP_PROJECT_ID = "" diff --git a/src/variables.tf b/src/variables.tf index 3fc2ee9..e10ebc8 100644 --- a/src/variables.tf +++ b/src/variables.tf @@ -1,5 +1,5 @@ # The hostname of the GHES instance (e.g. my-ghes-instance) -variable "GHES_HOSTNAME" { +variable "GHES_INSTANCE_NAME" { type = string } diff --git a/src/versions.tf b/src/versions.tf index ab819cb..b4479e1 100644 --- a/src/versions.tf +++ b/src/versions.tf @@ -5,6 +5,10 @@ terraform { source = "hashicorp/azurerm" version = "3.83.0" } + azuread = { + source = "hashicorp/azuread" + version = "2.46.0" + } aws = { source = "hashicorp/aws" version = "5.29.0"