diff --git a/modules/github-azure-oidc/README.md b/modules/github-azure-oidc/README.md new file mode 100644 index 0000000..7774967 --- /dev/null +++ b/modules/github-azure-oidc/README.md @@ -0,0 +1,70 @@ +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.6 | +| [azurerm](#requirement\_azurerm) | >=3.0.0 | +| [google-beta](#requirement\_google-beta) | >= 3.77 | +| [random](#requirement\_random) | >= 3.6 | + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | >=3.0.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_federated_identity_credential.bootstrap_drift_credentials](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource | +| [azurerm_federated_identity_credential.bootstrap_pull_request_credentials](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource | +| [azurerm_federated_identity_credential.organization_drift_credentials](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource | +| [azurerm_federated_identity_credential.organization_pull_request_credentials](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource | +| [azurerm_resource_group.github_foundations_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource | +| [azurerm_role_assignment.bootstrap_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | +| [azurerm_role_assignment.organization_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource | +| [azurerm_storage_account.github_foundations_sa](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource | +| [azurerm_storage_container.github_foundations_tf_state_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) | resource | +| [azurerm_storage_container.github_foundations_tf_state_encrypted_container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) | resource | +| [azurerm_storage_encryption_scope.encryption_scope](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_encryption_scope) | resource | +| [azurerm_user_assigned_identity.bootstrap_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | +| [azurerm_user_assigned_identity.organization_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource | +| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source | +| [azurerm_key_vault.key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault) | data source | +| [azurerm_resource_group.github_foundations_rg](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [drift\_detection\_branch\_name](#input\_drift\_detection\_branch\_name) | The name of the branch to use for drift detection. | `string` | n/a | yes | +| [github\_foundations\_organization\_name](#input\_github\_foundations\_organization\_name) | The name of the organization that the github foundation repos will be under. | `string` | n/a | yes | +| [kv\_name](#input\_kv\_name) | The name of the key vault to use for github foundation secrets. If storing secrets to authenticate against github in a different way then this does not need to be set. (Optional) | `string` | `""` | no | +| [kv\_resource\_group](#input\_kv\_resource\_group) | The name of the resource group that the key vault is in. If empty it will default to the github foundations resource group. | `string` | n/a | yes | +| [rg\_create](#input\_rg\_create) | Create the resource group. When set to false it uses the `rg_name` input to reference an existing resource group. Defaults to true. | `bool` | `true` | no | +| [rg\_location](#input\_rg\_location) | The location of the resource group to create the github foundation azure resources in. | `string` | n/a | yes | +| [rg\_name](#input\_rg\_name) | The name of the resource group to create the github foundation azure resources in. | `string` | n/a | yes | +| [sa\_name](#input\_sa\_name) | The name of the storage account for github foundations. | `string` | n/a | yes | +| [sa\_replication\_type](#input\_sa\_replication\_type) | The replication type of the storage account for github foundations. Valid options are LRS, GRS, RAGRS, ZRS, GZRS, and RA\_GZRS. Defaults to GRS. | `string` | `"GRS"` | no | +| [sa\_tier](#input\_sa\_tier) | The tier of the storage account for github foundations. Valid options are Standard and Premium. Defaults to Standard. | `string` | `"Standard"` | no | +| [tf\_state\_container](#input\_tf\_state\_container) | The name of the container to store the terraform state file(s) in. | `string` | `"tfstate"` | no | +| [tf\_state\_container\_anonymous\_access\_level](#input\_tf\_state\_container\_anonymous\_access\_level) | The anonymous access level of the container to store the terraform state file(s) in. | `string` | `"private"` | no | +| [tf\_state\_container\_default\_encryption\_scope](#input\_tf\_state\_container\_default\_encryption\_scope) | The default encryption scope of the container to store the terraform state file(s) in. |
object({
name = string
source = string
key_vault_key_id = optional(string)
}) | {
"name": "",
"source": "",
"storage_account_id": ""
} | no |
+| [tf\_state\_container\_encryption\_scope\_override\_enabled](#input\_tf\_state\_container\_encryption\_scope\_override\_enabled) | Whether or not the encryption scope override is enabled for the container to store the terraform state file(s) in. Defaults to false | `bool` | `false` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [bootstrap\_client\_id](#output\_bootstrap\_client\_id) | Bootstrap repository client id for authenticating with oidc. |
+| [container\_name](#output\_container\_name) | Terraform state container name. |
+| [organization\_client\_id](#output\_organization\_client\_id) | Organizations repository client id for authenticating with oidc. |
+| [resource\_group](#output\_resource\_group) | Resource group name. |
+| [sa\_name](#output\_sa\_name) | Terraform state container storage account name. |
+| [subscription\_id](#output\_subscription\_id) | Azure subscription id for authenticating with oidc. |
+| [tenant\_id](#output\_tenant\_id) | Azure tenant id for authenticating with oidc. |
\ No newline at end of file
diff --git a/modules/github-azure-oidc/oidc.tf b/modules/github-azure-oidc/oidc.tf
new file mode 100644
index 0000000..10a1865
--- /dev/null
+++ b/modules/github-azure-oidc/oidc.tf
@@ -0,0 +1,109 @@
+locals {
+ default_audience_name = "api://AzureADTokenExchange"
+ github_issuer_url = "https://token.actions.githubusercontent.com"
+
+ bootstrap_repo_name = "bootstrap"
+ organizations_repo_name = "organizations"
+
+ state_file_access_roles = {
+ "container-${local.tf_state_container.name}-write" = {
+ scope = "${local.tf_state_container.resource_manager_id}"
+ role_definition_name = "Storage Blob Data Contributor"
+ },
+ "storage-account-${azurerm_storage_account.github_foundations_sa.name}-contributor" = {
+ scope = "${azurerm_storage_account.github_foundations_sa.id}"
+ role_definition_name = "Storage Account Contributor"
+ }
+ }
+
+ bootstrap_project_roles = local.state_file_access_roles
+
+ organizations_project_roles = merge(
+ local.state_file_access_roles,
+ var.kv_name != "" ? {
+ "keyvault-${data.azurerm_key_vault.key_vault[0].name}-secret-read" = {
+ scope = "${data.azurerm_key_vault.key_vault[0].id}"
+ role_definition_name = "Key Vault Secrets User"
+ }
+ }: {},
+ var.kv_name != "" ? {
+ "keyvault-${data.azurerm_key_vault.key_vault[0].name}-vault-read" = {
+ scope = "${data.azurerm_key_vault.key_vault[0].id}"
+ role_definition_name = "Key Vault Reader"
+ }
+ }: {}
+ )
+}
+
+data "azurerm_client_config" "current" {}
+
+data "azurerm_key_vault" "key_vault" {
+ count = var.kv_name != "" ? 1 : 0
+ name = var.kv_name
+ resource_group_name = var.kv_resource_group != "" ? var.kv_resource_group : local.github_foundations_rg.name
+}
+
+/**
+* User assigned identities and roles for github state bucket and federated identity setup
+*/
+resource "azurerm_user_assigned_identity" "bootstrap_identity" {
+ location = local.github_foundations_rg.location
+ resource_group_name = local.github_foundations_rg.name
+ name = "${local.bootstrap_repo_name}-identity"
+}
+
+resource "azurerm_role_assignment" "bootstrap_role_assignment" {
+ for_each = local.bootstrap_project_roles
+ scope = each.value.scope
+ role_definition_name = each.value.role_definition_name
+ principal_id = azurerm_user_assigned_identity.bootstrap_identity.principal_id
+}
+
+resource "azurerm_user_assigned_identity" "organization_identity" {
+ location = local.github_foundations_rg.location
+ resource_group_name = local.github_foundations_rg.name
+ name = "${local.organizations_repo_name}-identity"
+}
+
+resource "azurerm_role_assignment" "organization_role_assignment" {
+ for_each = local.organizations_project_roles
+ scope = each.value.scope
+ role_definition_name = each.value.role_definition_name
+ principal_id = azurerm_user_assigned_identity.organization_identity.principal_id
+}
+
+resource "azurerm_federated_identity_credential" "bootstrap_pull_request_credentials" {
+ name = "${var.github_foundations_organization_name}-${local.bootstrap_repo_name}-pr-credentials"
+ resource_group_name = local.github_foundations_rg.name
+ audience = [local.default_audience_name]
+ issuer = local.github_issuer_url
+ parent_id = azurerm_user_assigned_identity.bootstrap_identity.id
+ subject = "repo:${var.github_foundations_organization_name}/${local.bootstrap_repo_name}:pull_request"
+}
+
+resource "azurerm_federated_identity_credential" "bootstrap_drift_credentials" {
+ name = "${var.github_foundations_organization_name}-${local.bootstrap_repo_name}-drift-credentials"
+ resource_group_name = local.github_foundations_rg.name
+ audience = [local.default_audience_name]
+ issuer = local.github_issuer_url
+ parent_id = azurerm_user_assigned_identity.bootstrap_identity.id
+ subject = "repo:${var.github_foundations_organization_name}/${local.bootstrap_repo_name}:ref:refs/heads/${var.drift_detection_branch_name}"
+}
+
+resource "azurerm_federated_identity_credential" "organization_pull_request_credentials" {
+ name = "${var.github_foundations_organization_name}-${local.organizations_repo_name}-pr-credentials"
+ resource_group_name = local.github_foundations_rg.name
+ audience = [local.default_audience_name]
+ issuer = local.github_issuer_url
+ parent_id = azurerm_user_assigned_identity.organization_identity.id
+ subject = "repo:${var.github_foundations_organization_name}/${local.organizations_repo_name}:pull_request"
+}
+
+resource "azurerm_federated_identity_credential" "organization_drift_credentials" {
+ name = "${var.github_foundations_organization_name}-${local.organizations_repo_name}-drift-credentials"
+ resource_group_name = local.github_foundations_rg.name
+ audience = [local.default_audience_name]
+ issuer = local.github_issuer_url
+ parent_id = azurerm_user_assigned_identity.organization_identity.id
+ subject = "repo:${var.github_foundations_organization_name}/${local.organizations_repo_name}:ref:refs/heads/${var.drift_detection_branch_name}"
+}
diff --git a/modules/github-azure-oidc/outputs.tf b/modules/github-azure-oidc/outputs.tf
new file mode 100644
index 0000000..d26968a
--- /dev/null
+++ b/modules/github-azure-oidc/outputs.tf
@@ -0,0 +1,34 @@
+output "resource_group" {
+ description = "Resource group name."
+ value = local.github_foundations_rg.name
+}
+
+output "bootstrap_client_id" {
+ description = "Bootstrap repository client id for authenticating with oidc."
+ value = azurerm_user_assigned_identity.bootstrap_identity.client_id
+}
+
+output "organization_client_id" {
+ description = "Organizations repository client id for authenticating with oidc."
+ value = azurerm_user_assigned_identity.organization_identity.client_id
+}
+
+output "tenant_id" {
+ description = "Azure tenant id for authenticating with oidc."
+ value = data.azurerm_client_config.current.tenant_id
+}
+
+output "subscription_id" {
+ description = "Azure subscription id for authenticating with oidc."
+ value = data.azurerm_client_config.current.subscription_id
+}
+
+output "sa_name" {
+ description = "Terraform state container storage account name."
+ value = azurerm_storage_account.github_foundations_sa.name
+}
+
+output "container_name" {
+ description = "Terraform state container name."
+ value = local.tf_state_container.name
+}
\ No newline at end of file
diff --git a/modules/github-azure-oidc/resource_group.tf b/modules/github-azure-oidc/resource_group.tf
new file mode 100644
index 0000000..9632e1a
--- /dev/null
+++ b/modules/github-azure-oidc/resource_group.tf
@@ -0,0 +1,17 @@
+locals {
+ github_foundations_rg = (
+ var.rg_create
+ ? try(azurerm_resource_group.github_foundations_rg[0], null)
+ : try(data.azurerm_resource_group.github_foundations_rg[0], null)
+ )
+}
+
+data "azurerm_resource_group" "github_foundations_rg" {
+ count = var.rg_create ? 0 : 1
+ name = var.rg_name
+}
+resource "azurerm_resource_group" "github_foundations_rg" {
+ count = var.rg_create ? 1 : 0
+ name = var.rg_name
+ location = var.rg_location
+}
\ No newline at end of file
diff --git a/modules/github-azure-oidc/storage.tf b/modules/github-azure-oidc/storage.tf
new file mode 100644
index 0000000..ba6181f
--- /dev/null
+++ b/modules/github-azure-oidc/storage.tf
@@ -0,0 +1,36 @@
+locals {
+ default_encryption_scope = var.tf_state_container_default_encryption_scope.name != "" ? azurerm_storage_encryption_scope.encryption_scope[0].name : null
+ tf_state_container = local.default_encryption_scope == null ? azurerm_storage_container.github_foundations_tf_state_container[0] : azurerm_storage_container.github_foundations_tf_state_encrypted_container[0]
+}
+
+resource "azurerm_storage_account" "github_foundations_sa" {
+ name = var.sa_name
+ resource_group_name = local.github_foundations_rg.name
+ location = local.github_foundations_rg.location
+ account_tier = var.sa_tier
+ account_replication_type = var.sa_replication_type
+}
+
+resource "azurerm_storage_encryption_scope" "encryption_scope" {
+ count = var.tf_state_container_default_encryption_scope.name != "" ? 1 : 0
+ name = var.tf_state_container_default_encryption_scope.name
+ storage_account_id = azurerm_storage_account.github_foundations_sa.id
+ source = var.tf_state_container_default_encryption_scope.source
+ key_vault_key_id = var.tf_state_container_default_encryption_scope.key_vault_key_id
+}
+
+resource "azurerm_storage_container" "github_foundations_tf_state_container" {
+ count = local.default_encryption_scope == null ? 1 : 0
+ name = var.tf_state_container
+ storage_account_name = azurerm_storage_account.github_foundations_sa.name
+ container_access_type = var.tf_state_container_anonymous_access_level
+}
+
+resource "azurerm_storage_container" "github_foundations_tf_state_encrypted_container" {
+ count = local.default_encryption_scope != null ? 1 : 0
+ name = var.tf_state_container
+ storage_account_name = azurerm_storage_account.github_foundations_sa.name
+ container_access_type = var.tf_state_container_anonymous_access_level
+ default_encryption_scope = local.default_encryption_scope
+ encryption_scope_override_enabled = var.tf_state_container_encryption_scope_override_enabled
+}
\ No newline at end of file
diff --git a/modules/github-azure-oidc/variables.tf b/modules/github-azure-oidc/variables.tf
new file mode 100644
index 0000000..73434c5
--- /dev/null
+++ b/modules/github-azure-oidc/variables.tf
@@ -0,0 +1,94 @@
+# Resource Group Variables
+variable "rg_create" {
+ description = "Create the resource group. When set to false it uses the `rg_name` input to reference an existing resource group. Defaults to true."
+ type = bool
+ default = true
+}
+
+variable "rg_name" {
+ type = string
+ description = "The name of the resource group to create the github foundation azure resources in."
+}
+
+variable "rg_location" {
+ type = string
+ description = "The location of the resource group to create the github foundation azure resources in."
+}
+
+#Storage Variables
+variable "sa_name" {
+ type = string
+ description = "The name of the storage account for github foundations."
+}
+
+variable "sa_tier" {
+ type = string
+ description = "The tier of the storage account for github foundations. Valid options are Standard and Premium. Defaults to Standard."
+ default = "Standard"
+}
+
+variable "sa_replication_type" {
+ type = string
+ description = "The replication type of the storage account for github foundations. Valid options are LRS, GRS, RAGRS, ZRS, GZRS, and RA_GZRS. Defaults to GRS."
+ default = "GRS"
+}
+
+variable "tf_state_container" {
+ type = string
+ description = "The name of the container to store the terraform state file(s) in."
+ default = "tfstate"
+}
+
+variable "tf_state_container_anonymous_access_level" {
+ type = string
+ description = "The anonymous access level of the container to store the terraform state file(s) in."
+ default = "private"
+}
+
+variable "tf_state_container_encryption_scope_override_enabled" {
+ type = bool
+ description = "Whether or not the encryption scope override is enabled for the container to store the terraform state file(s) in. Defaults to false"
+ default = false
+}
+
+variable "tf_state_container_default_encryption_scope" {
+ type = object({
+ name = string
+ source = string
+ key_vault_key_id = optional(string)
+ })
+ description = "The default encryption scope of the container to store the terraform state file(s) in."
+ default = {
+ name = ""
+ source = ""
+ storage_account_id = ""
+ }
+ validation {
+ condition = var.tf_state_container_default_encryption_scope.name == "" || var.tf_state_container_default_encryption_scope.source != "Microsoft.KeyVault" || (var.tf_state_container_default_encryption_scope.source == "Microsoft.KeyVault" && var.tf_state_container_default_encryption_scope.key_vault_key_id == null)
+ error_message = "Key vault key id must be set when source is \"Microsoft.KeyVault\"."
+ }
+}
+
+#Key Vault Variables
+variable "kv_name" {
+ type = string
+ description = "The name of the key vault to use for github foundation secrets. If storing secrets to authenticate against github in a different way then this does not need to be set. (Optional)"
+ default = ""
+}
+
+variable "kv_resource_group" {
+ type = string
+ description = "The name of the resource group that the key vault is in. If empty it will default to the github foundations resource group."
+}
+
+#Federated Identity Credentials Varialbes
+
+variable "github_foundations_organization_name" {
+ type = string
+ description = "The name of the organization that the github foundation repos will be under."
+}
+
+variable "drift_detection_branch_name" {
+ type = string
+ description = "The name of the branch to use for drift detection."
+}
diff --git a/modules/github-azure-oidc/versions.tf b/modules/github-azure-oidc/versions.tf
new file mode 100644
index 0000000..d34e8d7
--- /dev/null
+++ b/modules/github-azure-oidc/versions.tf
@@ -0,0 +1,17 @@
+terraform {
+ required_version = ">= 1.6"
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = ">=3.0.0" #tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 3.77" # tftest
+ }
+ random = {
+ source = "hashicorp/random"
+ version = ">= 3.6" # tftest
+ }
+ }
+}
diff --git a/modules/github-foundations/README.md b/modules/github-foundations/README.md
index c5c70c7..b96a1b6 100644
--- a/modules/github-foundations/README.md
+++ b/modules/github-foundations/README.md
@@ -24,11 +24,18 @@
| Name | Type |
|------|------|
| [github_actions_organization_secret.custom_oidc_organization_secret](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource |
+| [github_actions_organization_secret.tenant_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource |
| [github_actions_organization_secret.workload_identity_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource |
+| [github_actions_organization_variable.container_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
| [github_actions_organization_variable.custom_oidc_organization_variable](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
+| [github_actions_organization_variable.resource_group_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
+| [github_actions_organization_variable.storage_account_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
+| [github_actions_organization_variable.subscription_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
| [github_actions_organization_variable.tf_state_bucket_location](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
| [github_actions_organization_variable.tf_state_bucket_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
| [github_actions_organization_variable.tf_state_bucket_project_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource |
+| [github_actions_secret.bootstrap_managed_identity_client_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
+| [github_actions_secret.organization_managed_identity_client_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
| [github_actions_secret.organization_workload_identity_sa](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
| [github_actions_secret.repository_secret](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_secret) | resource |
| [github_actions_variable.gcp_secret_manager_project_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource |
@@ -49,7 +56,7 @@
| [account\_type](#input\_account\_type) | The type of GitHub account being used. Should be one of either `Personal`, `Organization`, or `Enterprise`. | `string` | n/a | yes |
| [bootstrap\_repository\_name](#input\_bootstrap\_repository\_name) | The name of the bootstrap repository. | `string` | `"bootstrap"` | no |
| [foundation\_devs\_team\_name](#input\_foundation\_devs\_team\_name) | The name of the foundation developers team. | `string` | `"foundation-devs"` | no |
-| [oidc\_configuration](#input\_oidc\_configuration) | n/a | object({
gcp = optional(object({
workload_identity_provider_name_secret_name = optional(string)
workload_identity_provider_name = string
organization_workload_identity_sa_secret_name = optional(string)
organization_workload_identity_sa = string
gcp_secret_manager_project_id_variable_name = optional(string)
gcp_secret_manager_project_id = string
gcp_tf_state_bucket_project_id_variable_name = optional(string)
gcp_tf_state_bucket_project_id = string
bucket_name_variable_name = optional(string)
bucket_name = string
bucket_location_variable_name = optional(string)
bucket_location = string
}))
custom = optional(object({
organization_secrets = map(string)
organization_variables = map(string)
repository_secrets = map(map(string))
repository_variables = map(map(string))
}))
}) | n/a | yes |
+| [oidc\_configuration](#input\_oidc\_configuration) | n/a | object({
gcp = optional(object({
workload_identity_provider_name_secret_name = optional(string)
workload_identity_provider_name = string
organization_workload_identity_sa_secret_name = optional(string)
organization_workload_identity_sa = string
gcp_secret_manager_project_id_variable_name = optional(string)
gcp_secret_manager_project_id = string
gcp_tf_state_bucket_project_id_variable_name = optional(string)
gcp_tf_state_bucket_project_id = string
bucket_name_variable_name = optional(string)
bucket_name = string
bucket_location_variable_name = optional(string)
bucket_location = string
}))
azure = optional(object({
bootstrap_client_id_variable_name = optional(string)
bootstrap_client_id = string
organization_client_id_variable_name = optional(string)
organization_client_id = string
tenant_id_variable_name = optional(string)
tenant_id = string
subscription_id_variable_name = optional(string)
subscription_id = string
resource_group_name_variable_name = optional(string)
resource_group_name = string
storage_account_name_variable_name = optional(string)
storage_account_name = string
container_name_variable_name = optional(string)
container_name = string
}))
custom = optional(object({
organization_secrets = map(string)
organization_variables = map(string)
repository_secrets = map(map(string))
repository_variables = map(map(string))
}))
}) | n/a | yes |
| [organizations\_repository\_name](#input\_organizations\_repository\_name) | The name of the organizations repository. | `string` | `"organizations"` | no |
| [readme\_path](#input\_readme\_path) | Local Path to the README file in your current codebase. Pushed to the github foundation repository. | `string` | `""` | no |
diff --git a/modules/github-foundations/azure-oidc-variables.tf b/modules/github-foundations/azure-oidc-variables.tf
new file mode 100644
index 0000000..7592b3a
--- /dev/null
+++ b/modules/github-foundations/azure-oidc-variables.tf
@@ -0,0 +1,75 @@
+resource "github_actions_secret" "organization_managed_identity_client_id" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ repository = github_repository.organizations_repo.name
+ secret_name = coalesce(var.oidc_configuration.azure.organization_client_id_variable_name, "AZURE_CLIENT_ID")
+ plaintext_value = var.oidc_configuration.azure.organization_client_id
+}
+
+resource "github_actions_secret" "bootstrap_managed_identity_client_id" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ repository = github_repository.bootstrap_repo.name
+ secret_name = coalesce(var.oidc_configuration.azure.bootstrap_client_id_variable_name, "AZURE_CLIENT_ID")
+ plaintext_value = var.oidc_configuration.azure.bootstrap_client_id
+}
+
+resource "github_actions_organization_secret" "tenant_id" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ secret_name = coalesce(var.oidc_configuration.azure.tenant_id_variable_name, "AZURE_TENANT_ID")
+ plaintext_value = var.oidc_configuration.azure.tenant_id
+ visibility = "selected"
+ selected_repository_ids = [
+ github_repository.bootstrap_repo.repo_id,
+ github_repository.organizations_repo.repo_id
+ ]
+}
+
+resource "github_actions_organization_variable" "subscription_id" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ variable_name = coalesce(var.oidc_configuration.azure.subscription_id_variable_name, "AZURE_SUBSCRIPTION_ID")
+ value = var.oidc_configuration.azure.subscription_id
+ visibility = "selected"
+ selected_repository_ids = [
+ github_repository.bootstrap_repo.repo_id,
+ github_repository.organizations_repo.repo_id
+ ]
+}
+
+resource "github_actions_organization_variable" "resource_group_name" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ variable_name = coalesce(var.oidc_configuration.azure.resource_group_name_variable_name, "AZURE_RESOURCE_GROUP_NAME")
+ value = var.oidc_configuration.azure.resource_group_name
+ visibility = "selected"
+ selected_repository_ids = [
+ github_repository.bootstrap_repo.repo_id,
+ github_repository.organizations_repo.repo_id
+ ]
+}
+
+resource "github_actions_organization_variable" "storage_account_name" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ variable_name = coalesce(var.oidc_configuration.azure.storage_account_name_variable_name, "AZURE_STORAGE_ACCOUNT_NAME")
+ value = var.oidc_configuration.azure.storage_account_name
+ visibility = "selected"
+ selected_repository_ids = [
+ github_repository.bootstrap_repo.repo_id,
+ github_repository.organizations_repo.repo_id
+ ]
+}
+
+resource "github_actions_organization_variable" "container_name" {
+ count = var.oidc_configuration.azure != null ? 1 : 0
+
+ variable_name = coalesce(var.oidc_configuration.azure.container_name_variable_name, "AZURE_CONTAINER_NAME")
+ value = var.oidc_configuration.azure.container_name
+ visibility = "selected"
+ selected_repository_ids = [
+ github_repository.bootstrap_repo.repo_id,
+ github_repository.organizations_repo.repo_id
+ ]
+}
diff --git a/modules/github-foundations/variables.tf b/modules/github-foundations/variables.tf
index fe9583e..bffd7f8 100644
--- a/modules/github-foundations/variables.tf
+++ b/modules/github-foundations/variables.tf
@@ -43,6 +43,28 @@ variable "oidc_configuration" {
bucket_location_variable_name = optional(string)
bucket_location = string
}))
+ azure = optional(object({
+ bootstrap_client_id_variable_name = optional(string)
+ bootstrap_client_id = string
+
+ organization_client_id_variable_name = optional(string)
+ organization_client_id = string
+
+ tenant_id_variable_name = optional(string)
+ tenant_id = string
+
+ subscription_id_variable_name = optional(string)
+ subscription_id = string
+
+ resource_group_name_variable_name = optional(string)
+ resource_group_name = string
+
+ storage_account_name_variable_name = optional(string)
+ storage_account_name = string
+
+ container_name_variable_name = optional(string)
+ container_name = string
+ }))
custom = optional(object({
organization_secrets = map(string)
organization_variables = map(string)
@@ -51,7 +73,7 @@ variable "oidc_configuration" {
}))
})
validation {
- condition = var.oidc_configuration.gcp != null || var.oidc_configuration.custom != null
+ condition = var.oidc_configuration.gcp != null || var.oidc_configuration.custom != null || var.oidc_configuration.azure != null
error_message = "At least one oidc_configuration must be set."
}
}