Skip to content

Commit

Permalink
feat: add instructions for deployment using GitHub Actions (#955)
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-cit committed Nov 28, 2023
1 parent a7ce17e commit 56450bd
Show file tree
Hide file tree
Showing 23 changed files with 1,449 additions and 78 deletions.
936 changes: 936 additions & 0 deletions 0-bootstrap/README-GitHub.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions 0-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ 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.

## Deploying with GitHub Actions

If you are deploying using [GitHub Actions](https://docs.github.com/en/actions), see [README-GitHub.md](./README-GitHub.md)
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 Cloud Build

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.
Expand Down
108 changes: 108 additions & 0 deletions 0-bootstrap/github.tf.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/**
* Copyright 2022 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.
*/


provider "github" {
owner = var.gh_repos.owner
token = var.gh_token
}

locals {
cicd_project_id = module.gh_cicd.project_id

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

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

commom_secrets = {
"PROJECT_ID" : module.gh_cicd.project_id,
"WIF_PROVIDER_NAME" : module.gh_oidc.provider_name,
"TF_BACKEND" : module.seed_bootstrap.gcs_bucket_tfstate,
"TF_VAR_gh_token": var.gh_token,
}

secrets_list = flatten([
for k, v in local.gh_config : [
for secret, plaintext in local.commom_secrets : {
config = k
secret_name = secret
plaintext_value = plaintext
repository = v
}
]
])

sa_secrets = [for k, v in local.gh_config : {
config = k
secret_name = "SERVICE_ACCOUNT_EMAIL"
plaintext_value = google_service_account.terraform-env-sa[k].email
repository = v
}
]

gh_secrets = { for v in concat(local.sa_secrets, local.secrets_list) : "${v.config}.${v.secret_name}" => v }

}

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

name = "${var.project_prefix}-b-cicd-wif-gh"
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",
]
}

module "gh_oidc" {
source = "terraform-google-modules/github-actions-runners/google//modules/gh-oidc"
version = "~> 3.1"

project_id = module.gh_cicd.project_id
pool_id = "foundation-pool"
provider_id = "foundation-gh-provider"
sa_mapping = local.sa_mapping
}

