Skip to content

Commit

Permalink
feat: Add GitLab support for IM module (#281)
Browse files Browse the repository at this point in the history
  • Loading branch information
josephdt12 authored Mar 28, 2024
1 parent 7fb8b70 commit a9858a9
Show file tree
Hide file tree
Showing 23 changed files with 883 additions and 70 deletions.
27 changes: 24 additions & 3 deletions build/int.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ steps:
- 'TF_VAR_billing_account=$_BILLING_ACCOUNT'
- 'TF_VAR_group_org_admins=test-gcp-org-admins@test.blueprints.joonix.net'
- 'TF_VAR_group_billing_admins=test-gcp-billing-admins@test.blueprints.joonix.net'
secretEnv: ['IM_GITHUB_PAT']
secretEnv: ['IM_GITHUB_PAT', 'IM_GITLAB_PAT']
- id: init-all
waitFor:
- prepare
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run all --stage init --verbose']
secretEnv: ['IM_GITHUB_PAT']
secretEnv: ['IM_GITHUB_PAT', 'IM_GITLAB_PAT']
- id: create-all
waitFor:
- init-all
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do create']
secretEnv: ['IM_GITHUB_PAT']
secretEnv: ['IM_GITHUB_PAT', 'IM_GITLAB_PAT']
- id: converge-simple
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'source /usr/local/bin/task_helper_functions.sh && kitchen_do converge simple-default']
Expand Down Expand Up @@ -154,10 +154,31 @@ steps:
args: ['/bin/bash', '-c', 'cft test run TestIMCloudBuildWorkspaceGitHub --stage teardown --verbose']
secretEnv: ['IM_GITHUB_PAT']

- id: apply-imworkspace-gitlab
waitFor:
- create-all
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestIMCloudBuildWorkspaceGitLab --stage apply --verbose']
secretEnv: ['IM_GITLAB_PAT']
- id: verify-imworkspace-gitlab
waitFor:
- apply-imworkspace-gitlab
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestIMCloudBuildWorkspaceGitLab --stage verify --verbose']
secretEnv: ['IM_GITLAB_PAT']
- id: teardown-imworkspace-gitlab
waitFor:
- verify-imworkspace-gitlab
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
args: ['/bin/bash', '-c', 'cft test run TestIMCloudBuildWorkspaceGitLab --stage teardown --verbose']
secretEnv: ['IM_GITLAB_PAT']

availableSecrets:
secretManager:
- versionName: $_IM_GITHUB_PAT_SECRET_ID/versions/latest
env: 'IM_GITHUB_PAT'
- versionName: $_IM_GITLAB_PAT_SECRET_ID/versions/latest
env: 'IM_GITLAB_PAT'
tags:
- 'ci'
- 'integration'
Expand Down
26 changes: 26 additions & 0 deletions examples/im_cloudbuild_workspace_gitlab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
## Overview

This example demonstrates the simplest usage of the [im_cloudbuild_workspace](../../modules/im_cloudbuild_workspace/) module.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| im\_gitlab\_pat | GitLab personal access token. | `string` | n/a | yes |
| project\_id | The ID of the project in which to provision resources. | `string` | n/a | yes |
| repository\_url | The URI of the repo where the Terraform configs are stored. | `string` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| cloudbuild\_apply\_trigger\_id | Trigger used for running IM apply |
| cloudbuild\_preview\_trigger\_id | Trigger used for creating IM previews |
| cloudbuild\_sa | Service account used by the Cloud Build triggers |
| gitlab\_api\_secret\_id | The secret ID for the secret containing the GitLab api access token. |
| gitlab\_read\_api\_secret\_id | The secret ID for the secret containing the GitLab read api access token. |
| infra\_manager\_sa | Service account used by Infrastructure Manager |
| project\_id | n/a |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
30 changes: 30 additions & 0 deletions examples/im_cloudbuild_workspace_gitlab/apis.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright 2024 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.
*/

