From 47daeaafe132730cab7b164c239e988854329c77 Mon Sep 17 00:00:00 2001 From: Luca Prete Date: Thu, 3 Aug 2023 18:09:45 +0200 Subject: [PATCH] Update FAST CI/CD workflows so it can work with ID_TOKEN and Gitlab 15+ --- fast/stages/0-bootstrap/README.md | 66 ++++++++++--------- fast/stages/0-bootstrap/cicd.tf | 8 ++- fast/stages/0-bootstrap/identity-providers.tf | 21 +++--- fast/stages/0-bootstrap/outputs.tf | 3 + .../templates/workflow-gitlab.yaml | 35 ++++++---- fast/stages/0-bootstrap/variables.tf | 17 +++-- fast/stages/1-resman/README.md | 56 ++++++++-------- fast/stages/1-resman/outputs.tf | 5 +- .../1-resman/templates/workflow-gitlab.yaml | 35 ++++++---- fast/stages/1-resman/variables.tf | 3 +- 10 files changed, 144 insertions(+), 105 deletions(-) diff --git a/fast/stages/0-bootstrap/README.md b/fast/stages/0-bootstrap/README.md index e25f2c6b..105b044f 100644 --- a/fast/stages/0-bootstrap/README.md +++ b/fast/stages/0-bootstrap/README.md @@ -395,26 +395,34 @@ The variable maps each provider's `issuer` attribute with the definitions in the Provider key names are used by the `cicd_repositories` variable to configure authentication for CI/CD repositories, and generally from your Terraform code whenever you need to configure IAM access or impersonation for federated identities. -This is a sample configuration of a GitHub and a Gitlab provider, `attribute_condition` attribute can use any of the mapped attribute for the provider (refer to the `identity-providers.tf` file for the full list) or set to `null` if needed: +This is a sample configuration of a GitHub and a Gitlab provider. Every parameter is optional. + +If users don't specify the `issuer_uri` we assume the default `issuer_uri` for public platforms should be used. + +If users don't specify the `audience`, we set the url of the provider, as recommended in the [WIF FAQ section](https://cloud.google.com/iam/docs/best-practices-for-using-workload-identity-federation#provider-audience). ```tfvars federated_identity_providers = { - github-sample = { + # Use the public GitHub and specify an attribute condition + github-public-sample = { attribute_condition = "attribute.repository_owner==\"my-github-org\"" issuer = "github" - custom_settings = null } - gitlab-sample = { - attribute_condition = "attribute.namespace_path==\"my-gitlab-org\"" + # Use a private instance of Gitlab and specify a custom issuer_uri + gitlab-private-sample = { issuer = "gitlab" - custom_settings = null + custom_settings = { + issuer_uri = "https://gitlab.fast.example.com" + } } - gitlab-ce-sample = { + # Use a private instance of Gitlab. + # Specify a custom audience and a custom issuer_uri + gitlab-private-aud-sample = { attribute_condition = "attribute.namespace_path==\"my-gitlab-org\"" issuer = "gitlab" custom_settings = { - issuer_uri = "https://gitlab.fast.example.com" allowed_audiences = ["https://gitlab.fast.example.com"] + issuer_uri = "https://gitlab.fast.example.com" } } } @@ -480,7 +488,6 @@ The remaining configuration is manual, as it regards the repositories themselves - ## Files | name | description | modules | resources | @@ -502,35 +509,34 @@ The remaining configuration is manual, as it regards the repositories themselves | name | description | type | required | default | producer | |---|---|:---:|:---:|:---:|:---:| | [billing_account](variables.tf#L17) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | object({…}) | ✓ | | | -| [organization](variables.tf#L201) | Organization details. | object({…}) | ✓ | | | -| [prefix](variables.tf#L216) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | +| [organization](variables.tf#L206) | Organization details. | object({…}) | ✓ | | | +| [prefix](variables.tf#L221) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | | | [bootstrap_user](variables.tf#L27) | Email of the nominal user running this stage for the first time. | string | | null | | | [cicd_repositories](variables.tf#L33) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | | [custom_role_names](variables.tf#L79) | Names of custom roles defined at the org level. | object({…}) | | {…} | | | [custom_roles](variables.tf#L93) | Map of role names => list of permissions to additionally create at the organization level. | map(list(string)) | | {} | | | [fast_features](variables.tf#L100) | Selective control for top-level FAST features. | object({…}) | | {} | | -| [federated_identity_providers](variables.tf#L113) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | -| [groups](variables.tf#L127) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | map(string) | | {…} | | -| [iam](variables.tf#L145) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | -| [iam_additive](variables.tf#L151) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | map(list(string)) | | {} | | -| [locations](variables.tf#L157) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {…} | | -| [log_sinks](variables.tf#L176) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | -| [outputs_location](variables.tf#L210) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | -| [project_parent_ids](variables.tf#L225) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | object({…}) | | {…} | | +| [federated_identity_providers](variables.tf#L113) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | map(object({…})) | | {} | | +| [groups](variables.tf#L132) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | map(string) | | {…} | | +| [iam](variables.tf#L150) | Organization-level custom IAM settings in role => [principal] format. | map(list(string)) | | {} | | +| [iam_additive](variables.tf#L156) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | map(list(string)) | | {} | | +| [locations](variables.tf#L162) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {…} | | +| [log_sinks](variables.tf#L181) | Org-level log sinks, in name => {type, filter} format. | map(object({…})) | | {…} | | +| [outputs_location](variables.tf#L215) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | +| [project_parent_ids](variables.tf#L230) | Optional parents for projects created here in folders/nnnnnnn format. Null values will use the organization as parent. | object({…}) | | {…} | | ## Outputs | name | description | sensitive | consumers | |---|---|:---:|---| -| [automation](outputs.tf#L97) | Automation resources. | | | -| [billing_dataset](outputs.tf#L102) | BigQuery dataset prepared for billing export. | | | -| [cicd_repositories](outputs.tf#L107) | CI/CD repository configurations. | | | -| [custom_roles](outputs.tf#L119) | Organization-level custom roles. | | | -| [federated_identity](outputs.tf#L124) | Workload Identity Federation pool and providers. | | | -| [outputs_bucket](outputs.tf#L134) | GCS bucket where generated output files are stored. | | | -| [project_ids](outputs.tf#L139) | Projects created by this stage. | | | -| [providers](outputs.tf#L149) | Terraform provider files for this stage and dependent stages. | ✓ | stage-01 | -| [service_accounts](outputs.tf#L156) | Automation service accounts created by this stage. | | | -| [tfvars](outputs.tf#L165) | Terraform variable files for the following stages. | ✓ | | - +| [automation](outputs.tf#L100) | Automation resources. | | | +| [billing_dataset](outputs.tf#L105) | BigQuery dataset prepared for billing export. | | | +| [cicd_repositories](outputs.tf#L110) | CI/CD repository configurations. | | | +| [custom_roles](outputs.tf#L122) | Organization-level custom roles. | | | +| [federated_identity](outputs.tf#L127) | Workload Identity Federation pool and providers. | | | +| [outputs_bucket](outputs.tf#L137) | GCS bucket where generated output files are stored. | | | +| [project_ids](outputs.tf#L142) | Projects created by this stage. | | | +| [providers](outputs.tf#L152) | Terraform provider files for this stage and dependent stages. | ✓ | stage-01 | +| [service_accounts](outputs.tf#L159) | Automation service accounts created by this stage. | | | +| [tfvars](outputs.tf#L168) | Terraform variable files for the following stages. | ✓ | | diff --git a/fast/stages/0-bootstrap/cicd.tf b/fast/stages/0-bootstrap/cicd.tf index 2b2a3df9..f0b321d9 100644 --- a/fast/stages/0-bootstrap/cicd.tf +++ b/fast/stages/0-bootstrap/cicd.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,12 @@ locals { cicd_providers = { for k, v in google_iam_workload_identity_pool_provider.default : k => { + audience = try( + v.oidc[0].allowed_audiences[0], + "https://iam.googleapis.com/${v.name}" + ) issuer = local.identity_providers[k].issuer - issuer_uri = local.identity_providers[k].issuer_uri + issuer_uri = try(v.oidc[0].issuer_uri, null) name = v.name principal_tpl = local.identity_providers[k].principal_tpl principalset_tpl = local.identity_providers[k].principalset_tpl diff --git a/fast/stages/0-bootstrap/identity-providers.tf b/fast/stages/0-bootstrap/identity-providers.tf index d315bdb3..1c1c8b20 100644 --- a/fast/stages/0-bootstrap/identity-providers.tf +++ b/fast/stages/0-bootstrap/identity-providers.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ locals { principal_tpl = "principal://iam.googleapis.com/%s/subject/repo:%s:ref:refs/heads/%s" principalset_tpl = "principalSet://iam.googleapis.com/%s/attribute.repository/%s" } - # https://docs.gitlab.com/ee/ci/cloud_services/index.html#how-it-works + # https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html#token-payload gitlab = { attribute_mapping = { "google.subject" = "assertion.sub" @@ -56,10 +56,9 @@ locals { "attribute.ref_protected" = "assertion.ref_protected" "attribute.ref_type" = "assertion.ref_type" } - allowed_audiences = ["https://gitlab.com"] - issuer_uri = "https://gitlab.com" - principal_tpl = "principalSet://iam.googleapis.com/%s/attribute.sub/project_path:%s:ref_type:branch:ref:%s" - principalset_tpl = "principalSet://iam.googleapis.com/%s/attribute.repository/%s" + issuer_uri = "https://gitlab.com" + principal_tpl = "principalSet://iam.googleapis.com/%s/attribute.sub/project_path:%s:ref_type:branch:ref:%s" + principalset_tpl = "principalSet://iam.googleapis.com/%s/attribute.repository/%s" } } } @@ -82,13 +81,11 @@ resource "google_iam_workload_identity_pool_provider" "default" { attribute_condition = each.value.attribute_condition attribute_mapping = each.value.attribute_mapping oidc { - allowed_audiences = ( - try(each.value.custom_settings.allowed_audiences, null) != null - ? each.value.custom_settings.allowed_audiences - : try(each.value.allowed_audiences, null) - ) + # Setting an empty list configures allowed_audiences to the url of the provider + allowed_audiences = each.value.custom_settings.allowed_audiences + # If users don't provide an issuer_uri, we set the public one for the plaform choosed. issuer_uri = ( - try(each.value.custom_settings.issuer_uri, null) != null + each.value.custom_settings.issuer_uri != null ? each.value.custom_settings.issuer_uri : try(each.value.issuer_uri, null) ) diff --git a/fast/stages/0-bootstrap/outputs.tf b/fast/stages/0-bootstrap/outputs.tf index 8c374eb7..1db70bc4 100644 --- a/fast/stages/0-bootstrap/outputs.tf +++ b/fast/stages/0-bootstrap/outputs.tf @@ -20,6 +20,9 @@ locals { cicd_workflows = { for k, v in local.cicd_repositories : k => templatefile( "${path.module}/templates/workflow-${v.type}.yaml", { + # If users give a list of custom audiences we set by default the first element. + # If no audiences are given, we set https://iam.googleapis.com/{PROVIDER_NAME} + audience = local.cicd_providers[v["identity_provider"]].audience identity_provider = try( local.cicd_providers[v["identity_provider"]].name, "" ) diff --git a/fast/stages/0-bootstrap/templates/workflow-gitlab.yaml b/fast/stages/0-bootstrap/templates/workflow-gitlab.yaml index 8981e70b..33e55d21 100644 --- a/fast/stages/0-bootstrap/templates/workflow-gitlab.yaml +++ b/fast/stages/0-bootstrap/templates/workflow-gitlab.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,6 @@ # limitations under the License. default: - before_script: - - echo "$${CI_JOB_JWT_V2}" > token.txt image: name: hashicorp/terraform entrypoint: @@ -22,6 +20,7 @@ default: - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" variables: + AUDIENCE: ${audience} GOOGLE_CREDENTIALS: cicd-sa-credentials.json FAST_OUTPUTS_BUCKET: ${outputs_bucket} FAST_SERVICE_ACCOUNT: ${service_account} @@ -39,13 +38,15 @@ stages: cache: key: gcp-auth paths: - - cicd-sa-credentials.json - .tf-setup gcp-auth: + stage: gcp-auth + id_tokens: + GITLAB_TOKEN: + aud: "$${AUDIENCE}" image: name: google/cloud-sdk:slim - stage: gcp-auth script: - | gcloud iam workload-identity-pools create-cred-config \ @@ -54,12 +55,14 @@ gcp-auth: --service-account-token-lifetime-seconds=3600 \ --output-file=$${GOOGLE_CREDENTIALS} \ --credential-source-file=token.txt + - rm token.txt + artifacts: + untracked: true + tf-files: - dependencies: - - gcp-auth + stage: tf-files image: name: google/cloud-sdk:slim - stage: tf-files script: # - gcloud components install -q alpha - gcloud config set auth/credential_file_override $${GOOGLE_CREDENTIALS} @@ -70,8 +73,13 @@ tf-files: - | gcloud alpha storage cp -r \ "gs://$${FAST_OUTPUTS_BUCKET}/tfvars" .tf-setup/ + artifacts: + untracked: true + dependencies: + - gcp-auth tf-plan: + stage: tf-plan # uncomment the following lines and set the SSH key secret for private modules repo # before_script: # - | @@ -80,20 +88,22 @@ tf-plan: # mkdir -p ~/.ssh # ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts # ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts - stage: tf-plan script: - - cp .tf-setup/$${TF_PROVIDERS_FILE} ./ + - cp ".tf-setup/$${TF_PROVIDERS_FILE}" ./ - | - for f in $${TF_VAR_FILES}; do + for f in "$${TF_VAR_FILES}"; do ln -s ".tf-setup/tfvars/$f" ./ done - terraform init - terraform validate - terraform plan + artifacts: + untracked: true dependencies: - tf-files tf-apply: + stage: tf-apply # uncomment the following lines and set the SSH key secret for private modules repo # before_script: # - | @@ -102,7 +112,6 @@ tf-apply: # mkdir -p ~/.ssh # ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts # ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts - stage: tf-apply script: - cp .tf-setup/$${TF_PROVIDERS_FILE} ./ - | @@ -112,6 +121,8 @@ tf-apply: - terraform init - terraform validate - terraform apply -input=false -auto-approve + artifacts: + untracked: true dependencies: - tf-files when: manual diff --git a/fast/stages/0-bootstrap/variables.tf b/fast/stages/0-bootstrap/variables.tf index 64b21782..f41d6dfa 100644 --- a/fast/stages/0-bootstrap/variables.tf +++ b/fast/stages/0-bootstrap/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -113,15 +113,20 @@ variable "fast_features" { variable "federated_identity_providers" { description = "Workload Identity Federation pools. The `cicd_repositories` variable references keys here." type = map(object({ - attribute_condition = string + attribute_condition = optional(string) issuer = string - custom_settings = object({ - issuer_uri = string - allowed_audiences = list(string) - }) + custom_settings = optional(object({ + issuer_uri = optional(string) + allowed_audiences = optional(list(string), []) + }), {}) })) default = {} nullable = false + # TODO: fix validation + # validation { + # condition = var.federated_identity_providers.custom_settings == null + # error_message = "Custom settings cannot be null." + # } } variable "groups" { diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md index 53b8defb..1a389364 100644 --- a/fast/stages/1-resman/README.md +++ b/fast/stages/1-resman/README.md @@ -334,7 +334,6 @@ Due to its simplicity, this stage lends itself easily to customizations: adding - ## Files | name | description | modules | resources | @@ -365,37 +364,36 @@ Due to its simplicity, this stage lends itself easily to customizations: adding | name | description | type | required | default | producer | |---|---|:---:|:---:|:---:|:---:| -| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap | -| [billing_account](variables.tf#L38) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | object({…}) | ✓ | | 0-bootstrap | -| [organization](variables.tf#L191) | Organization details. | object({…}) | ✓ | | 0-bootstrap | -| [prefix](variables.tf#L215) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | -| [cicd_repositories](variables.tf#L49) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | -| [custom_roles](variables.tf#L131) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | -| [data_dir](variables.tf#L140) | Relative path for the folder storing configuration data. | string | | "data" | | -| [fast_features](variables.tf#L146) | Selective control for top-level FAST features. | object({…}) | | {} | 0-0-bootstrap | -| [groups](variables.tf#L160) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | object({…}) | | {} | 0-bootstrap | -| [locations](variables.tf#L173) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {…} | 0-bootstrap | -| [organization_policy_configs](variables.tf#L201) | Organization policies customization. | object({…}) | | null | | -| [outputs_location](variables.tf#L209) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | -| [tag_names](variables.tf#L226) | Customized names for resource management tags. | object({…}) | | {…} | | -| [tags](variables.tf#L247) | Custome secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | -| [team_folders](variables.tf#L268) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | -| [tenants](variables.tf#L278) | Lightweight tenant definitions. | map(object({…})) | | {} | | -| [tenants_config](variables.tf#L294) | Lightweight tenants shared configuration. Roles will be assigned to tenant admin group and service accounts. | object({…}) | | {} | | +| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap | +| [billing_account](variables.tf#L39) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | object({…}) | ✓ | | 0-bootstrap | +| [organization](variables.tf#L192) | Organization details. | object({…}) | ✓ | | 0-bootstrap | +| [prefix](variables.tf#L216) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | +| [cicd_repositories](variables.tf#L50) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | object({…}) | | null | | +| [custom_roles](variables.tf#L132) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | +| [data_dir](variables.tf#L141) | Relative path for the folder storing configuration data. | string | | "data" | | +| [fast_features](variables.tf#L147) | Selective control for top-level FAST features. | object({…}) | | {} | 0-0-bootstrap | +| [groups](variables.tf#L161) | Group names or emails to grant organization-level permissions. If just the name is provided, the default organization domain is assumed. | object({…}) | | {} | 0-bootstrap | +| [locations](variables.tf#L174) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {…} | 0-bootstrap | +| [organization_policy_configs](variables.tf#L202) | Organization policies customization. | object({…}) | | null | | +| [outputs_location](variables.tf#L210) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | +| [tag_names](variables.tf#L227) | Customized names for resource management tags. | object({…}) | | {…} | | +| [tags](variables.tf#L248) | Custome secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | +| [team_folders](variables.tf#L269) | Team folders to be created. Format is described in a code comment. | map(object({…})) | | null | | +| [tenants](variables.tf#L279) | Lightweight tenant definitions. | map(object({…})) | | {} | | +| [tenants_config](variables.tf#L295) | Lightweight tenants shared configuration. Roles will be assigned to tenant admin group and service accounts. | object({…}) | | {} | | ## Outputs | name | description | sensitive | consumers | |---|---|:---:|---| -| [cicd_repositories](outputs.tf#L210) | WIF configuration for CI/CD repositories. | | | -| [dataplatform](outputs.tf#L224) | Data for the Data Platform stage. | | | -| [gke_multitenant](outputs.tf#L240) | Data for the GKE multitenant stage. | | 03-gke-multitenant | -| [networking](outputs.tf#L261) | Data for the networking stage. | | | -| [project_factories](outputs.tf#L270) | Data for the project factories stage. | | | -| [providers](outputs.tf#L285) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | -| [sandbox](outputs.tf#L292) | Data for the sandbox stage. | | xx-sandbox | -| [security](outputs.tf#L306) | Data for the networking stage. | | 02-security | -| [teams](outputs.tf#L316) | Data for the teams stage. | | | -| [tfvars](outputs.tf#L328) | Terraform variable files for the following stages. | ✓ | | - +| [cicd_repositories](outputs.tf#L213) | WIF configuration for CI/CD repositories. | | | +| [dataplatform](outputs.tf#L227) | Data for the Data Platform stage. | | | +| [gke_multitenant](outputs.tf#L243) | Data for the GKE multitenant stage. | | 03-gke-multitenant | +| [networking](outputs.tf#L264) | Data for the networking stage. | | | +| [project_factories](outputs.tf#L273) | Data for the project factories stage. | | | +| [providers](outputs.tf#L288) | Terraform provider files for this stage and dependent stages. | ✓ | 02-networking · 02-security · 03-dataplatform · xx-sandbox · xx-teams | +| [sandbox](outputs.tf#L295) | Data for the sandbox stage. | | xx-sandbox | +| [security](outputs.tf#L309) | Data for the networking stage. | | 02-security | +| [teams](outputs.tf#L319) | Data for the teams stage. | | | +| [tfvars](outputs.tf#L331) | Terraform variable files for the following stages. | ✓ | | diff --git a/fast/stages/1-resman/outputs.tf b/fast/stages/1-resman/outputs.tf index 80ec2b9d..c15706e2 100644 --- a/fast/stages/1-resman/outputs.tf +++ b/fast/stages/1-resman/outputs.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,6 +62,9 @@ locals { for k, v in local.cicd_repositories : k => templatefile( "${path.module}/templates/workflow-${v.type}.yaml", merge(local.cicd_workflow_attrs[k], { + audience = try( + local.identity_providers[v.identity_provider].audience, null + ) identity_provider = try( local.identity_providers[v.identity_provider].name, null ) diff --git a/fast/stages/1-resman/templates/workflow-gitlab.yaml b/fast/stages/1-resman/templates/workflow-gitlab.yaml index 8981e70b..33e55d21 100644 --- a/fast/stages/1-resman/templates/workflow-gitlab.yaml +++ b/fast/stages/1-resman/templates/workflow-gitlab.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# Copyright 2023 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,6 @@ # limitations under the License. default: - before_script: - - echo "$${CI_JOB_JWT_V2}" > token.txt image: name: hashicorp/terraform entrypoint: @@ -22,6 +20,7 @@ default: - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" variables: + AUDIENCE: ${audience} GOOGLE_CREDENTIALS: cicd-sa-credentials.json FAST_OUTPUTS_BUCKET: ${outputs_bucket} FAST_SERVICE_ACCOUNT: ${service_account} @@ -39,13 +38,15 @@ stages: cache: key: gcp-auth paths: - - cicd-sa-credentials.json - .tf-setup gcp-auth: + stage: gcp-auth + id_tokens: + GITLAB_TOKEN: + aud: "$${AUDIENCE}" image: name: google/cloud-sdk:slim - stage: gcp-auth script: - | gcloud iam workload-identity-pools create-cred-config \ @@ -54,12 +55,14 @@ gcp-auth: --service-account-token-lifetime-seconds=3600 \ --output-file=$${GOOGLE_CREDENTIALS} \ --credential-source-file=token.txt + - rm token.txt + artifacts: + untracked: true + tf-files: - dependencies: - - gcp-auth + stage: tf-files image: name: google/cloud-sdk:slim - stage: tf-files script: # - gcloud components install -q alpha - gcloud config set auth/credential_file_override $${GOOGLE_CREDENTIALS} @@ -70,8 +73,13 @@ tf-files: - | gcloud alpha storage cp -r \ "gs://$${FAST_OUTPUTS_BUCKET}/tfvars" .tf-setup/ + artifacts: + untracked: true + dependencies: + - gcp-auth tf-plan: + stage: tf-plan # uncomment the following lines and set the SSH key secret for private modules repo # before_script: # - | @@ -80,20 +88,22 @@ tf-plan: # mkdir -p ~/.ssh # ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts # ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts - stage: tf-plan script: - - cp .tf-setup/$${TF_PROVIDERS_FILE} ./ + - cp ".tf-setup/$${TF_PROVIDERS_FILE}" ./ - | - for f in $${TF_VAR_FILES}; do + for f in "$${TF_VAR_FILES}"; do ln -s ".tf-setup/tfvars/$f" ./ done - terraform init - terraform validate - terraform plan + artifacts: + untracked: true dependencies: - tf-files tf-apply: + stage: tf-apply # uncomment the following lines and set the SSH key secret for private modules repo # before_script: # - | @@ -102,7 +112,6 @@ tf-apply: # mkdir -p ~/.ssh # ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts # ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts - stage: tf-apply script: - cp .tf-setup/$${TF_PROVIDERS_FILE} ./ - | @@ -112,6 +121,8 @@ tf-apply: - terraform init - terraform validate - terraform apply -input=false -auto-approve + artifacts: + untracked: true dependencies: - tf-files when: manual diff --git a/fast/stages/1-resman/variables.tf b/fast/stages/1-resman/variables.tf index 70ee2139..35030d2a 100644 --- a/fast/stages/1-resman/variables.tf +++ b/fast/stages/1-resman/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ variable "automation" { project_number = string federated_identity_pool = string federated_identity_providers = map(object({ + audience = string issuer = string issuer_uri = string name = string