resource "github_actions_secret" "secrets" {
for_each = local.gh_secrets

repository = each.value.repository
secret_name = each.value.secret_name
plaintext_value = each.value.plaintext_value
}
17 changes: 15 additions & 2 deletions 0-bootstrap/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ output "optional_groups" {
/* ----------------------------------------
Specific to cloudbuild_module
---------------------------------------- */
# Comment-out the cloudbuild_bootstrap module and its outputs if you want to use Jenkins instead of Cloud Build
# Comment-out the cloudbuild_bootstrap module and its outputs if you want to use GitHub Actions or Jenkins instead of Cloud Build
output "cloudbuild_project_id" {
description = "Project where Cloud Build configuration and terraform container image will reside."
value = module.tf_source.cloudbuild_project_id
Expand Down Expand Up @@ -126,7 +126,6 @@ output "csr_repos" {
output "cloud_build_private_worker_pool_id" {
description = "ID of the Cloud Build private worker pool."
value = module.tf_private_pool.private_worker_pool_id

}

output "cloud_build_worker_range_id" {
Expand All @@ -144,6 +143,20 @@ output "cloud_build_peered_network_id" {
value = module.tf_private_pool.peered_network_id
}

/* ----------------------------------------
Specific to github_bootstrap
---------------------------------------- */
# Un-comment github_bootstrap and its outputs if you want to use GitHub Actions instead of Cloud Build
# output "cicd_project_id" {
# description = "Project where the CI/CD infrastructure for GitHub Action resides."
# value = module.gh_cicd.project_id
# }

# output "projects_gcs_bucket_tfstate" {
# description = "Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project."
# value = module.seed_bootstrap.gcs_bucket_tfstate
# }

/* ----------------------------------------
Specific to jenkins_bootstrap module
---------------------------------------- */
Expand Down
1 change: 1 addition & 0 deletions 0-bootstrap/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ locals {
"roles/cloudscheduler.admin",
"roles/resourcemanager.projectDeleter",
"roles/dns.admin",
"roles/iam.workloadIdentityPoolAdmin",
],
}

Expand Down
136 changes: 78 additions & 58 deletions 0-bootstrap/terraform.example.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -28,67 +28,87 @@ group_billing_admins = "REPLACE_ME"

default_region = "us-central1"

// Optional - for an organization with existing projects or for development/validation.
// Uncomment this variable to place all the example foundation resources under
// the provided folder instead of the root organization.
// The variable value is the numeric folder ID
// The folder must already exist.
//parent_folder = "01234567890"
# Optional - for an organization with existing projects or for development/validation.
# Uncomment this variable to place all the example foundation resources under
# the provided folder instead of the root organization.
# The variable value is the numeric folder ID
# The folder must already exist.
# parent_folder = "01234567890"

// Optional - for enabling the automatic groups creation, uncoment the groups
// variable and update the values with the desired group names
//groups = {
// create_groups = true,
// billing_project = "billing-project",
// required_groups = {
// group_org_admins = "group_org_admins_local_test@example.com"
// group_billing_admins = "group_billing_admins_local_test@example.com"
// billing_data_users = "billing_data_users_local_test@example.com"
// audit_data_users = "audit_data_users_local_test@example.com"
// monitoring_workspace_users = "monitoring_workspace_users_local_test@example.com"
// },
// optional_groups = {
// gcp_platform_viewer = "gcp_platform_viewer_local_test@example.com"
// gcp_security_reviewer = "gcp_security_reviewer_local_test@example.com"
// gcp_network_viewer = "gcp_network_viewer_local_test@example.com"
// gcp_scc_admin = "gcp_scc_admin_local_test@example.com"
// gcp_global_secrets_admin = "gcp_global_secrets_admin_local_test@example.com"
// gcp_audit_viewer = "gcp_audit_viewer_local_test@example.com"
// }
//}
//
# Optional - for enabling the automatic groups creation, uncoment the groups
# variable and update the values with the desired group names
# groups = {
# create_groups = true,
# billing_project = "billing-project",
# required_groups = {
# group_org_admins = "group_org_admins_local_test@example.com"
# group_billing_admins = "group_billing_admins_local_test@example.com"
# billing_data_users = "billing_data_users_local_test@example.com"
# audit_data_users = "audit_data_users_local_test@example.com"
# monitoring_workspace_users = "monitoring_workspace_users_local_test@example.com"
# },
# optional_groups = {
# gcp_platform_viewer = "gcp_platform_viewer_local_test@example.com"
# gcp_security_reviewer = "gcp_security_reviewer_local_test@example.com"
# gcp_network_viewer = "gcp_network_viewer_local_test@example.com"
# gcp_scc_admin = "gcp_scc_admin_local_test@example.com"
# gcp_global_secrets_admin = "gcp_global_secrets_admin_local_test@example.com"
# gcp_audit_viewer = "gcp_audit_viewer_local_test@example.com"
# }
# }
#


/* ----------------------------------------
Specific to github_bootstrap
---------------------------------------- */
# Un-comment github_bootstrap and its outputs if you want to use GitHub Actions instead of Cloud Build
# gh_repos = {
# owner = "YOUR-GITHUB-USER-OR-ORGANIZATION",
# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY",
# organization = "YOUR-ORGANIZATION-REPOSITORY",
# environments = "YOUR-ENVIRONMENTS-REPOSITORY",
# networks = "YOUR-NETWORKS-REPOSITORY",
# projects = "YOUR-PROJECTS-REPOSITORY",
# }
#
# to prevent saving the `gh_token` in plain text in this file,
# export the GitHub fine grained access token in the command line
# as an environment variable before running terraform.
# Run the following commnad in your shell:
# export TF_VAR_gh_token="YOUR-FINE-GRAINED-ACCESS-TOKEN"


/* ----------------------------------------
Specific to jenkins_bootstrap module
---------------------------------------- */
// Un-comment the jenkins_bootstrap module and its outputs if you want to use Jenkins instead of Cloud Build
//jenkins_agent_gce_subnetwork_cidr_range = "172.16.1.0/24"
//
//jenkins_agent_gce_private_ip_address = "172.16.1.6"
//
//jenkins_agent_gce_ssh_pub_key = "ssh-rsa [KEY_VALUE] [USERNAME]"
//
//jenkins_agent_sa_email = "jenkins-agent-gce" # service_account_prefix will be added
//
//jenkins_controller_subnetwork_cidr_range = ["10.1.0.6/32"]
//
//nat_bgp_asn = "64514"
//
//vpn_shared_secret = "shared_secret"
//
//on_prem_vpn_public_ip_address = ""
//
//on_prem_vpn_public_ip_address2 = ""
//
//router_asn = "64515"
//
//bgp_peer_asn = "64513"
//
//tunnel0_bgp_peer_address = "169.254.1.1"
//
//tunnel0_bgp_session_range = "169.254.1.2/30"
//
//tunnel1_bgp_peer_address = "169.254.2.1"
//
//tunnel1_bgp_session_range = "169.254.2.2/30"
# Un-comment the jenkins_bootstrap module and its outputs if you want to use Jenkins instead of Cloud Build
# jenkins_agent_gce_subnetwork_cidr_range = "172.16.1.0/24"
#
# jenkins_agent_gce_private_ip_address = "172.16.1.6"
#
# jenkins_agent_gce_ssh_pub_key = "ssh-rsa [KEY_VALUE] [USERNAME]"
#
# jenkins_agent_sa_email = "jenkins-agent-gce" # service_account_prefix will be added
#
# jenkins_controller_subnetwork_cidr_range = ["10.1.0.6/32"]
#
# nat_bgp_asn = "64514"
#
# vpn_shared_secret = "shared_secret"
#
# on_prem_vpn_public_ip_address = ""
#
# on_prem_vpn_public_ip_address2 = ""
#
# router_asn = "64515"
#
# bgp_peer_asn = "64513"
#
# tunnel0_bgp_peer_address = "169.254.1.1"
#
# tunnel0_bgp_session_range = "169.254.1.2/30"
#
# tunnel1_bgp_peer_address = "169.254.2.1"
#
# tunnel1_bgp_session_range = "169.254.2.2/30"
31 changes: 31 additions & 0 deletions 0-bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,37 @@ variable "initial_group_config" {
default = "WITH_INITIAL_OWNER"
}

/* ----------------------------------------
Specific to github_bootstrap
---------------------------------------- */

# Un-comment github_bootstrap and its outputs if you want to use GitHub Actions instead of Cloud Build
# variable "gh_repos" {
# description = <<EOT
# Configuration for the GitHub Repositories to be used to deploy the Terraform Example Foundation stages.
# owner: The owner of the repositories. An user or an organization.
# bootstrap: The repository to host the code of the bootstrap stage.
# organization: The repository to host the code of the organization stage.
# environments: The repository to host the code of the environments stage.
# networks: The repository to host the code of the networks stage.
# projects: The repository to host the code of the projects stage.
# EOT
# type = object({
# owner = string,
# bootstrap = string,
# organization = string,
# environments = string,
# networks = string,
# projects = string,
# })
# }

# variable "gh_token" {
# description = "A fine-grained personal access token for the user or organization. See https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token#creating-a-fine-grained-personal-access-token"
# type = string
# sensitive = true
# }

/* ----------------------------------------
Specific to jenkins_bootstrap module
---------------------------------------- */
Expand Down
6 changes: 6 additions & 0 deletions 0-bootstrap/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ terraform {
source = "hashicorp/google"
version = ">= 3.50, != 4.31.0"
}

// Un-comment github required_providers when using GitHub Actions
# github = {
# source = "integrations/github"
# version = "5.34.0"
# }
}

provider_meta "google" {
Expand Down
4 changes: 4 additions & 0 deletions 1-org/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ If you received a `PERMISSION_DENIED` error while running the `gcloud access-con

See `0-bootstrap` [README-Jenkins.md](../0-bootstrap/README-Jenkins.md#deploying-step-1-org).

### Deploying with GitHub Actions

See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-step-1-org).

### Running Terraform locally

1. The next instructions assume that you are at the same level of the `terraform-example-foundation` folder.
Expand Down
6 changes: 5 additions & 1 deletion 2-environments/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get

### Deploying with Jenkins

See `0-bootstrap` [README-Jenkins.md](../0-bootstrap/README-Jenkins.md#deploying-step-2-environments)
See `0-bootstrap` [README-Jenkins.md](../0-bootstrap/README-Jenkins.md#deploying-step-2-environments).

### Deploying with GitHub Actions

See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-step-2-environments).

### Run Terraform locally

Expand Down

0 comments on commit 56450bd

Please sign in to comment.