Skip to content

Commit

Permalink
feat: add instructions for deployment using GitLab pipelines (#1047)
Browse files Browse the repository at this point in the history
Co-authored-by: Renato Rudnicki <renatojr@ciandt.com>
Co-authored-by: Renato Rudnicki <77694243+renato-rudnicki@users.noreply.github.com>
Co-authored-by: Andrew Peabody <andrewpeabody@google.com>
Co-authored-by: Samir-Cit <samir@ciandt.com>
  • Loading branch information
5 people committed Jan 2, 2024
1 parent 87f3832 commit 0805878
Show file tree
Hide file tree
Showing 17 changed files with 1,626 additions and 21 deletions.
895 changes: 895 additions & 0 deletions 0-bootstrap/README-GitLab.md

Large diffs are not rendered by default.

17 changes: 15 additions & 2 deletions 0-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ See [troubleshooting](../docs/TROUBLESHOOTING.md) if you run into issues during

## Deploying with Jenkins

If you are using the `jenkins_bootstrap` sub-module, see
[README-Jenkins](https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/0-bootstrap/README-Jenkins.md)
If you are using the `jenkins_bootstrap` sub-module, see [README-Jenkins](./README-Jenkins.md)
for requirements and instructions on how to run the 0-bootstrap step. Using
Jenkins requires a few manual steps, including configuring connectivity with
your current Jenkins manager (controller) environment.
Expand All @@ -129,8 +128,22 @@ If you are deploying using [GitHub Actions](https://docs.github.com/en/actions),
for requirements and instructions on how to run the 0-bootstrap step.
Using GitHub Actions requires manual creation of the GitHub repositories used in each stage.

## Deploying with GitLab Pipelines

If you are deploying using [GitLab Pipelines](https://docs.gitlab.com/ee/ci/pipelines/), see [README-GitLab.md](./README-GitLab.md)
for requirements and instructions on how to run the 0-bootstrap step.
Using GitLab Pipeline requires manual creation of the GitLab projects (repositories) used in each stage.

## Deploying with Terraform Cloud

If you are deploying using [Terraform Cloud](https://developer.hashicorp.com/terraform/cloud-docs), see [README-Terraform-Cloud.md](./README-Terraform-Cloud.md)
for requirements and instructions on how to run the 0-bootstrap step.
Using Terraform Cloud requires manual creation of the GitHub repositories or GitLab projects used in each stage.

## Deploying with Cloud Build

**Note:** When deploying with cloud build is also possible to use a [script helper](../helpers/foundation-deployer/README.md) to do the deploy.

1. Clone [terraform-example-foundation](https://github.com/terraform-google-modules/terraform-example-foundation) into your local environment and navigate to the `0-bootstrap` folder.

```bash
Expand Down
175 changes: 175 additions & 0 deletions 0-bootstrap/gitlab.tf.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/**
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

locals {
cicd_project_id = module.gitlab_cicd.project_id

wif_sa_cicd_project = {
"bootstrap" = [
"roles/iam.workloadIdentityPoolAdmin",
],
}

gl_config = {
"bootstrap" = var.gl_repos.bootstrap,
"org" = var.gl_repos.organization,
"env" = var.gl_repos.environments,
"net" = var.gl_repos.networks,
"proj" = var.gl_repos.projects,
}

gl_branch_protection_envs = {
"env" = var.gl_repos.environments,
"net" = var.gl_repos.networks,
"proj" = var.gl_repos.projects,
}

sa_mapping = {
for k, v in local.gl_config : k => {
sa_name = google_service_account.terraform-env-sa[k].name
attribute = "attribute.project_path/${var.gl_repos.owner}/${v}"
}
}

common_vars = {
"PROJECT_ID" : module.gitlab_cicd.project_id,
"CICD_RUNNER_REPO" : var.gl_repos.cicd_runner,
"WIF_PROVIDER_NAME" : module.gitlab_oidc.provider_name,
"TF_BACKEND" : module.seed_bootstrap.gcs_bucket_tfstate,
"TF_VAR_gitlab_token" : var.gitlab_token,
}

vars_list = flatten([
for k, v in local.gl_config : [
for name, value in local.common_vars : {
config = k
name = name
value = value
repository = v
}
]
])

sa_vars = [for k, v in local.gl_config : {
config = k
name = "SERVICE_ACCOUNT_EMAIL"
value = google_service_account.terraform-env-sa[k].email
repository = v
}
]

gl_vars = { for v in concat(local.sa_vars, local.vars_list) : "${v.config}.${v.name}" => v }

}

provider "gitlab" {
token = var.gitlab_token
}

module "gitlab_cicd" {
source = "terraform-google-modules/project-factory/google"
version = "~> 12.0"

name = "${var.project_prefix}-b-cicd-wif-gl"
random_project_id = true
org_id = var.org_id
folder_id = google_folder.bootstrap.id
billing_account = var.billing_account
activate_apis = [
"compute.googleapis.com",
"admin.googleapis.com",
"iam.googleapis.com",
"billingbudgets.googleapis.com",
"cloudbilling.googleapis.com",
"serviceusage.googleapis.com",
"cloudresourcemanager.googleapis.com",
"iamcredentials.googleapis.com",
"sts.googleapis.com",
"dns.googleapis.com",
"secretmanager.googleapis.com",

]
}

module "gitlab_oidc" {
source = "./modules/gitlab-oidc"

project_id = module.gitlab_cicd.project_id
pool_id = "foundation-pool"
provider_id = "foundation-gl-provider"
sa_mapping = local.sa_mapping
}

resource "gitlab_project_variable" "variables" {
for_each = local.gl_vars

project = "${var.gl_repos.owner}/${each.value.repository}"
key = each.value.name
value = each.value.value
protected = false
masked = true
}

resource "gitlab_branch_protection" "image" {
project = "${var.gl_repos.owner}/${var.gl_repos.cicd_runner}"
branch = "image"
}

resource "gitlab_branch_protection" "plan" {
for_each = local.gl_config

project = "${var.gl_repos.owner}/${each.value}"
branch = "plan"
}

resource "gitlab_branch_protection" "production" {
for_each = local.gl_config

project = "${var.gl_repos.owner}/${each.value}"
branch = "production"
}

resource "gitlab_branch_protection" "non_production" {
for_each = local.gl_branch_protection_envs

project = "${var.gl_repos.owner}/${each.value}"
branch = "non-production"
}

resource "gitlab_branch_protection" "development" {
for_each = local.gl_branch_protection_envs

project = "${var.gl_repos.owner}/${each.value}"
branch = "development"
}

module "cicd_project_wif_iam_member" {
source = "./modules/parent-iam-member"
for_each = local.wif_sa_cicd_project

member = "serviceAccount:${google_service_account.terraform-env-sa[each.key].email}"
parent_type = "project"
parent_id = local.cicd_project_id
roles = each.value
}

resource "google_service_account_iam_member" "self_impersonate" {
for_each = local.granular_sa

service_account_id = google_service_account.terraform-env-sa[each.key].id
role = "roles/iam.serviceAccountTokenCreator"
member = "serviceAccount:${google_service_account.terraform-env-sa[each.key].email}"
}
51 changes: 51 additions & 0 deletions 0-bootstrap/modules/gitlab-oidc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

resource "google_project_service" "services" {
project = var.project_id
count = length(var.service_list)
service = var.service_list[count.index]
disable_on_destroy = false
}

resource "google_iam_workload_identity_pool" "main" {
project = var.project_id
workload_identity_pool_id = var.pool_id
display_name = var.pool_display_name
description = var.pool_description
disabled = false
}

resource "google_iam_workload_identity_pool_provider" "main" {
project = var.project_id
workload_identity_pool_id = google_iam_workload_identity_pool.main.workload_identity_pool_id
workload_identity_pool_provider_id = var.provider_id
display_name = var.provider_display_name
description = var.provider_description
attribute_condition = var.attribute_condition
attribute_mapping = var.attribute_mapping
oidc {
allowed_audiences = var.allowed_audiences
issuer_uri = var.issuer_uri
}
}

resource "google_service_account_iam_member" "wif-sa" {
for_each = var.sa_mapping
service_account_id = each.value.sa_name
role = "roles/iam.workloadIdentityUser"
member = "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.main.name}/${each.value.attribute}"
}
25 changes: 25 additions & 0 deletions 0-bootstrap/modules/gitlab-oidc/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "pool_name" {
description = "Pool name"
value = google_iam_workload_identity_pool.main.name
}

output "provider_name" {
description = "Provider name"
value = google_iam_workload_identity_pool_provider.main.name
}

0 comments on commit 0805878

Please sign in to comment.