From 6444331e683ddffa3e3466ffc2429346fb7bff77 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 16 Jan 2023 23:23:14 +0530 Subject: [PATCH 01/21] Create Jenkinsfile --- .../guardrails/folder-factory/Jenkinsfile | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 examples/guardrails/folder-factory/Jenkinsfile diff --git a/examples/guardrails/folder-factory/Jenkinsfile b/examples/guardrails/folder-factory/Jenkinsfile new file mode 100644 index 0000000..63cca86 --- /dev/null +++ b/examples/guardrails/folder-factory/Jenkinsfile @@ -0,0 +1,70 @@ +pipeline { + + agent any + environment { + BUCKET_PATH = credentials('backend-path') + REPO_FULL_NAME = credentials('bucket-repo') + PROJECT_NAME = credentials('project-name') + GCP_PROJECT_NUMBER = credentials('project-id') + workload_identity_pool_id = credentials('wif_pool_id') + workload_identity_pool_provider_id = credentials('wif_pool_provider_id') + SERVICE_ACCOUNT_NAME = credentials('sa-name') + + } + options { + skipDefaultCheckout(true) + } + stages { + stage('clean workspace') { + steps { + cleanWs() + } + } + stage('WIF') { + steps { + withCredentials([file(variable: 'ID_TOKEN_FILE', credentialsId: 'gcp')]) { + writeFile file: "$WORKSPACE_TMP/creds.json", text: """ + { + "type": "external_account", + "audience": "//iam.googleapis.com/projects/${GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${workload_identity_pool_id}/providers/${workload_identity_pool_provider_id}", + "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", + "token_url": "https://sts.googleapis.com/v1/token", + "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT_NAME}@${PROJECT_NAME}.iam.gserviceaccount.com:generateAccessToken", + "credential_source": { + "file": "$ID_TOKEN_FILE", + "format": { + "type": "text" + } + } + } + """ + sh ''' + gcloud auth login --brief --cred-file=$WORKSPACE_TMP/creds.json + ''' +} + + } + } + stage('checkout') { + steps { + checkout scm + } + } + stage('Terraform') { + steps { + + sh ''' + cd guardrails/folder-factory + terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=${REPO_FULL_NAME}" + terraform plan + terraform apply -auto-approve + + ''' + + } + } + + + } +} + From 6d440c4bf69a5cb21228e0729f15d5810e776975 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:31:03 +0530 Subject: [PATCH 02/21] Create Jenkinsfile --- .../guardrails/project-factory/Jenkinsfile | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/guardrails/project-factory/Jenkinsfile diff --git a/examples/guardrails/project-factory/Jenkinsfile b/examples/guardrails/project-factory/Jenkinsfile new file mode 100644 index 0000000..a7f9447 --- /dev/null +++ b/examples/guardrails/project-factory/Jenkinsfile @@ -0,0 +1,39 @@ +pipeline { + + agent any + environment { + BUCKET_PATH = credentials('backend-path') + + + } + + options { + skipDefaultCheckout(true) + } + stages { + stage('clean workspace') { + steps { + cleanWs() + } + } + stage('checkout') { + steps { + checkout scm + } + } + + stage('Terraform') { + steps { + + sh ''' + cd guardrails/project-factory + terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=project-factory-staging-tfstate" -var-file="staging.tfvars" + terraform plan -var-file="staging.tfvars" + terraform apply -var-file="staging.tfvars" -auto-approve + + ''' + + } + } + } +} From dff339cabb83d6735907c4ab6ceb7b41717ddf58 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:31:45 +0530 Subject: [PATCH 03/21] Update wif.tf --- examples/guardrails/project-factory/wif.tf | 40 +++++++--------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/examples/guardrails/project-factory/wif.tf b/examples/guardrails/project-factory/wif.tf index c54c67f..d3568e4 100644 --- a/examples/guardrails/project-factory/wif.tf +++ b/examples/guardrails/project-factory/wif.tf @@ -22,46 +22,30 @@ module "wif-project" { source = "./modules/project" name = "wif-prj-${random_id.rand.hex}" parent = var.folder - billing_account = "01B3B2-962224-4EEC67" + billing_account = var.billing_account } -resource "google_iam_workload_identity_pool" "wif-pool-gitlab" { +resource "google_iam_workload_identity_pool" "wif-pool-jenkins" { provider = google-beta - workload_identity_pool_id = "gitlab-pool-${random_id.rand.hex}" + workload_identity_pool_id = "jenkins-pool1-${random_id.rand.hex}" project = module.wif-project.project_id } -resource "google_iam_workload_identity_pool_provider" "wif-provider-gitlab" { +resource "google_iam_workload_identity_pool_provider" "wif-provider-jenkins" { provider = google-beta - workload_identity_pool_id = google_iam_workload_identity_pool.wif-pool-gitlab.workload_identity_pool_id - workload_identity_pool_provider_id = "gitlab-provider-${random_id.rand.hex}" + workload_identity_pool_id = google_iam_workload_identity_pool.wif-pool-jenkins.workload_identity_pool_id + workload_identity_pool_provider_id = "jenkins-provider-${random_id.rand.hex}" project = module.wif-project.project_id attribute_mapping = { "google.subject" = "assertion.sub" "attribute.sub" = "assertion.sub" + "attribute.branch_name" = "assertion.branchName" } oidc { - issuer_uri = "https://gitlab.com" - } -} - -resource "google_iam_workload_identity_pool" "wif-pool-github" { - provider = google-beta - workload_identity_pool_id = "github-pool-${random_id.rand.hex}" - project = module.wif-project.project_id -} - -resource "google_iam_workload_identity_pool_provider" "wif-provider-github" { - provider = google-beta - workload_identity_pool_id = google_iam_workload_identity_pool.wif-pool-github.workload_identity_pool_id - workload_identity_pool_provider_id = "github-provider-${random_id.rand.hex}" - project = module.wif-project.project_id - attribute_mapping = { - "google.subject" = "assertion.sub" - "attribute.sub" = "assertion.sub" - "attribute.actor" = "assertion.actor" - } - oidc { - issuer_uri = "https://token.actions.githubusercontent.com" + issuer_uri = var.issuer_uri + allowed_audiences = var.allowed_audiences } + depends_on = [ + google_iam_workload_identity_pool.wif-pool-jenkins + ] } From 2391021d897b71febecdad23811bdbfdfd41c69a Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:32:19 +0530 Subject: [PATCH 04/21] Update variables.tf --- examples/guardrails/project-factory/variables.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/guardrails/project-factory/variables.tf b/examples/guardrails/project-factory/variables.tf index df6e79d..c2c9ea4 100644 --- a/examples/guardrails/project-factory/variables.tf +++ b/examples/guardrails/project-factory/variables.tf @@ -17,3 +17,11 @@ variable "folder" { } +variable "billing_account" { +} +variable "issuer_uri" { +} + +variable "allowed_audiences" { + type = list +} From 2b6182e69d0d92df00cfdc54c92003370447774f Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 00:34:11 +0530 Subject: [PATCH 05/21] Update main.tf --- .../guardrails/project-factory/modules/project_plus/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/guardrails/project-factory/modules/project_plus/main.tf b/examples/guardrails/project-factory/modules/project_plus/main.tf index 7330dd0..2332f16 100644 --- a/examples/guardrails/project-factory/modules/project_plus/main.tf +++ b/examples/guardrails/project-factory/modules/project_plus/main.tf @@ -34,7 +34,7 @@ resource "google_service_account" "sa" { resource "google_service_account_iam_member" "sa-iam" { service_account_id = google_service_account.sa.name role = "roles/iam.workloadIdentityUser" - member = "principalSet://iam.googleapis.com/${var.wif-pool}/attribute.sub/${var.repo_sub}" + member = "principalSet://iam.googleapis.com/${var.wif-pool}/attribute.branch_name/${var.repo_sub}" } resource "google_project_iam_member" "sa-project" { From 200b22ab58306132203e639fe4b5ed9bd1b34a0d Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:37:02 +0530 Subject: [PATCH 06/21] Update variables.tf --- examples/guardrails/skunkworks/variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/guardrails/skunkworks/variables.tf b/examples/guardrails/skunkworks/variables.tf index 6af98ff..2709299 100644 --- a/examples/guardrails/skunkworks/variables.tf +++ b/examples/guardrails/skunkworks/variables.tf @@ -16,5 +16,5 @@ variable "project" { type = string - default = "project-id" + } From c6f54f7c1bd1be958c2fb316d4717adad4807099 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:37:57 +0530 Subject: [PATCH 07/21] Update main.tf --- examples/guardrails/project-factory/main.tf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/guardrails/project-factory/main.tf b/examples/guardrails/project-factory/main.tf index 3d589d4..6c7d4d7 100644 --- a/examples/guardrails/project-factory/main.tf +++ b/examples/guardrails/project-factory/main.tf @@ -25,11 +25,12 @@ module "project" { source = "./modules/project_plus" for_each = local.projects team = each.key - repo_sub = "${each.value.repo_provider == "gitlab" ? "project_path:${each.value.repo_name}:ref_type:branch:ref:${each.value.repo_branch}" : "repo:${each.value.repo_name}:ref:refs/heads/${each.value.repo_branch}"}" + repo_sub = each.value.repo_branch repo_provider = each.value.repo_provider billing_account = each.value.billing_account_id folder = var.folder roles = try(each.value.roles, []) - wif-pool = "${each.value.repo_provider == "gitlab" ? google_iam_workload_identity_pool.wif-pool-gitlab.name : google_iam_workload_identity_pool.wif-pool-github.name}" - depends_on = [google_iam_workload_identity_pool.wif-pool-github,google_iam_workload_identity_pool.wif-pool-gitlab] + wif-pool = google_iam_workload_identity_pool.wif-pool-jenkins.name + depends_on = [google_iam_workload_identity_pool.wif-pool-jenkins] } + From 31f46c96b734b620bae516c5c7139a65fe675a10 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:45:21 +0530 Subject: [PATCH 08/21] Create Jenkinsfile --- examples/guardrails/skunkworks/Jenkinsfile | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 examples/guardrails/skunkworks/Jenkinsfile diff --git a/examples/guardrails/skunkworks/Jenkinsfile b/examples/guardrails/skunkworks/Jenkinsfile new file mode 100644 index 0000000..099eed3 --- /dev/null +++ b/examples/guardrails/skunkworks/Jenkinsfile @@ -0,0 +1,65 @@ +pipeline { + + agent any + environment { + BUCKET_PATH = credentials('backend-path') + SKUNKWORK_PROJECT = credentials('staging-project') + SW_PROJECT_NUMBER = credentials('sw-project-number') + SW_SERVICE_ACCOUNT = credentials('sw-sa') + } + options { + skipDefaultCheckout(true) + } + stages { + stage('clean workspace') { + steps { + cleanWs() + } + } + stage('WIF') { + steps { + withCredentials([file(variable: 'ID_TOKEN_STAGE', credentialsId: 'staging')]) { + writeFile file: "$WORKSPACE_TMP/sts_creds.json", text: """ + { + "type": "external_account", + "audience": "//iam.googleapis.com/projects/${SW_PROJECT_NUMBER}/locations/global/workloadIdentityPools/jenkins-pool1-ad8aa16a/providers/jenkins-provider-ad8aa16a", + "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", + "token_url": "https://sts.googleapis.com/v1/token", + "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SW_SERVICE_ACCOUNT}@${SKUNKWORK_PROJECT}.iam.gserviceaccount.com:generateAccessToken", + "credential_source": { + "file": "$ID_TOKEN_STAGE", + "format": { + "type": "text" + } + } + } + """ + sh ''' + gcloud auth login --brief --cred-file=$WORKSPACE_TMP/sts_creds.json + ''' +} + } + } + + stage('checkout') { + steps { + checkout scm + } + } + stage('Terraform') { + steps { + + sh ''' + cd guardrails/skunkworks + terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=prod-skunkworks" + terraform plan -var="project=${SKUNKWORK_PROJECT}" + terraform apply -var="project=${SKUNKWORK_PROJECT}" -auto-approve + + ''' + + } + } + + + } +} From c5e06c5784d7ec888236d6f1360fd61341187829 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:56:50 +0530 Subject: [PATCH 09/21] Update Jenkinsfile with config validator changes --- .../guardrails/folder-factory/Jenkinsfile | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/examples/guardrails/folder-factory/Jenkinsfile b/examples/guardrails/folder-factory/Jenkinsfile index 63cca86..1c88f06 100644 --- a/examples/guardrails/folder-factory/Jenkinsfile +++ b/examples/guardrails/folder-factory/Jenkinsfile @@ -9,6 +9,7 @@ pipeline { workload_identity_pool_id = credentials('wif_pool_id') workload_identity_pool_provider_id = credentials('wif_pool_provider_id') SERVICE_ACCOUNT_NAME = credentials('sa-name') + policy_file_path = credentials('policy_file_path') } options { @@ -50,21 +51,44 @@ pipeline { checkout scm } } - stage('Terraform') { + stage('Terraform Plan') { steps { sh ''' cd guardrails/folder-factory terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=${REPO_FULL_NAME}" - terraform plan - terraform apply -auto-approve + terraform plan -input=false -out ffjenkins.tfplan + ''' } } - + stage('Terraform Validate') { + steps { + + sh ''' + cd guardrails/folder-factory + terraform show -json "ffjenkins.tfplan" > "ffjenkins.json" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${PROJECT_NAME}" + gcloud beta terraform vet "ffjenkins.json" --policy-library="${policy_file_path}" --project="${PROJECT_NAME}" + + ''' + + } + } + stage('Terraform Apply') { + steps { + + sh ''' + cd guardrails/folder-factory + terraform apply -auto-approve + + ''' + + } + } } } From 7d752fadca12f81031314b745d480d00ae6049af Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:59:25 +0530 Subject: [PATCH 10/21] Update Jenkinsfile for config validator --- .../guardrails/project-factory/Jenkinsfile | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/examples/guardrails/project-factory/Jenkinsfile b/examples/guardrails/project-factory/Jenkinsfile index a7f9447..88ce49e 100644 --- a/examples/guardrails/project-factory/Jenkinsfile +++ b/examples/guardrails/project-factory/Jenkinsfile @@ -3,7 +3,7 @@ pipeline { agent any environment { BUCKET_PATH = credentials('backend-path') - + policy_file_path = credentials('policy_file_path') } @@ -22,17 +22,39 @@ pipeline { } } - stage('Terraform') { + stage('Terraform Plan') { steps { sh ''' cd guardrails/project-factory terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=project-factory-staging-tfstate" -var-file="staging.tfvars" - terraform plan -var-file="staging.tfvars" - terraform apply -var-file="staging.tfvars" -auto-approve + terraform plan -var-file="staging.tfvars" -out pfjenkins.tfplan + ''' + } + } + stage('Terraform Validate') { + steps { + + sh ''' + cd guardrails/project-factory + terraform show -json "pfjenkins.tfplan" > "ffjenkins.json" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${PROJECT_NAME}" + gcloud beta terraform vet "pfjenkins.json" --policy-library="${policy_file_path}" --project="${PROJECT_NAME}" + ''' + + } + } + stage('Terraform Apply') { + steps { + + sh ''' + cd guardrails/project-factory + terraform apply -var-file="staging.tfvars" -auto-approve + ''' + } } } From 5460c019b1ce310e7c8bcfe67d4939e80c010387 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 09:06:02 +0530 Subject: [PATCH 11/21] Update Jenkinfile for config validator --- examples/guardrails/skunkworks/Jenkinsfile | 34 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/examples/guardrails/skunkworks/Jenkinsfile b/examples/guardrails/skunkworks/Jenkinsfile index 099eed3..e740c56 100644 --- a/examples/guardrails/skunkworks/Jenkinsfile +++ b/examples/guardrails/skunkworks/Jenkinsfile @@ -6,6 +6,9 @@ pipeline { SKUNKWORK_PROJECT = credentials('staging-project') SW_PROJECT_NUMBER = credentials('sw-project-number') SW_SERVICE_ACCOUNT = credentials('sw-sa') + SW_workload_identity_pool_id = credentials('sw_wif_pool_id') + SW_workload_identity_pool_provider_id = credentials('sw_wif_pool_provider_id') + policy_file_path = credentials('policy_file_path') } options { skipDefaultCheckout(true) @@ -22,7 +25,7 @@ pipeline { writeFile file: "$WORKSPACE_TMP/sts_creds.json", text: """ { "type": "external_account", - "audience": "//iam.googleapis.com/projects/${SW_PROJECT_NUMBER}/locations/global/workloadIdentityPools/jenkins-pool1-ad8aa16a/providers/jenkins-provider-ad8aa16a", + "audience": "//iam.googleapis.com/projects/${SW_PROJECT_NUMBER}/locations/global/workloadIdentityPools/${SW_workload_identity_pool_id}/providers/${SW_workload_identity_pool_provider_id}", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SW_SERVICE_ACCOUNT}@${SKUNKWORK_PROJECT}.iam.gserviceaccount.com:generateAccessToken", @@ -46,20 +49,41 @@ pipeline { checkout scm } } - stage('Terraform') { + stage('Terraform Plan') { steps { sh ''' cd guardrails/skunkworks terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=prod-skunkworks" - terraform plan -var="project=${SKUNKWORK_PROJECT}" - terraform apply -var="project=${SKUNKWORK_PROJECT}" -auto-approve + terraform plan -var="project=${SKUNKWORK_PROJECT}" -out swjenkins.tfplan + ''' } } - + stage('Terraform Validate') { + steps { + + sh ''' + cd guardrails/skunkworks + terraform show -json "swjenkins.tfplan" > "swjenkins.json" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${sw-project-number}" + gcloud beta terraform vet "swjenkins.json" --policy-library="${policy_file_path}" --project="${sw-project-number}" + ''' + + } + } + stage('Terraform Apply') { + steps { + + sh ''' + cd guardrails/skunkworks + terraform apply -var="project=${SKUNKWORK_PROJECT}" -auto-approve + ''' + + } + } } } From b4ad1b24d0575264871a7ea9c694080cfe73e338 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 09:06:41 +0530 Subject: [PATCH 12/21] Update Jenkinsfile --- examples/guardrails/project-factory/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/guardrails/project-factory/Jenkinsfile b/examples/guardrails/project-factory/Jenkinsfile index 88ce49e..8340813 100644 --- a/examples/guardrails/project-factory/Jenkinsfile +++ b/examples/guardrails/project-factory/Jenkinsfile @@ -41,8 +41,8 @@ pipeline { sh ''' cd guardrails/project-factory terraform show -json "pfjenkins.tfplan" > "ffjenkins.json" - gcloud source repos clone gcp-policies "${policy_file_path}" --project="${PROJECT_NAME}" - gcloud beta terraform vet "pfjenkins.json" --policy-library="${policy_file_path}" --project="${PROJECT_NAME}" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" + gcloud beta terraform vet "pfjenkins.json" --policy-library="${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" ''' } From e4835eb06a82778025f6f3a58625d312727e3834 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 09:07:07 +0530 Subject: [PATCH 13/21] Update Jenkinsfile --- examples/guardrails/folder-factory/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/guardrails/folder-factory/Jenkinsfile b/examples/guardrails/folder-factory/Jenkinsfile index 1c88f06..329ce22 100644 --- a/examples/guardrails/folder-factory/Jenkinsfile +++ b/examples/guardrails/folder-factory/Jenkinsfile @@ -71,8 +71,8 @@ pipeline { sh ''' cd guardrails/folder-factory terraform show -json "ffjenkins.tfplan" > "ffjenkins.json" - gcloud source repos clone gcp-policies "${policy_file_path}" --project="${PROJECT_NAME}" - gcloud beta terraform vet "ffjenkins.json" --policy-library="${policy_file_path}" --project="${PROJECT_NAME}" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" + gcloud beta terraform vet "ffjenkins.json" --policy-library="${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" ''' From b1713ca6e465466f61373a0293a036e16b4b48fa Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Mon, 20 Mar 2023 09:07:44 +0530 Subject: [PATCH 14/21] Update Jenkinsfile --- examples/guardrails/skunkworks/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/guardrails/skunkworks/Jenkinsfile b/examples/guardrails/skunkworks/Jenkinsfile index e740c56..0c6d91f 100644 --- a/examples/guardrails/skunkworks/Jenkinsfile +++ b/examples/guardrails/skunkworks/Jenkinsfile @@ -68,8 +68,8 @@ pipeline { sh ''' cd guardrails/skunkworks terraform show -json "swjenkins.tfplan" > "swjenkins.json" - gcloud source repos clone gcp-policies "${policy_file_path}" --project="${sw-project-number}" - gcloud beta terraform vet "swjenkins.json" --policy-library="${policy_file_path}" --project="${sw-project-number}" + gcloud source repos clone gcp-policies "${policy_file_path}" --project="${SW_PROJECT_NUMBER}" + gcloud beta terraform vet "swjenkins.json" --policy-library="${policy_file_path}" --project="${SW_PROJECT_NUMBER}" ''' } From 6b8b6feabfa7474b956db2de2f32daefcabfd18d Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Thu, 23 Mar 2023 12:04:36 +0530 Subject: [PATCH 15/21] Update Readme.md file --- examples/guardrails/folder-factory/README.md | 41 ++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/examples/guardrails/folder-factory/README.md b/examples/guardrails/folder-factory/README.md index a139948..43dd0b0 100644 --- a/examples/guardrails/folder-factory/README.md +++ b/examples/guardrails/folder-factory/README.md @@ -57,3 +57,44 @@ iam: ``` Every folder is defined with its own yaml file located in the following [Folder](data/folder). + +## How to run this stage +### Prerequisites + +Workload Identity setup between the folder factory gitlab repositories and the GCP Identity provider configured with a service account containing required permissions to create folders and their organizational policies. There is a sample code provided in “folder.yaml.sample” to create a folder and for terraform to create a folder minimum below permissions are required. +“Folder Creator” or “Folder Admin” at org level +“Organization Policy Admin” at org level + + +### Installation Steps + +Step 1: Create a bucket for terraform backend on the GCP environment. +Step 2: Create Jenkins Pipeline on Jenkins. +Step 3: Configure the below variables on Jenkins Credentials. + +### Terraform config validator +The pipeline has an option to utilise the integrated config validator (gcloud terraform vet) to impose constraints on your terraform configuration. You have to provide the policy-library repo URL to $POLICY_LIBRARY_REPO variable. See the below for details on the Variables to be set on the CI/CD pipeline. + + +| Variable | | Example Value | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- | +| PROJECT_NAME | The project containing the service account that has permission to communicate with the WIF provider. Should be created as part of Project Factory. | jenkins-connect-prj | +| GCP_PROJECT_NUMBER | Project number for the project that hosts the WIF provider | 107999111999 | +| SERVICE_ACCOUNT_NAME | The name of the service account that will be used to deploy. Must be hosted in PROJECT_NAME. | jenkins-sa | +| BUCKET_PATH | A state bucket that will hold the terraform state. This bucket must previously exist and the service account must have permission to read/write to it. | jenkins-gcs-state-bucket-name | +| policy_file_path | https://github.com/GoogleCloudPlatform/policy-library | The public repo where the policies are hosted | +| workload_identity_pool_id | | jenkins-test-pool | +| workload_identity_provider_id | | jenkins-test-provider | | + +* Once the prerequisites are set up, any commit to the remote main branch with changes to *.tf, *.tfvars, data/*, modules/* files should trigger the pipeline. + + +### Pipeline Workflow Overview +The complete workflow comprises of 6 stages and 2 before-script jobs + * Stages: + * Clean workspace : This step cleans the previous packages from Jenkins workspace + * WIF : Execute the Workload Identity Federation script and generate credential file. + * Terraform plan: Runs terraform plan and saves the plan and json version of the plan as artifacts, this depends on the branch + * Terraform validate: Runs gcloud terraform vet against the terraform code with the constraints in the specified repository. + * apply: This is executed for specified list of branches, currently main/master + From 4b0a5d2a931dd0d8f6095ff60595aa1c7771ebb2 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Thu, 23 Mar 2023 12:42:30 +0530 Subject: [PATCH 16/21] Update Readme file --- examples/guardrails/project-factory/README.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/examples/guardrails/project-factory/README.md b/examples/guardrails/project-factory/README.md index f901e7f..bd5b101 100644 --- a/examples/guardrails/project-factory/README.md +++ b/examples/guardrails/project-factory/README.md @@ -73,3 +73,45 @@ repo_branch: dev ``` Every project is defined with its own file located in the [Project Folder](data/projects). + +## How to run this stage +### Prerequisites + +Workload Identity setup between the folder factory gitlab repositories and the GCP Identity provider configured with a service account containing required permissions to create folders and their organizational policies. There is a sample code provided in “folder.yaml.sample” to create a folder and for terraform to create a folder minimum below permissions are required. +“Folder Creator” or “Folder Admin” at org level +“Organization Policy Admin” at org level + + +### Installation Steps + +Step 1: Create a bucket for terraform backend on the GCP environment. +Step 2: Create Jenkins Pipeline on Jenkins. +Step 3: Configure the below variables on Jenkins Credentials. + +### Terraform config validator +The pipeline has an option to utilise the integrated config validator (gcloud terraform vet) to impose constraints on your terraform configuration. You have to provide the policy-library repo URL to $POLICY_LIBRARY_REPO variable. See the below for details on the Variables to be set on the CI/CD pipeline. + + +| Variable | | Example Value | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- | +| PROJECT_NAME | The project containing the service account that has permission to communicate with the WIF provider. Should be created as part of Project Factory. | jenkins-connect-prj | +| GCP_PROJECT_NUMBER | Project number for the project that hosts the WIF provider | 107999111999 | +| SERVICE_ACCOUNT_NAME | The name of the service account that will be used to deploy. Must be hosted in PROJECT_NAME. | jenkins-sa | +| BUCKET_PATH | A state bucket that will hold the terraform state. This bucket must previously exist and the service account must have permission to read/write to it. | jenkins-gcs-state-bucket-name | +| policy_file_path | https://github.com/GoogleCloudPlatform/policy-library | The public repo where the policies are hosted | +| workload_identity_pool_id | | jenkins-test-pool | +| workload_identity_provider_id | | jenkins-test-provider | | + +* Once the prerequisites are set up, any commit to the remote main branch with changes to *.tf, *.tfvars, data/*, modules/* files should trigger the pipeline. + + +### Pipeline Workflow Overview +The complete workflow comprises of 6 stages and 2 before-script jobs + * Stages: + * Clean workspace : This step cleans the previous packages from Jenkins workspace + * WIF : Execute the Workload Identity Federation script and generate credential file. + * Terraform plan: Runs terraform plan and saves the plan and json version of the plan as artifacts, this depends on the branch + * Terraform validate: Runs gcloud terraform vet against the terraform code with the constraints in the specified repository. + * apply: This is executed for specified list of branches, currently main/master + + From 042923e274889d614c70660641efc70f28ddaa92 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Thu, 23 Mar 2023 12:43:03 +0530 Subject: [PATCH 17/21] Update Readme file --- examples/guardrails/skunkworks/README.md | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/examples/guardrails/skunkworks/README.md b/examples/guardrails/skunkworks/README.md index 0b89bb2..7602c43 100644 --- a/examples/guardrails/skunkworks/README.md +++ b/examples/guardrails/skunkworks/README.md @@ -27,3 +27,43 @@ env: SERVICE_ACCOUNT: 'XXXX@XXXX' # The service account that should be used for this repository. ``` +## How to run this stage +### Prerequisites + +Workload Identity setup between the folder factory gitlab repositories and the GCP Identity provider configured with a service account containing required permissions to create folders and their organizational policies. There is a sample code provided in “folder.yaml.sample” to create a folder and for terraform to create a folder minimum below permissions are required. +“Folder Creator” or “Folder Admin” at org level +“Organization Policy Admin” at org level + + +### Installation Steps + +Step 1: Create a bucket for terraform backend on the GCP environment. +Step 2: Create Jenkins Pipeline on Jenkins. +Step 3: Configure the below variables on Jenkins Credentials. + +### Terraform config validator +The pipeline has an option to utilise the integrated config validator (gcloud terraform vet) to impose constraints on your terraform configuration. You have to provide the policy-library repo URL to $POLICY_LIBRARY_REPO variable. See the below for details on the Variables to be set on the CI/CD pipeline. + + +| Variable | | Example Value | +| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- | +| PROJECT_NAME | The project containing the service account that has permission to communicate with the WIF provider. Should be created as part of Project Factory. | jenkins-connect-prj | +| GCP_PROJECT_NUMBER | Project number for the project that hosts the WIF provider | 107999111999 | +| SERVICE_ACCOUNT_NAME | The name of the service account that will be used to deploy. Must be hosted in PROJECT_NAME. | jenkins-sa | +| BUCKET_PATH | A state bucket that will hold the terraform state. This bucket must previously exist and the service account must have permission to read/write to it. | jenkins-gcs-state-bucket-name | +| policy_file_path | https://github.com/GoogleCloudPlatform/policy-library | The public repo where the policies are hosted | +| workload_identity_pool_id | | jenkins-test-pool | +| workload_identity_provider_id | | jenkins-test-provider | | + +* Once the prerequisites are set up, any commit to the remote main branch with changes to *.tf, *.tfvars, data/*, modules/* files should trigger the pipeline. + + +### Pipeline Workflow Overview +The complete workflow comprises of 6 stages and 2 before-script jobs + * Stages: + * Clean workspace : This step cleans the previous packages from Jenkins workspace + * WIF : Execute the Workload Identity Federation script and generate credential file. + * Terraform plan: Runs terraform plan and saves the plan and json version of the plan as artifacts, this depends on the branch + * Terraform validate: Runs gcloud terraform vet against the terraform code with the constraints in the specified repository. + * apply: This is executed for specified list of branches, currently main/master + From e1212ae912510521c887f67461b157f1d9b0f35b Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:05:46 +0530 Subject: [PATCH 18/21] Updated formatting of Jenkinsfile --- .../guardrails/folder-factory/Jenkinsfile | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/examples/guardrails/folder-factory/Jenkinsfile b/examples/guardrails/folder-factory/Jenkinsfile index 329ce22..dbc93e0 100644 --- a/examples/guardrails/folder-factory/Jenkinsfile +++ b/examples/guardrails/folder-factory/Jenkinsfile @@ -2,15 +2,14 @@ pipeline { agent any environment { - BUCKET_PATH = credentials('backend-path') - REPO_FULL_NAME = credentials('bucket-repo') - PROJECT_NAME = credentials('project-name') - GCP_PROJECT_NUMBER = credentials('project-id') - workload_identity_pool_id = credentials('wif_pool_id') - workload_identity_pool_provider_id = credentials('wif_pool_provider_id') - SERVICE_ACCOUNT_NAME = credentials('sa-name') - policy_file_path = credentials('policy_file_path') - + BUCKET_PATH = credentials('backend-path') + REPO_FULL_NAME = credentials('bucket-repo') + PROJECT_NAME = credentials('project-name') + GCP_PROJECT_NUMBER = credentials('project-id') + workload_identity_pool_id = credentials('wif_pool_id') + workload_identity_pool_provider_id = credentials('wif_pool_provider_id') + SERVICE_ACCOUNT_NAME = credentials('sa-name') + policy_file_path = credentials('policy_file_path') } options { skipDefaultCheckout(true) @@ -21,7 +20,7 @@ pipeline { cleanWs() } } - stage('WIF') { + stage('WIF') { steps { withCredentials([file(variable: 'ID_TOKEN_FILE', credentialsId: 'gcp')]) { writeFile file: "$WORKSPACE_TMP/creds.json", text: """ @@ -42,8 +41,7 @@ pipeline { sh ''' gcloud auth login --brief --cred-file=$WORKSPACE_TMP/creds.json ''' -} - +} } } stage('checkout') { @@ -57,36 +55,26 @@ pipeline { sh ''' cd guardrails/folder-factory terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=${REPO_FULL_NAME}" - terraform plan -input=false -out ffjenkins.tfplan - - - ''' - + terraform plan -input=false -out ffjenkins.tfplan + ''' } } - stage('Terraform Validate') { steps { - sh ''' cd guardrails/folder-factory terraform show -json "ffjenkins.tfplan" > "ffjenkins.json" gcloud source repos clone gcp-policies "${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" gcloud beta terraform vet "ffjenkins.json" --policy-library="${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" - - ''' - + ''' } } stage('Terraform Apply') { - steps { - + steps { sh ''' cd guardrails/folder-factory terraform apply -auto-approve - - ''' - + ''' } } } From a686801902c972f26dbe9f37c1eb426d35c1c178 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:05:57 +0530 Subject: [PATCH 19/21] Update Jenkinsfile --- examples/guardrails/folder-factory/Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/guardrails/folder-factory/Jenkinsfile b/examples/guardrails/folder-factory/Jenkinsfile index dbc93e0..f69e778 100644 --- a/examples/guardrails/folder-factory/Jenkinsfile +++ b/examples/guardrails/folder-factory/Jenkinsfile @@ -1,5 +1,4 @@ -pipeline { - +pipeline { agent any environment { BUCKET_PATH = credentials('backend-path') From 3aebc741465786bf441b7b3a19fb725d1c39c76b Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:07:09 +0530 Subject: [PATCH 20/21] Updated formatting of Jenkinsfile --- .../guardrails/project-factory/Jenkinsfile | 30 ++++++------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/examples/guardrails/project-factory/Jenkinsfile b/examples/guardrails/project-factory/Jenkinsfile index 8340813..5543a60 100644 --- a/examples/guardrails/project-factory/Jenkinsfile +++ b/examples/guardrails/project-factory/Jenkinsfile @@ -1,12 +1,9 @@ pipeline { - agent any environment { - BUCKET_PATH = credentials('backend-path') - policy_file_path = credentials('policy_file_path') - + BUCKET_PATH = credentials('backend-path') + policy_file_path = credentials('policy_file_path') } - options { skipDefaultCheckout(true) } @@ -21,40 +18,31 @@ pipeline { checkout scm } } - stage('Terraform Plan') { - steps { - + steps { sh ''' cd guardrails/project-factory terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=project-factory-staging-tfstate" -var-file="staging.tfvars" - terraform plan -var-file="staging.tfvars" -out pfjenkins.tfplan - - - ''' - + terraform plan -var-file="staging.tfvars" -out pfjenkins.tfplan + ''' } } stage('Terraform Validate') { - steps { - + steps { sh ''' cd guardrails/project-factory terraform show -json "pfjenkins.tfplan" > "ffjenkins.json" gcloud source repos clone gcp-policies "${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" gcloud beta terraform vet "pfjenkins.json" --policy-library="${policy_file_path}" --project="${GCP_PROJECT_NUMBER}" - ''' - + ''' } } stage('Terraform Apply') { - steps { - + steps { sh ''' cd guardrails/project-factory terraform apply -var-file="staging.tfvars" -auto-approve - ''' - + ''' } } } From ef75520fa609bf0723f19d343f19c668287159a2 Mon Sep 17 00:00:00 2001 From: saborni-d <116881883+saborni-d@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:09:10 +0530 Subject: [PATCH 21/21] Updated Formatting Jenkinsfile --- examples/guardrails/skunkworks/Jenkinsfile | 43 ++++++++-------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/examples/guardrails/skunkworks/Jenkinsfile b/examples/guardrails/skunkworks/Jenkinsfile index 0c6d91f..e2856a0 100644 --- a/examples/guardrails/skunkworks/Jenkinsfile +++ b/examples/guardrails/skunkworks/Jenkinsfile @@ -1,14 +1,13 @@ -pipeline { - +pipeline { agent any environment { - BUCKET_PATH = credentials('backend-path') - SKUNKWORK_PROJECT = credentials('staging-project') - SW_PROJECT_NUMBER = credentials('sw-project-number') - SW_SERVICE_ACCOUNT = credentials('sw-sa') - SW_workload_identity_pool_id = credentials('sw_wif_pool_id') - SW_workload_identity_pool_provider_id = credentials('sw_wif_pool_provider_id') - policy_file_path = credentials('policy_file_path') + BUCKET_PATH = credentials('backend-path') + SKUNKWORK_PROJECT = credentials('staging-project') + SW_PROJECT_NUMBER = credentials('sw-project-number') + SW_SERVICE_ACCOUNT = credentials('sw-sa') + SW_workload_identity_pool_id = credentials('sw_wif_pool_id') + SW_workload_identity_pool_provider_id = credentials('sw_wif_pool_provider_id') + policy_file_path = credentials('policy_file_path') } options { skipDefaultCheckout(true) @@ -43,47 +42,37 @@ pipeline { } } } - stage('checkout') { steps { checkout scm } } stage('Terraform Plan') { - steps { - + steps { sh ''' cd guardrails/skunkworks terraform init -backend-config="bucket=${BUCKET_PATH}" -backend-config="prefix=prod-skunkworks" - terraform plan -var="project=${SKUNKWORK_PROJECT}" -out swjenkins.tfplan - - - ''' - + terraform plan -var="project=${SKUNKWORK_PROJECT}" -out swjenkins.tfplan + ''' } } stage('Terraform Validate') { - steps { - + steps { sh ''' cd guardrails/skunkworks terraform show -json "swjenkins.tfplan" > "swjenkins.json" gcloud source repos clone gcp-policies "${policy_file_path}" --project="${SW_PROJECT_NUMBER}" gcloud beta terraform vet "swjenkins.json" --policy-library="${policy_file_path}" --project="${SW_PROJECT_NUMBER}" - ''' - + ''' } } stage('Terraform Apply') { - steps { - + steps { sh ''' cd guardrails/skunkworks terraform apply -var="project=${SKUNKWORK_PROJECT}" -auto-approve - ''' - + ''' } - } - + } } }