module "enabled_google_apis" {
source = "terraform-google-modules/project-factory/google//modules/project_services"
version = "~> 14.0"

project_id = var.project_id
disable_services_on_destroy = false

activate_apis = [
"iam.googleapis.com",
"compute.googleapis.com",
"cloudbuild.googleapis.com",
"config.googleapis.com",
]
}
32 changes: 32 additions & 0 deletions examples/im_cloudbuild_workspace_gitlab/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright 2024 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.
*/

module "im_workspace" {
source = "../../modules/im_cloudbuild_workspace"

project_id = var.project_id
deployment_id = "im-example-gitlab-deployment"

tf_repo_type = "GITLAB"
im_deployment_repo_uri = var.repository_url
im_deployment_ref = "main"
im_tf_variables = "project_id=${var.project_id}"
infra_manager_sa_roles = ["roles/compute.networkAdmin"]
tf_version = "1.2.3"

gitlab_api_access_token = var.im_gitlab_pat
gitlab_read_api_access_token = var.im_gitlab_pat
}
51 changes: 51 additions & 0 deletions examples/im_cloudbuild_workspace_gitlab/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Copyright 2024 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 "project_id" {
value = var.project_id
}

output "cloudbuild_preview_trigger_id" {
description = "Trigger used for creating IM previews"
value = module.im_workspace.cloudbuild_preview_trigger_id
}

output "cloudbuild_apply_trigger_id" {
description = "Trigger used for running IM apply"
value = module.im_workspace.cloudbuild_apply_trigger_id
}

output "cloudbuild_sa" {
description = "Service account used by the Cloud Build triggers"
value = module.im_workspace.cloudbuild_sa
}

output "infra_manager_sa" {
description = "Service account used by Infrastructure Manager"
value = module.im_workspace.infra_manager_sa
}

output "gitlab_api_secret_id" {
description = "The secret ID for the secret containing the GitLab api access token."
value = module.im_workspace.gitlab_api_secret_id
sensitive = true
}

output "gitlab_read_api_secret_id" {
description = "The secret ID for the secret containing the GitLab read api access token."
value = module.im_workspace.gitlab_read_api_secret_id
sensitive = true
}
31 changes: 31 additions & 0 deletions examples/im_cloudbuild_workspace_gitlab/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright 2024 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.
*/

variable "project_id" {
description = "The ID of the project in which to provision resources."
type = string
}

variable "repository_url" {
description = "The URI of the repo where the Terraform configs are stored."
type = string
}

