From 4e49e1f38c9345c3e7e227e0d418ae277c41b55c Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Wed, 20 Mar 2024 15:59:21 -0400 Subject: [PATCH 1/7] made gcs oidc configuration optional. Allow for users to define their own github secret and action variables to use for oidc auth --- .../github-foundations/action-variables.tf | 51 -------------- .../custom-oidc-variables.tf | 65 +++++++++++++++++ .../github-foundations/gcp-oidc-variables.tf | 63 +++++++++++++++++ modules/github-foundations/variables.tf | 70 +++++++++---------- 4 files changed, 162 insertions(+), 87 deletions(-) delete mode 100644 modules/github-foundations/action-variables.tf create mode 100644 modules/github-foundations/custom-oidc-variables.tf create mode 100644 modules/github-foundations/gcp-oidc-variables.tf diff --git a/modules/github-foundations/action-variables.tf b/modules/github-foundations/action-variables.tf deleted file mode 100644 index ad39345..0000000 --- a/modules/github-foundations/action-variables.tf +++ /dev/null @@ -1,51 +0,0 @@ -resource "github_actions_secret" "organization_workload_identity_sa" { - repository = github_repository.organizations_repo.name - secret_name = "GCP_SERVICE_ACCOUNT" - plaintext_value = var.organization_workload_identity_sa -} - -resource "github_actions_variable" "gcp_secret_manager_project_id" { - repository = github_repository.organizations_repo.name - variable_name = "GCP_SECRET_MANAGER_PROJECT" - value = var.gcp_project_id -} - -resource "github_actions_organization_secret" "workload_identity_provider" { - secret_name = "WORKLOAD_IDENTITY_PROVIDER" - plaintext_value = var.workload_identity_provider_name - visibility = "selected" - selected_repository_ids = [ - github_repository.bootstrap_repo.repo_id, - github_repository.organizations_repo.repo_id - ] -} - -resource "github_actions_organization_variable" "tf_state_bucket_project_id" { - variable_name = "TF_STATE_BUCKET_PROJECT_ID" - value = var.gcp_tf_state_bucket_project_id - visibility = "selected" - selected_repository_ids = [ - github_repository.bootstrap_repo.repo_id, - github_repository.organizations_repo.repo_id - ] -} - -resource "github_actions_organization_variable" "tf_state_bucket_name" { - variable_name = "TF_STATE_BUCKET_NAME" - value = var.bucket_name - visibility = "selected" - selected_repository_ids = [ - github_repository.bootstrap_repo.repo_id, - github_repository.organizations_repo.repo_id - ] -} - -resource "github_actions_organization_variable" "tf_state_bucket_location" { - variable_name = "TF_STATE_BUCKET_LOCATION" - value = var.bucket_location - visibility = "selected" - selected_repository_ids = [ - github_repository.bootstrap_repo.repo_id, - github_repository.organizations_repo.repo_id - ] -} \ No newline at end of file diff --git a/modules/github-foundations/custom-oidc-variables.tf b/modules/github-foundations/custom-oidc-variables.tf new file mode 100644 index 0000000..80dd60d --- /dev/null +++ b/modules/github-foundations/custom-oidc-variables.tf @@ -0,0 +1,65 @@ +locals { + expanded_list_of_repo_secrets = merge( + [ + for repo, secrets in var.oidc_configuration.custom.repository_secrets : { + for name, encrypted_value in secrets : "${repo}_${name}" => { + name = name + encrypted_value = encrypted_value + repository = repo + } + } + ] + ) + + expanded_list_of_repo_variables = merge( + [ + for repo, variables in var.oidc_configuration.custom.repository_variables : { + for name, value in variables : "${repo}_${name}" => { + name = name + value = value + repository = repo + } + } + ] + ) +} + +resource "github_actions_organization_secret" "custom_oidc_organization_secret" { + for_each = var.oidc_configuration.custom.organization_secrets + + secret_name = each.key + encrypted_value = each.value + visibility = "selected" + selected_repository_ids = [ + github_repository.bootstrap_repo.repo_id, + github_repository.organizations_repo.repo_id + ] +} + +resource "github_actions_organization_variable" "custom_oidc_organization_variable" { + for_each = var.oidc_configuration.custom.organization_variables + + variable_name = each.key + value = each.value + visibility = "selected" + selected_repository_ids = [ + github_repository.bootstrap_repo.repo_id, + github_repository.organizations_repo.repo_id + ] +} + +resource "github_actions_secret" "repository_secret" { + for_each = local.expanded_list_of_repo_secrets + + repository = each.value.repository + secret_name = each.value.name + encrypted_value = each.value.encrypted_value +} + +resource "github_actions_variable" "repository_variable" { + for_each = local.expanded_list_of_repo_variables + + repository = each.value.repository + variable_name = each.value.name + value = each.value.value +} diff --git a/modules/github-foundations/gcp-oidc-variables.tf b/modules/github-foundations/gcp-oidc-variables.tf new file mode 100644 index 0000000..9b5516f --- /dev/null +++ b/modules/github-foundations/gcp-oidc-variables.tf @@ -0,0 +1,63 @@ +resource "github_actions_secret" "organization_workload_identity_sa" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + repository = github_repository.organizations_repo.name + secret_name = coalesce(var.oidc_configuration.gcp.organization_workload_identity_sa_secret_name, "GCP_SERVICE_ACCOUNT") + plaintext_value = var.oidc_configuration.gcp.organization_workload_identity_sa +} + +resource "github_actions_variable" "gcp_secret_manager_project_id" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + repository = github_repository.organizations_repo.name + variable_name = coalesce(var.oidc_configuration.gcp.gcp_secret_manager_project_id_variable_name, "GCP_SECRET_MANAGER_PROJECT") + value = var.oidc_configuration.gcp.gcp_secret_manager_project_id +} + +resource "github_actions_organization_secret" "workload_identity_provider" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + secret_name = coalesce(var.oidc_configuration.gcp.workload_identity_provider_name_secret_name, "WORKLOAD_IDENTITY_PROVIDER") + plaintext_value = var.oidc_configuration.gcp.workload_identity_provider_name + visibility = "selected" + selected_repository_ids = [ + github_repository.bootstrap_repo.repo_id, + github_repository.organizations_repo.repo_id + ] +} + +resource "github_actions_organization_variable" "tf_state_bucket_project_id" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + variable_name = coalesce(var.oidc_configuration.gcp.gcp_tf_state_bucket_project_id_variable_name, "TF_STATE_BUCKET_PROJECT_ID") + value = var.oidc_configuration.gcp.gcp_tf_state_bucket_project_id + visibility = "selected" + selected_repository_ids = [ + github_repository.bootstrap_repo.repo_id, + github_repository.organizations_repo.repo_id + ] +} + +resource "github_actions_organization_variable" "tf_state_bucket_name" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + variable_name = coalesce(var.oidc_configuration.gcp.bucket_name_variable_name, "TF_STATE_BUCKET_NAME") + value = var.oidc_configuration.gcp.bucket_name + visibility = "selected" + selected_repository_ids = [ + github_repository.bootstrap_repo.repo_id, + github_repository.organizations_repo.repo_id + ] +} + +resource "github_actions_organization_variable" "tf_state_bucket_location" { + count = var.oidc_configuration.gcp != null ? 1 : 0 + + variable_name = coalesce(var.oidc_configuration.gcp.bucket_location_variable_name, "TF_STATE_BUCKET_LOCATION") + value = var.oidc_configuration.gcp.bucket_location + 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 9a82faf..d851746 100644 --- a/modules/github-foundations/variables.tf +++ b/modules/github-foundations/variables.tf @@ -1,39 +1,3 @@ -variable "workload_identity_provider_name" { - type = string - description = "The name of the workload identity provider to use for the oidc of the github foundation repositories." -} - -variable "bootstrap_workload_identity_sa" { - type = string - description = "The service account to use for the bootstrap repository oidc." -} - -variable "organization_workload_identity_sa" { - type = string - description = "The service account to use for the organization repository oidc." -} - -variable "gcp_project_id" { - type = string - description = "The id of the gcp project where secret manager was setup." - -} - -variable "gcp_tf_state_bucket_project_id" { - type = string - description = "The id of the gcp project where the tf state bucket was setup." -} - -variable "bucket_name" { - type = string - description = "The name of the tf state bucket." -} - -variable "bucket_location" { - type = string - description = "The location of the tf state bucket." -} - variable "readme_path" { type = string description = "Local Path to the README file in your current codebase. Pushed to the github foundation repository." @@ -56,4 +20,38 @@ variable "foundation_devs_team_name" { type = string description = "The name of the foundation developers team." default = "foundation-devs" +} + +variable "oidc_configuration" { + type = 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)) + })) + }) + validation { + condition = length(keys(var.oidc_configuration)) > 0 + error_message = "At least one oidc_configuration must be set." + } } \ No newline at end of file From af4b057cc9c7ab2bf1648f12e6a87f64d500bb21 Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Thu, 21 Mar 2024 09:34:20 -0400 Subject: [PATCH 2/7] added try block to catch null errors --- modules/github-foundations/custom-oidc-variables.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/github-foundations/custom-oidc-variables.tf b/modules/github-foundations/custom-oidc-variables.tf index 80dd60d..71bd4b6 100644 --- a/modules/github-foundations/custom-oidc-variables.tf +++ b/modules/github-foundations/custom-oidc-variables.tf @@ -1,7 +1,7 @@ locals { expanded_list_of_repo_secrets = merge( [ - for repo, secrets in var.oidc_configuration.custom.repository_secrets : { + for repo, secrets in try(var.oidc_configuration.custom.repository_secrets, {}) : { for name, encrypted_value in secrets : "${repo}_${name}" => { name = name encrypted_value = encrypted_value @@ -13,7 +13,7 @@ locals { expanded_list_of_repo_variables = merge( [ - for repo, variables in var.oidc_configuration.custom.repository_variables : { + for repo, variables in try(var.oidc_configuration.custom.repository_variables, {}) : { for name, value in variables : "${repo}_${name}" => { name = name value = value @@ -25,7 +25,7 @@ locals { } resource "github_actions_organization_secret" "custom_oidc_organization_secret" { - for_each = var.oidc_configuration.custom.organization_secrets + for_each = try(var.oidc_configuration.custom.organization_secrets, {}) secret_name = each.key encrypted_value = each.value @@ -37,7 +37,7 @@ resource "github_actions_organization_secret" "custom_oidc_organization_secret" } resource "github_actions_organization_variable" "custom_oidc_organization_variable" { - for_each = var.oidc_configuration.custom.organization_variables + for_each = try(var.oidc_configuration.custom.organization_variables, {}) variable_name = each.key value = each.value From 100282a2d814023a161a1fc7ba6e24fcb50f442e Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Thu, 21 Mar 2024 09:36:40 -0400 Subject: [PATCH 3/7] moved try for local variable loop up --- modules/github-foundations/custom-oidc-variables.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/github-foundations/custom-oidc-variables.tf b/modules/github-foundations/custom-oidc-variables.tf index 71bd4b6..555ffb4 100644 --- a/modules/github-foundations/custom-oidc-variables.tf +++ b/modules/github-foundations/custom-oidc-variables.tf @@ -1,26 +1,26 @@ locals { - expanded_list_of_repo_secrets = merge( + expanded_list_of_repo_secrets = try(merge( [ - for repo, secrets in try(var.oidc_configuration.custom.repository_secrets, {}) : { + for repo, secrets in var.oidc_configuration.custom.repository_secrets : { for name, encrypted_value in secrets : "${repo}_${name}" => { name = name encrypted_value = encrypted_value repository = repo } } - ] + ], []) ) - expanded_list_of_repo_variables = merge( + expanded_list_of_repo_variables = try(merge( [ - for repo, variables in try(var.oidc_configuration.custom.repository_variables, {}) : { + for repo, variables in var.oidc_configuration.custom.repository_variables : { for name, value in variables : "${repo}_${name}" => { name = name value = value repository = repo } } - ] + ], []) ) } From 0e74b0bd63764aaa4bd526e59da5915ed10ae788 Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Thu, 21 Mar 2024 09:37:59 -0400 Subject: [PATCH 4/7] typo --- modules/github-foundations/custom-oidc-variables.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/github-foundations/custom-oidc-variables.tf b/modules/github-foundations/custom-oidc-variables.tf index 555ffb4..669c595 100644 --- a/modules/github-foundations/custom-oidc-variables.tf +++ b/modules/github-foundations/custom-oidc-variables.tf @@ -8,8 +8,8 @@ locals { repository = repo } } - ], []) - ) + ] + ), []) expanded_list_of_repo_variables = try(merge( [ @@ -20,8 +20,8 @@ locals { repository = repo } } - ], []) - ) + ] + ), []) } resource "github_actions_organization_secret" "custom_oidc_organization_secret" { From b7b17768b0515272ec45d88425415a343ad7d193 Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Thu, 21 Mar 2024 09:39:06 -0400 Subject: [PATCH 5/7] type conversion --- modules/github-foundations/custom-oidc-variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/github-foundations/custom-oidc-variables.tf b/modules/github-foundations/custom-oidc-variables.tf index 669c595..26f219d 100644 --- a/modules/github-foundations/custom-oidc-variables.tf +++ b/modules/github-foundations/custom-oidc-variables.tf @@ -49,7 +49,7 @@ resource "github_actions_organization_variable" "custom_oidc_organization_variab } resource "github_actions_secret" "repository_secret" { - for_each = local.expanded_list_of_repo_secrets + for_each = toset(local.expanded_list_of_repo_secrets) repository = each.value.repository secret_name = each.value.name @@ -57,7 +57,7 @@ resource "github_actions_secret" "repository_secret" { } resource "github_actions_variable" "repository_variable" { - for_each = local.expanded_list_of_repo_variables + for_each = toset(local.expanded_list_of_repo_variables) repository = each.value.repository variable_name = each.value.name From 2930b81d19adfc388a497608602f1f9081d281b9 Mon Sep 17 00:00:00 2001 From: Tyler Mizuyabu Date: Thu, 21 Mar 2024 09:48:18 -0400 Subject: [PATCH 6/7] trying a simpler validation condition --- modules/github-foundations/variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/github-foundations/variables.tf b/modules/github-foundations/variables.tf index d851746..b7808f5 100644 --- a/modules/github-foundations/variables.tf +++ b/modules/github-foundations/variables.tf @@ -51,7 +51,7 @@ variable "oidc_configuration" { })) }) validation { - condition = length(keys(var.oidc_configuration)) > 0 + condition = var.oidc_configuration.gcp != null || var.oidc_configuration.custom != null error_message = "At least one oidc_configuration must be set." } } \ No newline at end of file From 5c9231cfc1f9745ace6f9502ed70538f9e8491f2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 21 Mar 2024 13:48:49 +0000 Subject: [PATCH 7/7] terraform-docs: automated action --- modules/github-foundations/README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/github-foundations/README.md b/modules/github-foundations/README.md index 890204b..306535f 100644 --- a/modules/github-foundations/README.md +++ b/modules/github-foundations/README.md @@ -22,12 +22,16 @@ | 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.workload_identity_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | 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.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.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 | +| [github_actions_variable.repository_variable](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_variable) | resource | | [github_issue_labels.drift_labels](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/issue_labels) | resource | | [github_repository.bootstrap_repo](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | | [github_repository.organizations_repo](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | @@ -42,16 +46,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [bootstrap\_repository\_name](#input\_bootstrap\_repository\_name) | The name of the bootstrap repository. | `string` | `"bootstrap"` | no | -| [bootstrap\_workload\_identity\_sa](#input\_bootstrap\_workload\_identity\_sa) | The service account to use for the bootstrap repository oidc. | `string` | n/a | yes | -| [bucket\_location](#input\_bucket\_location) | The location of the tf state bucket. | `string` | n/a | yes | -| [bucket\_name](#input\_bucket\_name) | The name of the tf state bucket. | `string` | n/a | yes | | [foundation\_devs\_team\_name](#input\_foundation\_devs\_team\_name) | The name of the foundation developers team. | `string` | `"foundation-devs"` | no | -| [gcp\_project\_id](#input\_gcp\_project\_id) | The id of the gcp project where secret manager was setup. | `string` | n/a | yes | -| [gcp\_tf\_state\_bucket\_project\_id](#input\_gcp\_tf\_state\_bucket\_project\_id) | The id of the gcp project where the tf state bucket was setup. | `string` | n/a | yes | -| [organization\_workload\_identity\_sa](#input\_organization\_workload\_identity\_sa) | The service account to use for the organization repository oidc. | `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
}))
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 | -| [workload\_identity\_provider\_name](#input\_workload\_identity\_provider\_name) | The name of the workload identity provider to use for the oidc of the github foundation repositories. | `string` | n/a | yes | ## Outputs