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
diff --git a/fast/stages/2-networking-a-peering/landing.tf b/fast/stages/2-networking-a-peering/landing.tf
index db40b3f1..013c6e86 100644
--- a/fast/stages/2-networking-a-peering/landing.tf
+++ b/fast/stages/2-networking-a-peering/landing.tf
@@ -84,5 +84,4 @@ module "landing-nat-primary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.primary]}"
router_network = module.landing-vpc.name
- router_asn = 4200001024
}
diff --git a/fast/stages/2-networking-a-peering/spoke-dev.tf b/fast/stages/2-networking-a-peering/spoke-dev.tf
index 2256926f..838ba6a4 100644
--- a/fast/stages/2-networking-a-peering/spoke-dev.tf
+++ b/fast/stages/2-networking-a-peering/spoke-dev.tf
@@ -80,7 +80,6 @@ module "dev-spoke-cloudnat" {
name = "dev-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.dev-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-a-peering/spoke-prod.tf b/fast/stages/2-networking-a-peering/spoke-prod.tf
index b7e3abcb..7569647e 100644
--- a/fast/stages/2-networking-a-peering/spoke-prod.tf
+++ b/fast/stages/2-networking-a-peering/spoke-prod.tf
@@ -79,7 +79,6 @@ module "prod-spoke-cloudnat" {
name = "prod-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.prod-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-b-vpn/landing.tf b/fast/stages/2-networking-b-vpn/landing.tf
index db40b3f1..013c6e86 100644
--- a/fast/stages/2-networking-b-vpn/landing.tf
+++ b/fast/stages/2-networking-b-vpn/landing.tf
@@ -84,5 +84,4 @@ module "landing-nat-primary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.primary]}"
router_network = module.landing-vpc.name
- router_asn = 4200001024
}
diff --git a/fast/stages/2-networking-b-vpn/spoke-dev.tf b/fast/stages/2-networking-b-vpn/spoke-dev.tf
index 2256926f..838ba6a4 100644
--- a/fast/stages/2-networking-b-vpn/spoke-dev.tf
+++ b/fast/stages/2-networking-b-vpn/spoke-dev.tf
@@ -80,7 +80,6 @@ module "dev-spoke-cloudnat" {
name = "dev-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.dev-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-b-vpn/spoke-prod.tf b/fast/stages/2-networking-b-vpn/spoke-prod.tf
index b7e3abcb..7569647e 100644
--- a/fast/stages/2-networking-b-vpn/spoke-prod.tf
+++ b/fast/stages/2-networking-b-vpn/spoke-prod.tf
@@ -79,7 +79,6 @@ module "prod-spoke-cloudnat" {
name = "prod-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.prod-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-c-nva/landing.tf b/fast/stages/2-networking-c-nva/landing.tf
index 75cb9e81..e7329a43 100644
--- a/fast/stages/2-networking-c-nva/landing.tf
+++ b/fast/stages/2-networking-c-nva/landing.tf
@@ -85,7 +85,6 @@ module "landing-nat-primary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.primary]}"
router_network = module.landing-untrusted-vpc.name
- router_asn = 4200001024
}
moved {
@@ -101,7 +100,6 @@ module "landing-nat-secondary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.secondary]}"
router_network = module.landing-untrusted-vpc.name
- router_asn = 4200001024
}
# Trusted VPC
diff --git a/fast/stages/2-networking-d-separate-envs/spoke-dev.tf b/fast/stages/2-networking-d-separate-envs/spoke-dev.tf
index fd15e26c..b5b485be 100644
--- a/fast/stages/2-networking-d-separate-envs/spoke-dev.tf
+++ b/fast/stages/2-networking-d-separate-envs/spoke-dev.tf
@@ -80,7 +80,6 @@ module "dev-spoke-cloudnat" {
name = "dev-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.dev-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-d-separate-envs/spoke-prod.tf b/fast/stages/2-networking-d-separate-envs/spoke-prod.tf
index c8d8a69c..bf43728d 100644
--- a/fast/stages/2-networking-d-separate-envs/spoke-prod.tf
+++ b/fast/stages/2-networking-d-separate-envs/spoke-prod.tf
@@ -79,7 +79,6 @@ module "prod-spoke-cloudnat" {
name = "prod-nat-${local.region_shortnames[each.value]}"
router_create = true
router_network = module.prod-spoke-vpc.name
- router_asn = 4200001024
logging_filter = "ERRORS_ONLY"
}
diff --git a/fast/stages/2-networking-e-nva-bgp/landing.tf b/fast/stages/2-networking-e-nva-bgp/landing.tf
index 434adb85..ab6c94eb 100644
--- a/fast/stages/2-networking-e-nva-bgp/landing.tf
+++ b/fast/stages/2-networking-e-nva-bgp/landing.tf
@@ -86,7 +86,6 @@ module "landing-nat-primary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.primary]}"
router_network = module.landing-untrusted-vpc.name
- router_asn = 4200001024
}
moved {
@@ -102,7 +101,6 @@ module "landing-nat-secondary" {
router_create = true
router_name = "prod-nat-${local.region_shortnames[var.regions.secondary]}"
router_network = module.landing-untrusted-vpc.name
- router_asn = 4200001024
}
# Trusted VPC