variable "im_gitlab_pat" {
description = "GitLab personal access token."
type = string
sensitive = true
}
11 changes: 10 additions & 1 deletion modules/im_cloudbuild_workspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This IM Cloud Build Workspace blueprint creates an opinionated workflow for actuating Terraform
resources on Cloud Build using Infrastructure Manager. A set of Cloud Build triggers manage
preview and apply operations on a configuration stored in a GitHub repository.
preview and apply operations on a configuration stored in a GitHub or GitLab repository.
The Cloud Build triggers use a per-workspace Service Account which can be configured with a
minimal set of permissions for calling Infrastructure Manager. Infrastructure Manager uses a separate
service account with a set of permissions required by the given Terraform configuration.
Expand Down Expand Up @@ -56,6 +56,13 @@ for actuating resources.
| github\_pat\_secret | The secret ID within Secret Manager for an existing personal access token for GitHub. | `string` | `""` | no |
| github\_pat\_secret\_version | The secret version ID or alias for the GitHub PAT secret. Uses the latest if not provided. | `string` | `""` | no |
| github\_personal\_access\_token | Personal access token for a GitHub repository. If provided, creates a secret within Secret Manager. | `string` | `""` | no |
| gitlab\_api\_access\_token | GitLab personal access token with api scope. If provided, creates a secret within Secret Manager. | `string` | `""` | no |
| gitlab\_api\_access\_token\_secret | The secret ID within Secret Manager for an existing api access token for GitLab. | `string` | `""` | no |
| gitlab\_api\_access\_token\_secret\_version | The secret version ID or alias for the GitLab api token secret. Uses the latest if not provided. | `string` | `""` | no |
| gitlab\_host\_uri | The URI of the GitLab Enterprise host this connection is for. Defaults to non-enterprise. | `string` | `""` | no |
| gitlab\_read\_api\_access\_token | GitLab personal access token with read\_api scope. If provided, creates a secret within Secret Manager. | `string` | `""` | no |
| gitlab\_read\_api\_access\_token\_secret | The secret ID within Secret Manager for an existing read\_api access token for GitLab. | `string` | `""` | no |
| gitlab\_read\_api\_access\_token\_secret\_version | The secret version ID or alias for the GitLab read\_api token secret. Uses the latest if not provided. | `string` | `""` | no |
| host\_connection\_name | Name for the VCS connection. Generated if not given. | `string` | `""` | no |
| im\_deployment\_ref | Git branch or ref configured to run infra-manager apply. All other refs will run plan by default. | `string` | n/a | yes |
| im\_deployment\_repo\_dir | The directory inside the repo where the Terraform root config is located. If empty defaults to repo root. | `string` | `""` | no |
Expand All @@ -81,6 +88,8 @@ for actuating resources.
| cloudbuild\_preview\_trigger\_id | Trigger used for running infra-manager preview |
| cloudbuild\_sa | Service account used by the Cloud Build triggers |
| github\_secret\_id | The secret ID for the GitHub secret containing the personal access token. |
| gitlab\_api\_secret\_id | The secret ID for the GitLab secret containing the token with api access. |
| gitlab\_read\_api\_secret\_id | The secret ID for the GitLab secret containing the token with read\_api access. |
| infra\_manager\_sa | Service account used by Infrastructure Manager |
| repo\_connection\_id | The Cloud Build repository connection ID |
| vcs\_connection\_id | The Cloud Build VCS host connection ID |
Expand Down
9 changes: 8 additions & 1 deletion modules/im_cloudbuild_workspace/cb.tf
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,20 @@ resource "google_cloudbuild_trigger" "triggers" {
repository_event_config {
repository = google_cloudbuildv2_repository.repository_connection.id
dynamic "pull_request" {
for_each = each.key == "preview" ? [1] : []
for_each = (each.key == "preview") && (local.is_gh_repo) ? [1] : []
content {
branch = var.im_deployment_ref
invert_regex = false
comment_control = var.pull_request_comment_control
}
}
dynamic "push" {
for_each = (each.key == "preview") && (local.is_gl_repo) ? [1] : []
content {
branch = var.im_deployment_ref
invert_regex = true
}
}
dynamic "push" {
for_each = each.key == "apply" ? [1] : []
content {
Expand Down
5 changes: 3 additions & 2 deletions modules/im_cloudbuild_workspace/github.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ locals {
existing_github_secret_version = local.is_gh_repo && var.github_pat_secret != "" ? data.google_secret_manager_secret_version.existing_github_pat_secret_version[0].name : ""
github_secret_version_id = local.create_github_secret ? google_secret_manager_secret_version.github_token_secret_version[0].name : local.existing_github_secret_version

secret_id = var.github_personal_access_token != "" ? google_secret_manager_secret.github_token_secret[0].id : data.google_secret_manager_secret.existing_github_pat_secret[0].secret_id
github_secret_id = local.is_gh_repo ? (local.create_github_secret ? google_secret_manager_secret.github_token_secret[0].id : data.google_secret_manager_secret.existing_github_pat_secret[0].secret_id) : ""
}

// Create a secret containing the personal access token and grant permissions to the Service Agent.
Expand Down Expand Up @@ -63,7 +63,8 @@ data "google_secret_manager_secret_version" "existing_github_pat_secret_version"
}

resource "google_secret_manager_secret_iam_member" "github_token_iam_member" {
secret_id = local.secret_id
count = local.is_gh_repo ? 1 : 0
secret_id = local.github_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:service-${data.google_project.project.number}@gcp-sa-cloudbuild.iam.gserviceaccount.com"
}
Loading

0 comments on commit a9858a9

Please sign in to comment.