├── test ├── .gitignore ├── setup │ ├── .gitignore │ ├── versions.tf │ ├── outputs.tf │ ├── variables.tf │ ├── iam.tf │ └── main.tf └── integration │ ├── discover_test.go │ ├── tfc-agent-mig-vm-packer │ └── tfc_agent_mig_vm_packer_test.go │ ├── tfc-agent-mig-vm-simple │ └── tfc_agent_mig_vm_simple_test.go │ ├── tfc-agent-mig-container-vm-simple │ └── tfc_agent_mig_container_vm_simple_test.go │ ├── tfc-agent-gke-custom │ └── tfc_agent_gke_custom_test.go │ ├── tfc-agent-gke-simple │ └── tfc_agent_gke_simple_test.go │ ├── oidc-simple │ └── oidc_simple_test.go │ └── go.mod ├── examples ├── tfc-agent-gke-custom │ ├── .dockerignore │ ├── .gcloudignore │ ├── providers.tf │ ├── cloudbuild.yaml │ ├── Dockerfile │ ├── variables.tf │ ├── outputs.tf │ ├── main.tf │ └── README.md ├── tfc-agent-mig-vm-packer │ ├── .gcloudignore │ ├── cloudbuild.yaml │ ├── outputs.tf │ ├── startup.sh │ ├── variables.tf │ ├── main.tf │ ├── README.md │ └── packer │ │ └── packer.pkr.hcl ├── tfc-agent-gke-simple │ ├── providers.tf │ ├── variables.tf │ ├── outputs.tf │ ├── README.md │ └── main.tf ├── oidc-simple │ ├── outputs.tf │ ├── README.md │ ├── variables.tf │ └── main.tf ├── tfc-agent-mig-vm-simple │ ├── outputs.tf │ ├── variables.tf │ ├── README.md │ └── main.tf └── tfc-agent-mig-container-vm-simple │ ├── outputs.tf │ ├── variables.tf │ ├── main.tf │ └── README.md ├── assets └── icon.png ├── .github ├── renovate.json ├── release-please.yml ├── trusted-contribution.yml └── workflows │ ├── stale.yml │ └── lint.yaml ├── .dockerignore ├── SECURITY.md ├── CODEOWNERS ├── modules ├── tfc-oidc │ ├── outputs.tf │ ├── versions.tf │ ├── main.tf │ ├── variables.tf │ └── README.md ├── tfc-agent-mig-vm │ ├── versions.tf │ ├── outputs.tf │ ├── scripts │ │ └── startup.sh │ ├── README.md │ ├── variables.tf │ └── main.tf ├── tfc-agent-mig-container-vm │ ├── versions.tf │ ├── outputs.tf │ ├── README.md │ ├── variables.tf │ └── main.tf └── tfc-agent-gke │ ├── versions.tf │ ├── outputs.tf │ ├── README.md │ ├── variables.tf │ └── main.tf ├── .gitignore ├── Makefile ├── CHANGELOG.md ├── CONTRIBUTING.md ├── README.md └── LICENSE /test/.gitignore: -------------------------------------------------------------------------------- 1 | source.sh 2 | -------------------------------------------------------------------------------- /test/setup/.gitignore: -------------------------------------------------------------------------------- 1 | terraform.tfvars 2 | source.sh 3 | outputs.env 4 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/.dockerignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | *.tf* 3 | *.tfvars 4 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-packer/.gcloudignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | *.tfstate 3 | *.tf 4 | *.out 5 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/.gcloudignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | *.tfstate 3 | *.tf 4 | *.out 5 | sample-manifests 6 | -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GoogleCloudPlatform/terraform-google-tf-cloud-agents/HEAD/assets/icon.png -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>GoogleCloudPlatform/cloud-foundation-toolkit//infra/terraform/test-org/github/resources/renovate"] 4 | } 5 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .terraform 3 | .terraform.d 4 | .kitchen 5 | terraform.tfstate.d 6 | test/fixtures/*/.terraform 7 | test/fixtures/*/terraform.tfstate.d 8 | examples/.kitchen 9 | examples/*/.terraform 10 | examples/*/terraform.tfstate.d 11 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | To report a security issue, please use http://g.co/vulnz. We use 2 | http://g.co/vulnz for our intake, and do coordination and disclosure here on 3 | GitHub (including using GitHub Security Advisory). The Google Security Team will 4 | respond within 5 working days of your report on g.co/vulnz. 5 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # NOTE: This file is automatically generated from values at: 2 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/org/locals.tf 3 | 4 | * @GoogleCloudPlatform/blueprint-solutions 5 | 6 | # NOTE: GitHub CODEOWNERS locations: 7 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-and-branch-protection 8 | 9 | CODEOWNERS @GoogleCloudPlatform/blueprint-solutions 10 | .github/CODEOWNERS @GoogleCloudPlatform/blueprint-solutions 11 | docs/CODEOWNERS @GoogleCloudPlatform/blueprint-solutions 12 | 13 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | releaseType: terraform-module 16 | handleGHRelease: true 17 | primaryBranch: main 18 | bumpMinorPreMajor: true 19 | -------------------------------------------------------------------------------- /test/integration/discover_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package test 16 | 17 | import ( 18 | "testing" 19 | 20 | "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" 21 | ) 22 | 23 | func TestAll(t *testing.T) { 24 | tft.AutoDiscoverAndTest(t) 25 | } 26 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/providers.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | provider "kubernetes" { 18 | host = "https://${module.tfc_agent_gke.kubernetes_endpoint}" 19 | token = data.google_client_config.default.access_token 20 | cluster_ca_certificate = base64decode(module.tfc_agent_gke.ca_certificate) 21 | } 22 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-simple/providers.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | provider "kubernetes" { 18 | host = "https://${module.tfc_agent_gke.kubernetes_endpoint}" 19 | token = data.google_client_config.default.access_token 20 | cluster_ca_certificate = base64decode(module.tfc_agent_gke.ca_certificate) 21 | } 22 | -------------------------------------------------------------------------------- /modules/tfc-oidc/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "pool_name" { 18 | description = "Pool name" 19 | value = google_iam_workload_identity_pool.tfc_pool.name 20 | } 21 | 22 | output "provider_name" { 23 | description = "Provider name" 24 | value = google_iam_workload_identity_pool_provider.tfc_provider.name 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX leaves these everywhere on SMB shares 2 | ._* 3 | 4 | # OSX trash 5 | .DS_Store 6 | 7 | # Python 8 | *.pyc 9 | 10 | # Emacs save files 11 | *~ 12 | \#*\# 13 | .\#* 14 | 15 | # Vim-related files 16 | [._]*.s[a-w][a-z] 17 | [._]s[a-w][a-z] 18 | *.un~ 19 | Session.vim 20 | .netrwhist 21 | 22 | ### https://raw.github.com/github/gitignore/90f149de451a5433aebd94d02d11b0e28843a1af/Terraform.gitignore 23 | 24 | # Local .terraform directories 25 | **/.terraform/* 26 | 27 | # .tfstate files 28 | *.tfstate 29 | *.tfstate.* 30 | 31 | # Crash log files 32 | crash.log 33 | 34 | # Kitchen files 35 | **/inspec.lock 36 | **/.kitchen 37 | **/kitchen.local.yml 38 | **/Gemfile.lock 39 | 40 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 41 | # .tfvars files are managed as part of configuration and so should be included in 42 | # version control. 43 | **/*.tfvars 44 | 45 | credentials.json 46 | 47 | # tf lock file 48 | .terraform.lock.hcl 49 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | steps: 16 | - name: "gcr.io/cloud-builders/docker" 17 | args: 18 | [ 19 | "build", 20 | "-t", 21 | "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}:${_VERSION}", 22 | ".", 23 | ] 24 | images: 25 | - "${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/${_IMAGE}" 26 | -------------------------------------------------------------------------------- /modules/tfc-oidc/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 3.53, < 7.0.0" 23 | } 24 | } 25 | 26 | provider_meta "google" { 27 | module_name = "blueprints/terraform/terraform-google-tf-cloud-agents:tfc-oidc/v0.2.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/trusted-contribution.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2023-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | annotations: 19 | - type: comment 20 | text: "/gcbrun" 21 | trustedContributors: 22 | - release-please[bot] 23 | - renovate[bot] 24 | - renovate-bot 25 | - forking-renovate[bot] 26 | - dependabot[bot] 27 | -------------------------------------------------------------------------------- /test/setup/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | google = { 21 | source = "hashicorp/google" 22 | version = ">= 3.25.0" 23 | } 24 | google-beta = { 25 | source = "hashicorp/google-beta" 26 | version = ">= 3.25.0" 27 | } 28 | tfe = { 29 | source = "hashicorp/tfe" 30 | version = ">= 0.48.0" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-packer/cloudbuild.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | steps: 16 | - name: 'hashicorp/packer:1.11.2' 17 | args: 18 | - init 19 | - -var 20 | - project_id=$PROJECT_ID 21 | - -var 22 | - tfc_agent_version=${_TFC_AGENT_VERSION} 23 | - packer/packer.pkr.hcl 24 | - name: 'hashicorp/packer:1.11.2' 25 | args: 26 | - build 27 | - --force 28 | - -var 29 | - project_id=$PROJECT_ID 30 | - -var 31 | - tfc_agent_version=${_TFC_AGENT_VERSION} 32 | - packer/packer.pkr.hcl 33 | -------------------------------------------------------------------------------- /test/setup/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | value = module.project.project_id 19 | } 20 | 21 | output "sa_key" { 22 | value = google_service_account_key.int_test.private_key 23 | sensitive = true 24 | } 25 | 26 | output "tfc_org_name" { 27 | value = data.tfe_organization.tfc_org.name 28 | } 29 | 30 | output "tfc_agent_image" { 31 | value = "us-central1-docker.pkg.dev/${module.project.project_id}/hashicorp/tfc-agent:latest" 32 | } 33 | 34 | output "source_image" { 35 | value = "tfc-agent-image" 36 | } 37 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | #hadolint ignore=DL3007 16 | FROM hashicorp/tfc-agent:latest 17 | 18 | USER root 19 | 20 | # Downloading gcloud package 21 | RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz 22 | 23 | # Installing the package 24 | RUN mkdir -p /usr/local/gcloud \ 25 | && tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz \ 26 | && /usr/local/gcloud/google-cloud-sdk/install.sh 27 | 28 | # Adding the package path to local 29 | ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin 30 | 31 | USER tfc-agent 32 | -------------------------------------------------------------------------------- /examples/oidc-simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The project id to create Workload Identity Federation pool and example Service Account" 19 | value = var.project_id 20 | } 21 | 22 | output "pool_name" { 23 | description = "Pool name" 24 | value = module.oidc.pool_name 25 | } 26 | 27 | output "provider_name" { 28 | description = "Provider name" 29 | value = module.oidc.provider_name 30 | } 31 | 32 | output "sa_email" { 33 | description = "Example SA email" 34 | value = google_service_account.sa.email 35 | } 36 | -------------------------------------------------------------------------------- /test/setup/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | variable "org_id" { 17 | description = "The numeric organization id" 18 | type = string 19 | } 20 | 21 | variable "folder_id" { 22 | description = "The folder to deploy in" 23 | type = string 24 | } 25 | 26 | variable "billing_account" { 27 | description = "The billing account id associated with the project, e.g. XXXXXX-YYYYYY-ZZZZZZ" 28 | type = string 29 | } 30 | 31 | variable "tfc_org_name" { 32 | type = string 33 | default = "tfc-integration-sandbox" 34 | description = "Terraform Cloud org name to use" 35 | } 36 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-vm/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7.0.0" 24 | } 25 | google-beta = { 26 | source = "hashicorp/google-beta" 27 | version = ">= 3.53, < 7.0.0" 28 | } 29 | random = { 30 | source = "hashicorp/random" 31 | version = ">= 3.4.3, < 4.0" 32 | } 33 | } 34 | 35 | provider_meta "google" { 36 | module_name = "blueprints/terraform/terraform-google-tf-cloud-agents:tfc-agent-mig-vm/v0.2.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-container-vm/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 3.53, < 7.0.0" 24 | } 25 | google-beta = { 26 | source = "hashicorp/google-beta" 27 | version = ">= 3.53, < 7.0.0" 28 | } 29 | random = { 30 | source = "hashicorp/random" 31 | version = ">= 3.4.3, < 4.0" 32 | } 33 | } 34 | 35 | provider_meta "google" { 36 | module_name = "blueprints/terraform/terraform-google-tf-cloud-agents:tfc-agent-mig-container-vm/v0.2.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/setup/iam.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | int_required_roles = [ 19 | "roles/owner", 20 | "roles/artifactregistry.admin" 21 | ] 22 | } 23 | 24 | resource "google_service_account" "int_test" { 25 | project = module.project.project_id 26 | account_id = "ci-account" 27 | display_name = "ci-account" 28 | } 29 | 30 | resource "google_project_iam_member" "int_test" { 31 | for_each = toset(local.int_required_roles) 32 | 33 | project = module.project.project_id 34 | role = each.value 35 | member = "serviceAccount:${google_service_account.int_test.email}" 36 | } 37 | 38 | resource "google_service_account_key" "int_test" { 39 | service_account_id = google_service_account.int_test.id 40 | } 41 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-vm/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "mig_instance_group" { 18 | description = "The instance group url of the created MIG" 19 | value = module.mig.instance_group 20 | } 21 | 22 | output "mig_name" { 23 | description = "The name of the MIG" 24 | value = local.instance_name 25 | } 26 | 27 | output "mig_instance_template" { 28 | description = "The name of the MIG Instance Template" 29 | value = module.mig_template.name 30 | } 31 | 32 | output "network_name" { 33 | description = "Name of the VPC" 34 | value = local.network_name 35 | } 36 | 37 | output "service_account_email" { 38 | description = "Service account email used with the MIG template" 39 | value = local.service_account_email 40 | } 41 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent MIG" 19 | value = var.project_id 20 | } 21 | 22 | output "mig_instance_group" { 23 | description = "The instance group url of the created MIG" 24 | value = module.tfc_agent_mig.mig_instance_group 25 | } 26 | 27 | output "mig_name" { 28 | description = "The name of the MIG" 29 | value = module.tfc_agent_mig.mig_name 30 | } 31 | 32 | output "service_account_email" { 33 | description = "Service account email used with the MIG template" 34 | value = module.tfc_agent_mig.service_account_email 35 | } 36 | 37 | output "mig_instance_template" { 38 | description = "The name of the MIG Instance Template" 39 | value = module.tfc_agent_mig.mig_instance_template 40 | } 41 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-container-vm-simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent MIG" 19 | value = var.project_id 20 | } 21 | 22 | output "mig_instance_group" { 23 | description = "The instance group url of the created MIG" 24 | value = module.tfc_agent_mig.mig_instance_group 25 | } 26 | 27 | output "mig_name" { 28 | description = "The name of the MIG" 29 | value = module.tfc_agent_mig.mig_name 30 | } 31 | 32 | output "service_account_email" { 33 | description = "Service account email used with the MIG template" 34 | value = module.tfc_agent_mig.service_account_email 35 | } 36 | 37 | output "mig_instance_template" { 38 | description = "The name of the MIG Instance Template" 39 | value = module.tfc_agent_mig.mig_instance_template 40 | } 41 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-packer/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent MIG" 19 | value = var.project_id 20 | } 21 | 22 | output "mig_instance_group" { 23 | description = "The instance group url of the created MIG" 24 | value = module.tfc_agent_mig.mig_instance_group 25 | } 26 | 27 | output "mig_name" { 28 | description = "The name of the MIG" 29 | value = module.tfc_agent_mig.mig_name 30 | } 31 | 32 | output "service_account_email" { 33 | description = "Service account email for GCE used with the MIG template" 34 | value = module.tfc_agent_mig.service_account_email 35 | } 36 | 37 | output "mig_instance_template" { 38 | description = "The name of the MIG Instance Template" 39 | value = module.tfc_agent_mig.mig_instance_template 40 | } 41 | -------------------------------------------------------------------------------- /modules/tfc-agent-gke/versions.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | terraform { 18 | required_version = ">= 1.3" 19 | required_providers { 20 | 21 | google = { 22 | source = "hashicorp/google" 23 | version = ">= 4.3.0, < 7.0.0" 24 | } 25 | 26 | kubernetes = { 27 | source = "hashicorp/kubernetes" 28 | version = ">= 2.0, <3.0" 29 | } 30 | 31 | random = { 32 | source = "hashicorp/random" 33 | version = ">= 3.4.3, < 4.0" 34 | } 35 | } 36 | 37 | provider_meta "google" { 38 | module_name = "blueprints/terraform/terraform-google-tf-cloud-agents:tfc-agent-gke/v0.2.0" 39 | } 40 | } 41 | 42 | provider "kubernetes" { 43 | host = "https://${module.tfc_agent_cluster.endpoint}" 44 | token = data.google_client_config.default.access_token 45 | cluster_ca_certificate = base64decode( 46 | module.tfc_agent_cluster.ca_certificate 47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-container-vm/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "mig_instance_group" { 18 | description = "The instance group url of the created MIG" 19 | value = module.mig.instance_group 20 | } 21 | 22 | output "mig_name" { 23 | description = "The name of the MIG" 24 | value = local.instance_name 25 | } 26 | 27 | output "mig_instance_template" { 28 | description = "The name of the MIG Instance Template" 29 | value = module.mig_template.name 30 | } 31 | 32 | output "network_name" { 33 | description = "Name of the VPC" 34 | value = local.network_name 35 | } 36 | 37 | output "subnet_name" { 38 | description = "Name of the subnet in the VPC" 39 | value = local.subnet_name 40 | } 41 | 42 | output "service_account_email" { 43 | description = "Service account email attached to MIG templates for GCE" 44 | value = local.service_account_email 45 | } 46 | -------------------------------------------------------------------------------- /examples/oidc-simple/README.md: -------------------------------------------------------------------------------- 1 | # OIDC Simple Example 2 | 3 | ## Overview 4 | 5 | This example showcases how to configure [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) using the [tfc-oidc module](../../modules/tfc-oidc/README.md) for a sample Service Account. 6 | 7 | 8 | ## Inputs 9 | 10 | | Name | Description | Type | Default | Required | 11 | |------|-------------|------|---------|:--------:| 12 | | project\_id | The project id to create Workload Identity Federation pool and example Service Account | `string` | n/a | yes | 13 | | role\_list | Google Cloud roles required for the Service Account | `list(string)` |
[| no | 14 | | tfc\_org\_name | Terraform Cloud org name where the Workload Identity Federation pool will be attached | `string` | n/a | yes | 15 | | tfc\_project\_name | Terraform Cloud project name where the Workload Identity Federation pool will be attached | `string` | `"GCP OIDC"` | no | 16 | | tfc\_workspace\_name | Terraform Cloud workspace name where the Workload Identity Federation pool will be attached | `string` | `"gcp-oidc"` | no | 17 | 18 | ## Outputs 19 | 20 | | Name | Description | 21 | |------|-------------| 22 | | pool\_name | Pool name | 23 | | project\_id | The project id to create Workload Identity Federation pool and example Service Account | 24 | | provider\_name | Provider name | 25 | | sa\_email | Example SA email | 26 | 27 | 28 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-packer/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2023 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Install jq 17 | apt-get update 18 | apt-get -y install jq unzip 19 | 20 | secretUri=$(curl -sS "http://metadata.google.internal/computeMetadata/v1/instance/attributes/secret-id" -H "Metadata-Flavor: Google") 21 | # Secrets URI is of the form projects/$PROJECT_NUMBER/secrets/$SECRET_NAME/versions/$SECRET_VERSION 22 | # Split into array based on `/` delimeter 23 | IFS="/" read -r -a secretsConfig <<<"$secretUri" 24 | 25 | # Get SECRET_NAME and SECRET_VERSION 26 | SECRET_NAME=${secretsConfig[3]} 27 | SECRET_VERSION=${secretsConfig[5]} 28 | 29 | # Access secret from secrets manager 30 | secrets=$(gcloud secrets versions access "$SECRET_VERSION" --secret="$SECRET_NAME") 31 | 32 | # Set secrets as env vars 33 | # shellcheck disable=SC2046 34 | 35 | # Use wordsplitting 36 | export $(echo "$secrets" | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]") 37 | 38 | # Start agent service 39 | cd /agent || exit 40 | ./tfc-agent 41 | -------------------------------------------------------------------------------- /examples/oidc-simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The project id to create Workload Identity Federation pool and example Service Account" 20 | } 21 | 22 | variable "tfc_org_name" { 23 | type = string 24 | description = "Terraform Cloud org name where the Workload Identity Federation pool will be attached" 25 | } 26 | 27 | variable "tfc_project_name" { 28 | type = string 29 | description = "Terraform Cloud project name where the Workload Identity Federation pool will be attached" 30 | default = "GCP OIDC" 31 | } 32 | 33 | variable "tfc_workspace_name" { 34 | type = string 35 | description = "Terraform Cloud workspace name where the Workload Identity Federation pool will be attached" 36 | default = "gcp-oidc" 37 | } 38 | 39 | variable "role_list" { 40 | description = "Google Cloud roles required for the Service Account" 41 | type = list(string) 42 | default = [ 43 | "roles/storage.admin" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent cluster" 20 | } 21 | 22 | variable "tfc_org_name" { 23 | type = string 24 | description = "Terraform Cloud org name where the agent pool will be created" 25 | } 26 | 27 | variable "tfc_project_name" { 28 | type = string 29 | description = "Terraform Cloud project to use" 30 | default = "GCP agents" 31 | } 32 | 33 | variable "tfc_workspace_name" { 34 | type = string 35 | description = "Terraform Cloud workspace name to be created" 36 | default = "tfc-agent-gke-simple" 37 | } 38 | 39 | variable "tfc_agent_pool_name" { 40 | type = string 41 | description = "Terraform Cloud agent pool name to be created" 42 | default = "tfc-agent-gke-simple-pool" 43 | } 44 | 45 | variable "tfc_agent_pool_token_description" { 46 | type = string 47 | description = "Terraform Cloud agent pool token description" 48 | default = "tfc-agent-gke-simple-pool-token" 49 | } 50 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-vm-simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent MIG" 20 | } 21 | 22 | variable "tfc_org_name" { 23 | type = string 24 | description = "Terraform Cloud org name where the agent pool will be created" 25 | } 26 | 27 | variable "tfc_project_name" { 28 | type = string 29 | description = "Terraform Cloud project name to be created" 30 | default = "GCP agents" 31 | } 32 | 33 | variable "tfc_workspace_name" { 34 | type = string 35 | description = "Terraform Cloud workspace name to be created" 36 | default = "tfc-agent-mig-vm-simple" 37 | } 38 | 39 | variable "tfc_agent_pool_name" { 40 | type = string 41 | description = "Terraform Cloud agent pool name to be created" 42 | default = "tfc-agent-mig-vm-simple-pool" 43 | } 44 | 45 | variable "tfc_agent_pool_token_description" { 46 | type = string 47 | description = "Terraform Cloud agent pool token description" 48 | default = "tfc-agent-mig-vm-simple-pool-token" 49 | } 50 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2022-2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # NOTE: This file is automatically generated from: 16 | # https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/main/infra/terraform/test-org/github 17 | 18 | name: "Close stale issues" 19 | on: 20 | schedule: 21 | - cron: "0 23 * * *" 22 | 23 | permissions: 24 | contents: read 25 | issues: write 26 | pull-requests: write 27 | actions: write 28 | 29 | jobs: 30 | stale: 31 | if: github.repository_owner == 'GoogleCloudPlatform' || github.repository_owner == 'terraform-google-modules' 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/stale@v10 35 | with: 36 | repo-token: ${{ secrets.GITHUB_TOKEN }} 37 | stale-issue-message: 'This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 38 | stale-pr-message: 'This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days' 39 | exempt-issue-labels: 'triaged' 40 | exempt-pr-labels: 'dependencies,autorelease: pending' 41 | operations-per-run: 100 42 | -------------------------------------------------------------------------------- /examples/tfc-agent-mig-container-vm-simple/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent MIG" 20 | } 21 | 22 | variable "tfc_org_name" { 23 | type = string 24 | description = "Terraform Cloud org name where the agent pool will be created" 25 | } 26 | 27 | variable "tfc_project_name" { 28 | type = string 29 | description = "Terraform Cloud project name to be created" 30 | default = "GCP agents" 31 | } 32 | 33 | variable "tfc_workspace_name" { 34 | type = string 35 | description = "Terraform Cloud workspace name to be created" 36 | default = "tfc-agent-mig-container-vm-simple" 37 | } 38 | 39 | variable "tfc_agent_pool_name" { 40 | type = string 41 | description = "Terraform Cloud agent pool name to be created" 42 | default = "tfc-agent-mig-container-vm-simple-pool" 43 | } 44 | 45 | variable "tfc_agent_pool_token_description" { 46 | type = string 47 | description = "Terraform Cloud agent pool token description" 48 | default = "tfc-agent-mig-container-vm-simple-pool-token" 49 | } 50 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent cluster" 20 | } 21 | 22 | variable "tfc_org_name" { 23 | type = string 24 | description = "Terraform Cloud org name where the agent pool will be created" 25 | } 26 | 27 | variable "tfc_project_name" { 28 | type = string 29 | description = "Terraform Cloud project to use" 30 | default = "GCP agents" 31 | } 32 | 33 | variable "tfc_workspace_name" { 34 | type = string 35 | description = "Terraform Cloud workspace name to be created" 36 | default = "tfc-agent-gke-custom" 37 | } 38 | 39 | variable "tfc_agent_pool_name" { 40 | type = string 41 | description = "Terraform Cloud agent pool name to be created" 42 | default = "tfc-agent-gke-custom-pool" 43 | } 44 | 45 | variable "tfc_agent_pool_token_description" { 46 | type = string 47 | description = "Terraform Cloud agent pool token description" 48 | default = "tfc-agent-gke-custom-pool-token" 49 | } 50 | 51 | variable "tfc_agent_image" { 52 | type = string 53 | description = "The custom Terraform Cloud agent image to use" 54 | } 55 | -------------------------------------------------------------------------------- /modules/tfc-agent-gke/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "kubernetes_endpoint" { 18 | description = "The GKE cluster endpoint" 19 | sensitive = true 20 | value = module.tfc_agent_cluster.endpoint 21 | } 22 | 23 | output "client_token" { 24 | description = "The bearer token for auth" 25 | sensitive = true 26 | value = base64encode(data.google_client_config.default.access_token) 27 | } 28 | 29 | output "ca_certificate" { 30 | description = "The cluster CA certificate (base64 encoded)" 31 | sensitive = true 32 | value = module.tfc_agent_cluster.ca_certificate 33 | } 34 | 35 | output "service_account" { 36 | description = "The default service account used for TFC agent nodes" 37 | value = module.tfc_agent_cluster.service_account 38 | } 39 | 40 | output "cluster_name" { 41 | description = "GKE cluster name" 42 | value = module.tfc_agent_cluster.name 43 | } 44 | 45 | output "network_name" { 46 | description = "Name of the VPC" 47 | value = local.network_name 48 | } 49 | 50 | output "subnet_name" { 51 | description = "Name of the subnet in the VPC" 52 | value = local.subnet_name 53 | } 54 | 55 | output "location" { 56 | description = "GKE cluster location" 57 | value = module.tfc_agent_cluster.location 58 | } 59 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-custom/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent cluster" 19 | value = var.project_id 20 | } 21 | 22 | output "kubernetes_endpoint" { 23 | description = "The cluster endpoint" 24 | sensitive = true 25 | value = module.tfc_agent_gke.kubernetes_endpoint 26 | } 27 | 28 | output "ca_certificate" { 29 | description = "The cluster CA certificate (base64 encoded)" 30 | sensitive = true 31 | value = module.tfc_agent_gke.ca_certificate 32 | } 33 | 34 | output "service_account" { 35 | description = "The default service account used for TFC agent nodes" 36 | value = module.tfc_agent_gke.service_account 37 | } 38 | 39 | output "cluster_name" { 40 | description = "GKE cluster name" 41 | value = module.tfc_agent_gke.cluster_name 42 | } 43 | 44 | output "network_name" { 45 | description = "Name of the VPC" 46 | value = module.tfc_agent_gke.network_name 47 | } 48 | 49 | output "subnet_name" { 50 | description = "Name of the subnet in the VPC" 51 | value = module.tfc_agent_gke.subnet_name 52 | } 53 | 54 | output "location" { 55 | description = "GKE cluster location" 56 | value = module.tfc_agent_gke.location 57 | } 58 | -------------------------------------------------------------------------------- /examples/tfc-agent-gke-simple/outputs.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | output "project_id" { 18 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent cluster" 19 | value = var.project_id 20 | } 21 | 22 | output "kubernetes_endpoint" { 23 | description = "The GKE cluster endpoint" 24 | sensitive = true 25 | value = module.tfc_agent_gke.kubernetes_endpoint 26 | } 27 | 28 | output "ca_certificate" { 29 | description = "The cluster CA certificate (base64 encoded)" 30 | sensitive = true 31 | value = module.tfc_agent_gke.ca_certificate 32 | } 33 | 34 | output "service_account" { 35 | description = "The default service account used for TFC agent nodes" 36 | value = module.tfc_agent_gke.service_account 37 | } 38 | 39 | output "cluster_name" { 40 | description = "GKE cluster name" 41 | value = module.tfc_agent_gke.cluster_name 42 | } 43 | 44 | output "network_name" { 45 | description = "Name of the VPC" 46 | value = module.tfc_agent_gke.network_name 47 | } 48 | 49 | output "subnet_name" { 50 | description = "Name of the subnet in the VPC" 51 | value = module.tfc_agent_gke.subnet_name 52 | } 53 | 54 | output "location" { 55 | description = "GKE cluster location" 56 | value = module.tfc_agent_gke.location 57 | } 58 | -------------------------------------------------------------------------------- /test/setup/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2019 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module "project" { 18 | source = "terraform-google-modules/project-factory/google" 19 | version = "~> 17.0" 20 | 21 | name = "ci-tf-cloud-agents" 22 | random_project_id = "true" 23 | org_id = var.org_id 24 | folder_id = var.folder_id 25 | billing_account = var.billing_account 26 | auto_create_network = true 27 | deletion_policy = "DELETE" 28 | 29 | activate_apis = [ 30 | "artifactregistry.googleapis.com", 31 | "cloudresourcemanager.googleapis.com", 32 | "compute.googleapis.com", 33 | "container.googleapis.com", 34 | "iam.googleapis.com", 35 | "serviceusage.googleapis.com", 36 | "secretmanager.googleapis.com", 37 | "storage-api.googleapis.com", 38 | ] 39 | } 40 | 41 | data "tfe_organization" "tfc_org" { 42 | name = var.tfc_org_name 43 | } 44 | 45 | resource "google_artifact_registry_repository" "hashicorp" { 46 | project = module.project.project_id 47 | location = "us-central1" 48 | repository_id = "hashicorp" 49 | description = "HashiCorp Docker repository" 50 | format = "DOCKER" 51 | } 52 | 53 | resource "local_file" "env_file" { 54 | filename = "${path.module}/outputs.env" 55 | content = <
"roles/storage.admin"
]
[| no | 55 | 56 | ## Outputs 57 | 58 | | Name | Description | 59 | |------|-------------| 60 | | ca\_certificate | The cluster CA certificate (base64 encoded) | 61 | | client\_token | The bearer token for auth | 62 | | cluster\_name | GKE cluster name | 63 | | kubernetes\_endpoint | The GKE cluster endpoint | 64 | | location | GKE cluster location | 65 | | network\_name | Name of the VPC | 66 | | service\_account | The default service account used for TFC agent nodes | 67 | | subnet\_name | Name of the subnet in the VPC | 68 | 69 | 70 | 71 | ## Requirements 72 | 73 | Before this module can be used on a project, you must ensure that the following pre-requisites are fulfilled: 74 | 75 | 1. Required APIs are activated 76 | 77 | ```text 78 | "iam.googleapis.com", 79 | "cloudresourcemanager.googleapis.com", 80 | "containerregistry.googleapis.com", 81 | "container.googleapis.com", 82 | "storage-component.googleapis.com", 83 | "logging.googleapis.com", 84 | "monitoring.googleapis.com" 85 | ``` 86 | -------------------------------------------------------------------------------- /modules/tfc-oidc/README.md: -------------------------------------------------------------------------------- 1 | ## Terraform Cloud OIDC (Dynamic Credentials) 2 | 3 | This module handles the opinionated creation of infrastructure necessary to configure [Workload Identity pools](https://cloud.google.com/iam/docs/workload-identity-federation#pools) and [providers](https://cloud.google.com/iam/docs/workload-identity-federation#providers) for authenticating to GCP using [Terraform Cloud Dynamic Credentials](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/gcp-configuration). 4 | 5 | This includes: 6 | 7 | - Creation of a Workload Identity pool 8 | - Configuring a Workload Identity provider 9 | - Granting external identities necessary IAM roles on Service Accounts 10 | 11 | ### Example Usage 12 | 13 | ```terraform 14 | module "tfc_oidc" { 15 | source = "GoogleCloudPlatform/tf-cloud-agents/google//modules/tfc-oidc" 16 | project_id = var.project_id 17 | pool_id = "example-pool" 18 | provider_id = "example-tfc-provider" 19 | sa_mapping = { 20 | "foo-service-account" = { 21 | sa_name = "projects/my-project/serviceAccounts/foo-service-account@my-project.iam.gserviceaccount.com" 22 | sa_email = "foo-service-account@my-project.iam.gserviceaccount.com" 23 | attribute = "*" 24 | } 25 | } 26 | tfc_organization_name = "example-tfc-organization" 27 | tfc_project_name = "example-tfc-project" 28 | tfc_workspace_name = "example-tfc-workspace-name" 29 | } 30 | ``` 31 | 32 | Below are some examples: 33 | 34 | ### [OIDC Simple](../../examples/oidc-simple/README.md) 35 | 36 | This example shows how to use this module along with a Service Account to access storage buckets. 37 | 38 | ### Terraform Cloud Workflow 39 | 40 | Once provisioned, you can use the `example-tfc-workspace-name` workspace from the example above to provision any infrastructure that the Service Account has access for. 41 | 42 | 43 | ## Inputs 44 | 45 | | Name | Description | Type | Default | Required | 46 | |------|-------------|------|---------|:--------:| 47 | | allowed\_audiences | Workload Identity Pool Provider allowed audiences | `list(string)` | `[]` | no | 48 | | attribute\_condition | Workload Identity Pool Provider attribute condition expression
"us-central1-a"
]
{
"attribute.aud": "assertion.aud",
"attribute.terraform_full_workspace": "assertion.terraform_full_workspace",
"attribute.terraform_organization_id": "assertion.terraform_organization_id",
"attribute.terraform_organization_name": "assertion.terraform_organization_name",
"attribute.terraform_project_id": "assertion.terraform_project_id",
"attribute.terraform_project_name": "assertion.terraform_project_name",
"attribute.terraform_run_id": "assertion.terraform_run_id",
"attribute.terraform_run_phase": "assertion.terraform_run_phase",
"attribute.terraform_workspace_id": "assertion.terraform_workspace_id",
"attribute.terraform_workspace_name": "assertion.terraform_workspace_name",
"google.subject": "assertion.sub"
} | no |
50 | | issuer\_uri | Workload Identity Pool Issuer URL for Terraform Cloud/Enterprise.map(object({
sa_name = string
sa_email = string
attribute = string
})) | `{}` | no |
59 | | service\_list | Google Cloud APIs required for the project | `list(string)` | [| no | 60 | | tfc\_organization\_name | The Terraform Cloud organization to use | `string` | n/a | yes | 61 | | tfc\_project\_name | The Terraform Cloud project to use | `string` | `"Default Project"` | no | 62 | | tfc\_workspace\_name | The Terraform Cloud workspace to authorize via OIDC | `string` | `"gcp-oidc-workspace"` | no | 63 | 64 | ## Outputs 65 | 66 | | Name | Description | 67 | |------|-------------| 68 | | pool\_name | Pool name | 69 | | provider\_name | Provider name | 70 | 71 | 72 | 73 | ## Requirements 74 | 75 | Before this module can be used on a project, you must ensure that the following pre-requisites are fulfilled: 76 | 77 | 1. Required APIs are activated 78 | 79 | ``` 80 | "iam.googleapis.com", 81 | "cloudresourcemanager.googleapis.com", 82 | "sts.googleapis.com", 83 | "iamcredentials.googleapis.com" 84 | ``` 85 | 86 | 1. Service Account used to deploy this module has the following roles 87 | 88 | ``` 89 | roles/iam.workloadIdentityPoolAdmin 90 | roles/iam.serviceAccountAdmin 91 | ``` 92 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-vm/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent" 20 | } 21 | 22 | variable "region" { 23 | type = string 24 | description = "The GCP region to use when deploying resources" 25 | default = "us-central1" 26 | } 27 | 28 | variable "create_network" { 29 | type = bool 30 | description = "When set to true, VPC, router and NAT will be auto created" 31 | default = true 32 | } 33 | 34 | variable "network_name" { 35 | type = string 36 | description = "Name for the VPC network" 37 | default = "tfc-agent-network" 38 | } 39 | 40 | variable "network_project" { 41 | type = string 42 | description = <<-EOF 43 | The project ID of the shared VPCs host (for shared vpc support). 44 | If not provided, the project_id is used 45 | EOF 46 | default = "" 47 | } 48 | 49 | variable "subnet_ip" { 50 | type = string 51 | description = "IP range for the subnet" 52 | default = "10.10.10.0/24" 53 | } 54 | 55 | variable "subnet_name" { 56 | type = string 57 | description = "Name for the subnet" 58 | default = "tfc-agent-subnet" 59 | } 60 | 61 | variable "min_replicas" { 62 | type = number 63 | description = "Minimum number of Terraform agent instances" 64 | default = 1 65 | } 66 | 67 | variable "max_replicas" { 68 | type = number 69 | description = "Maximum number of Terraform agent instances" 70 | default = 10 71 | } 72 | 73 | variable "create_service_account" { 74 | description = "Set to true to create a new service account, false to use an existing one" 75 | type = bool 76 | default = true 77 | } 78 | 79 | variable "service_account_email" { 80 | type = string 81 | description = "Service account email address to use with the MIG template, required if create_service_account is set to false" 82 | default = "" 83 | } 84 | 85 | variable "machine_type" { 86 | type = string 87 | description = "The GCP machine type to deploy" 88 | default = "n1-standard-1" 89 | } 90 | 91 | variable "source_image_family" { 92 | type = string 93 | description = <<-EOF 94 | Source image family. If neither source_image nor source_image_family 95 | is specified, defaults to the latest public Ubuntu image 96 | EOF 97 | default = "ubuntu-2204-lts" 98 | } 99 | 100 | variable "source_image_project" { 101 | type = string 102 | description = "Project where the source image originates" 103 | default = "ubuntu-os-cloud" 104 | } 105 | 106 | variable "source_image" { 107 | type = string 108 | description = <<-EOF 109 | Source disk image. If neither source_image nor source_image_family is specified, 110 | defaults to the latest public CentOS image 111 | EOF 112 | default = "" 113 | } 114 | 115 | variable "startup_script" { 116 | type = string 117 | description = "User startup script to run when instances spin up" 118 | default = "" 119 | } 120 | 121 | variable "custom_metadata" { 122 | type = map(any) 123 | description = "User provided custom metadata" 124 | default = {} 125 | } 126 | 127 | variable "cooldown_period" { 128 | type = number 129 | description = <<-EOF 130 | The number of seconds that the autoscaler should wait before it 131 | starts collecting information from a new instance 132 | EOF 133 | default = 60 134 | } 135 | 136 | variable "tfc_agent_secret" { 137 | type = string 138 | description = "The secret id for storing the Terraform Cloud agent secret" 139 | default = "tfc-agent" 140 | } 141 | 142 | variable "tfc_agent_address" { 143 | type = string 144 | description = "The HTTP or HTTPS address of the Terraform Cloud/Enterprise API" 145 | default = "https://app.terraform.io" 146 | } 147 | 148 | variable "tfc_agent_single" { 149 | type = bool 150 | description = <<-EOF 151 | Enable single mode. This causes the agent to handle at most one job and 152 | immediately exit thereafter. Useful for running agents as ephemeral 153 | containers, VMs, or other isolated contexts with a higher-level scheduler 154 | or process supervisor 155 | EOF 156 | default = false 157 | } 158 | 159 | variable "tfc_agent_auto_update" { 160 | type = string 161 | description = <<-EOF 162 | Controls automatic core updates behavior. 163 | Acceptable values include disabled, patch, and minor 164 | EOF 165 | default = "minor" 166 | } 167 | 168 | variable "tfc_agent_name_prefix" { 169 | type = string 170 | description = <<-EOF 171 | This name may be used in the Terraform Cloud user interface to help 172 | easily identify the agent 173 | EOF 174 | default = "tfc-agent-mig-vm" 175 | } 176 | 177 | variable "tfc_agent_labels" { 178 | type = set(string) 179 | description = "Terraform Cloud agent labels to attach to the VMs" 180 | default = [] 181 | } 182 | 183 | variable "tfc_agent_version" { 184 | type = string 185 | description = "Terraform Cloud agent version to install" 186 | default = "1.12.0" 187 | } 188 | 189 | variable "tfc_agent_token" { 190 | type = string 191 | description = "Terraform Cloud agent token. (Organization Settings >> Agents)" 192 | sensitive = true 193 | } 194 | -------------------------------------------------------------------------------- /modules/tfc-agent-gke/variables.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | variable "project_id" { 18 | type = string 19 | description = "The Google Cloud Platform project ID to deploy Terraform Cloud agent cluster" 20 | } 21 | 22 | variable "region" { 23 | type = string 24 | description = "The GCP region to use when deploying resources" 25 | default = "us-central1" 26 | } 27 | 28 | variable "zones" { 29 | type = list(string) 30 | description = "The GCP zone to use when deploying resources" 31 | default = ["us-central1-a"] 32 | } 33 | 34 | variable "ip_range_pods_name" { 35 | type = string 36 | description = "The secondary IP range to use for pods" 37 | default = "ip-range-pods" 38 | } 39 | 40 | variable "ip_range_services_name" { 41 | type = string 42 | description = "The secondary IP range to use for services" 43 | default = "ip-range-scv" 44 | } 45 | 46 | variable "ip_range_pods_cidr" { 47 | type = string 48 | description = "The secondary IP range CIDR to use for pods" 49 | default = "192.168.0.0/18" 50 | } 51 | 52 | variable "ip_range_services_cider" { 53 | type = string 54 | description = "The secondary IP range CIDR to use for services" 55 | default = "192.168.64.0/18" 56 | } 57 | 58 | variable "network_name" { 59 | type = string 60 | description = "Name for the VPC network" 61 | default = "tfc-agent-network" 62 | } 63 | 64 | variable "subnet_ip" { 65 | type = string 66 | description = "IP range for the subnet" 67 | default = "10.0.0.0/17" 68 | } 69 | 70 | variable "subnet_name" { 71 | type = string 72 | description = "Name for the subnet" 73 | default = "tfc-agent-subnet" 74 | } 75 | 76 | variable "create_network" { 77 | type = bool 78 | description = "When set to true, VPC will be auto created" 79 | default = true 80 | } 81 | 82 | variable "network_project_id" { 83 | type = string 84 | description = <<-EOF 85 | The project ID of the shared VPCs host (for shared vpc support). 86 | If not provided, the project_id is used 87 | EOF 88 | default = "" 89 | } 90 | 91 | variable "machine_type" { 92 | type = string 93 | description = "Machine type for TFC agent node pool" 94 | default = "n1-standard-4" 95 | } 96 | 97 | variable "max_node_count" { 98 | type = number 99 | description = "Maximum number of nodes in the TFC agent node pool" 100 | default = 4 101 | } 102 | 103 | variable "min_node_count" { 104 | type = number 105 | description = "Minimum number of nodes in the TFC agent node pool" 106 | default = 2 107 | } 108 | 109 | variable "create_service_account" { 110 | description = "Set to true to create a new service account, false to use an existing one" 111 | type = bool 112 | default = true 113 | } 114 | 115 | variable "service_account_email" { 116 | type = string 117 | description = "Optional Service Account for the GKE nodes, required if create_service_account is set to false" 118 | default = "" 119 | } 120 | 121 | variable "tfc_agent_k8s_secrets" { 122 | type = string 123 | description = "Name for the k8s secret required to configure TFC agent on GKE" 124 | default = "tfc-agent-k8s-secrets" 125 | } 126 | 127 | variable "tfc_agent_address" { 128 | type = string 129 | description = "The HTTP or HTTPS address of the Terraform Cloud/Enterprise API" 130 | default = "https://app.terraform.io" 131 | } 132 | 133 | variable "tfc_agent_single" { 134 | type = bool 135 | description = <<-EOF 136 | Enable single mode. This causes the agent to handle at most one job and 137 | immediately exit thereafter. Useful for running agents as ephemeral 138 | containers, VMs, or other isolated contexts with a higher-level scheduler 139 | or process supervisor. 140 | EOF 141 | default = false 142 | } 143 | 144 | variable "tfc_agent_auto_update" { 145 | type = string 146 | description = "Controls automatic core updates behavior. Acceptable values include disabled, patch, and minor" 147 | default = "minor" 148 | } 149 | 150 | variable "tfc_agent_name_prefix" { 151 | type = string 152 | description = "This name may be used in the Terraform Cloud user interface to help easily identify the agent" 153 | default = "tfc-agent-k8s" 154 | } 155 | 156 | variable "tfc_agent_image" { 157 | type = string 158 | description = "The Terraform Cloud agent image to use" 159 | default = "hashicorp/tfc-agent:latest" 160 | } 161 | 162 | variable "tfc_agent_memory_request" { 163 | type = string 164 | description = "Memory request for the Terraform Cloud agent container" 165 | default = "2Gi" 166 | } 167 | 168 | variable "tfc_agent_cpu_request" { 169 | type = string 170 | description = "CPU request for the Terraform Cloud agent container" 171 | default = "2" 172 | } 173 | 174 | variable "tfc_agent_token" { 175 | type = string 176 | description = "Terraform Cloud agent token. (Organization Settings >> Agents)" 177 | sensitive = true 178 | } 179 | 180 | variable "tfc_agent_min_replicas" { 181 | type = string 182 | description = "Minimum replicas for the Terraform Cloud agent pod autoscaler" 183 | default = "1" 184 | } 185 | 186 | variable "tfc_agent_max_replicas" { 187 | type = string 188 | description = "Maximum replicas for the Terraform Cloud agent pod autoscaler" 189 | default = "10" 190 | } 191 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-vm/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | network_name = var.create_network ? google_compute_network.tfc_agent_network[0].self_link : var.network_name 19 | service_account_email = var.create_service_account ? google_service_account.tfc_agent_service_account[0].email : var.service_account_email 20 | startup_script = var.startup_script == "" ? file("${path.module}/scripts/startup.sh") : var.startup_script 21 | instance_name = "${var.tfc_agent_name_prefix}-${random_string.suffix.result}" 22 | tfc_agent_secret = "${var.tfc_agent_secret}-${random_string.suffix.result}" 23 | } 24 | 25 | resource "random_string" "suffix" { 26 | length = 4 27 | special = false 28 | upper = false 29 | } 30 | 31 | /***************************************** 32 | Optional Terraform agent Networking 33 | *****************************************/ 34 | 35 | resource "google_compute_network" "tfc_agent_network" { 36 | count = var.create_network ? 1 : 0 37 | name = var.network_name 38 | project = var.project_id 39 | auto_create_subnetworks = false 40 | } 41 | 42 | resource "google_compute_subnetwork" "tfc_agent_subnetwork" { 43 | count = var.create_network ? 1 : 0 44 | project = var.project_id 45 | name = var.subnet_name 46 | ip_cidr_range = var.subnet_ip 47 | region = var.region 48 | network = local.network_name 49 | } 50 | 51 | resource "google_compute_router" "tfc_agent_router" { 52 | count = var.create_network ? 1 : 0 53 | name = "${var.network_name}-router" 54 | network = google_compute_network.tfc_agent_network[0].self_link 55 | region = var.region 56 | project = var.project_id 57 | } 58 | 59 | resource "google_compute_router_nat" "tfc_agent_nat" { 60 | count = var.create_network ? 1 : 0 61 | project = var.project_id 62 | name = "${var.network_name}-nat" 63 | router = google_compute_router.tfc_agent_router[0].name 64 | region = google_compute_router.tfc_agent_router[0].region 65 | nat_ip_allocate_option = "AUTO_ONLY" 66 | source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" 67 | } 68 | 69 | /***************************************** 70 | IAM Bindings GCE SVC 71 | *****************************************/ 72 | 73 | resource "google_service_account" "tfc_agent_service_account" { 74 | count = var.create_service_account ? 1 : 0 75 | project = var.project_id 76 | account_id = "tfc-agent-mig-vm-sa" 77 | display_name = "Terraform Cloud agent GCE Service Account" 78 | } 79 | 80 | /***************************************** 81 | Terraform agent Secrets 82 | *****************************************/ 83 | 84 | resource "google_secret_manager_secret" "tfc_agent_secret" { 85 | provider = google-beta 86 | project = var.project_id 87 | secret_id = local.tfc_agent_secret 88 | 89 | labels = { 90 | label = local.tfc_agent_secret 91 | } 92 | 93 | replication { 94 | user_managed { 95 | replicas { 96 | location = var.region 97 | } 98 | } 99 | } 100 | } 101 | 102 | resource "google_secret_manager_secret_version" "tfc_agent_secret_version" { 103 | provider = google-beta 104 | secret = google_secret_manager_secret.tfc_agent_secret.id 105 | secret_data = jsonencode({ 106 | "TFC_AGENT_NAME" = local.instance_name 107 | "TFC_ADDRESS" = var.tfc_agent_address 108 | "TFC_AGENT_TOKEN" = var.tfc_agent_token 109 | "TFC_AGENT_SINGLE" = var.tfc_agent_single 110 | "TFC_AGENT_AUTO_UPDATE" = var.tfc_agent_auto_update 111 | "AGENT_VERSION" = var.tfc_agent_version 112 | "LABELS" = join(",", var.tfc_agent_labels) 113 | }) 114 | } 115 | 116 | resource "google_secret_manager_secret_iam_member" "tfc_agent_secret_member" { 117 | provider = google-beta 118 | project = var.project_id 119 | secret_id = google_secret_manager_secret.tfc_agent_secret.id 120 | role = "roles/secretmanager.secretAccessor" 121 | member = "serviceAccount:${local.service_account_email}" 122 | } 123 | 124 | /***************************************** 125 | Terraform agent GCE Instance Template 126 | *****************************************/ 127 | 128 | module "mig_template" { 129 | source = "terraform-google-modules/vm/google//modules/instance_template" 130 | version = "~> 12.0" 131 | 132 | project_id = var.project_id 133 | machine_type = var.machine_type 134 | network = local.network_name 135 | subnetwork = var.subnet_name 136 | region = var.region 137 | subnetwork_project = var.network_project != "" ? var.network_project : var.project_id 138 | service_account = { 139 | email = local.service_account_email 140 | scopes = [ 141 | "https://www.googleapis.com/auth/cloud-platform", 142 | ] 143 | } 144 | disk_size_gb = 100 145 | disk_type = "pd-ssd" 146 | auto_delete = true 147 | source_image = var.source_image 148 | source_image_family = var.source_image_family 149 | source_image_project = var.source_image_project 150 | name_prefix = var.tfc_agent_name_prefix 151 | startup_script = local.startup_script 152 | metadata = merge({ 153 | "secret-id" = google_secret_manager_secret_version.tfc_agent_secret_version.name 154 | }, var.custom_metadata) 155 | tags = [ 156 | local.instance_name 157 | ] 158 | 159 | depends_on = [ 160 | google_compute_network.tfc_agent_network, 161 | google_compute_subnetwork.tfc_agent_subnetwork, 162 | ] 163 | } 164 | 165 | /***************************************** 166 | Terraform agent MIG 167 | *****************************************/ 168 | 169 | module "mig" { 170 | source = "terraform-google-modules/vm/google//modules/mig" 171 | version = "~> 12.0" 172 | 173 | project_id = var.project_id 174 | region = var.region 175 | hostname = local.instance_name 176 | instance_template = module.mig_template.self_link 177 | 178 | /* autoscaler */ 179 | autoscaling_enabled = true 180 | min_replicas = var.min_replicas 181 | max_replicas = var.max_replicas 182 | cooldown_period = var.cooldown_period 183 | } 184 | -------------------------------------------------------------------------------- /modules/tfc-agent-mig-container-vm/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | dind_volume_mounts = var.dind ? [{ 19 | mountPath = "/var/run/docker.sock" 20 | name = "dockersock" 21 | readOnly = false 22 | }] : [] 23 | dind_volumes = var.dind ? [ 24 | { 25 | name = "dockersock" 26 | 27 | hostPath = { 28 | path = "/var/run/docker.sock" 29 | } 30 | }] : [] 31 | network_name = var.create_network ? google_compute_network.tfc_agent_network[0].self_link : (var.subnet_name != "" ? null : var.network_name) 32 | subnet_name = var.create_network ? google_compute_subnetwork.tfc_agent_subnetwork[0].self_link : var.subnet_name 33 | service_account_email = var.create_service_account ? google_service_account.tfc_agent_service_account[0].email : var.service_account_email 34 | instance_name = "${var.tfc_agent_name_prefix}-${random_string.suffix.result}" 35 | } 36 | 37 | resource "random_string" "suffix" { 38 | length = 4 39 | special = false 40 | upper = false 41 | } 42 | 43 | /***************************************** 44 | Optional TFC agent Networking 45 | *****************************************/ 46 | 47 | resource "google_compute_network" "tfc_agent_network" { 48 | count = var.create_network ? 1 : 0 49 | name = var.network_name 50 | project = var.project_id 51 | auto_create_subnetworks = false 52 | } 53 | 54 | resource "google_compute_subnetwork" "tfc_agent_subnetwork" { 55 | count = var.create_network ? 1 : 0 56 | project = var.project_id 57 | name = var.subnet_name 58 | ip_cidr_range = var.subnet_ip 59 | region = var.region 60 | network = google_compute_network.tfc_agent_network[0].name 61 | } 62 | 63 | resource "google_compute_router" "default" { 64 | count = var.create_network ? 1 : 0 65 | name = "${var.network_name}-router" 66 | network = google_compute_network.tfc_agent_network[0].self_link 67 | region = var.region 68 | project = var.project_id 69 | } 70 | 71 | resource "google_compute_router_nat" "nat" { 72 | count = var.create_network ? 1 : 0 73 | project = var.project_id 74 | name = "${var.network_name}-nat" 75 | router = google_compute_router.default[0].name 76 | region = google_compute_router.default[0].region 77 | nat_ip_allocate_option = "AUTO_ONLY" 78 | source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" 79 | } 80 | 81 | /***************************************** 82 | IAM Bindings GCE SVC 83 | *****************************************/ 84 | 85 | resource "google_service_account" "tfc_agent_service_account" { 86 | count = var.create_service_account ? 1 : 0 87 | project = var.project_id 88 | account_id = "tfc-agent-mig-container-vm-sa" 89 | display_name = "Terrform agent GCE Service Account" 90 | } 91 | 92 | # allow GCE to pull images from GCR 93 | resource "google_project_iam_member" "gce" { 94 | count = var.create_service_account ? 1 : 0 95 | project = var.project_id 96 | role = "roles/storage.objectViewer" 97 | member = "serviceAccount:${local.service_account_email}" 98 | } 99 | 100 | /***************************************** 101 | TFC agent GCE Instance Template 102 | *****************************************/ 103 | 104 | module "gce_container" { 105 | source = "terraform-google-modules/container-vm/google" 106 | version = "~> 3.2" 107 | 108 | container = { 109 | image = var.image 110 | env = [ 111 | { 112 | name = "TFC_AGENT_NAME" 113 | value = local.instance_name 114 | }, 115 | { 116 | name = "TFC_AGENT_TOKEN" 117 | value = var.tfc_agent_token 118 | }, 119 | { 120 | name = "TFC_ADDRESS" 121 | value = var.tfc_agent_address 122 | }, 123 | { 124 | name = "TFC_AGENT_AUTO_UPDATE" 125 | value = var.tfc_agent_auto_update 126 | }, 127 | { 128 | name = "TFC_AGENT_SINGLE" 129 | value = var.tfc_agent_single 130 | } 131 | ] 132 | 133 | # Declare volumes to be mounted 134 | # This is similar to how Docker volumes are mounted 135 | volumeMounts = concat([ 136 | { 137 | mountPath = "/cache" 138 | name = "tempfs-0" 139 | readOnly = false 140 | } 141 | ], local.dind_volume_mounts) 142 | } 143 | 144 | # Declare the volumes 145 | volumes = concat([ 146 | { 147 | name = "tempfs-0" 148 | 149 | emptyDir = { 150 | medium = "Memory" 151 | } 152 | } 153 | ], local.dind_volumes) 154 | 155 | restart_policy = var.restart_policy 156 | } 157 | 158 | module "mig_template" { 159 | source = "terraform-google-modules/vm/google//modules/instance_template" 160 | version = "~> 12.0" 161 | 162 | region = var.region 163 | project_id = var.project_id 164 | network = local.network_name 165 | subnetwork = local.subnet_name 166 | subnetwork_project = var.subnetwork_project != "" ? var.subnetwork_project : var.project_id 167 | service_account = { 168 | email = local.service_account_email 169 | scopes = [ 170 | "https://www.googleapis.com/auth/cloud-platform", 171 | ] 172 | } 173 | disk_size_gb = 100 174 | disk_type = "pd-ssd" 175 | auto_delete = true 176 | source_image_family = "cos-stable" 177 | source_image_project = "cos-cloud" 178 | startup_script = var.startup_script 179 | name_prefix = var.tfc_agent_name_prefix 180 | source_image = reverse(split("/", module.gce_container.source_image))[0] 181 | metadata = merge(var.additional_metadata, { 182 | google-logging-enabled = "true" 183 | "gce-container-declaration" = module.gce_container.metadata_value 184 | }) 185 | tags = [ 186 | local.instance_name 187 | ] 188 | labels = { 189 | container-vm = module.gce_container.vm_container_label 190 | } 191 | } 192 | 193 | /***************************************** 194 | TFC agent MIG 195 | *****************************************/ 196 | 197 | module "mig" { 198 | source = "terraform-google-modules/vm/google//modules/mig" 199 | version = "~> 12.0" 200 | 201 | region = var.region 202 | project_id = var.project_id 203 | target_size = var.target_size 204 | hostname = local.instance_name 205 | instance_template = module.mig_template.self_link 206 | 207 | /* autoscaler */ 208 | autoscaling_enabled = var.autoscaling_enabled 209 | cooldown_period = var.cooldown_period 210 | } 211 | -------------------------------------------------------------------------------- /modules/tfc-agent-gke/main.tf: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2023 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | locals { 18 | network_name = var.create_network ? google_compute_network.tfc_agent_network[0].name : var.network_name 19 | subnet_name = var.create_network ? google_compute_subnetwork.tfc_agent_subnetwork[0].name : var.subnet_name 20 | service_account_email = var.create_service_account ? google_service_account.tfc_agent_service_account[0].email : var.service_account_email 21 | tfc_agent_name = "${var.tfc_agent_name_prefix}-${random_string.suffix.result}" 22 | } 23 | 24 | resource "random_string" "suffix" { 25 | length = 4 26 | special = false 27 | upper = false 28 | } 29 | 30 | /***************************************** 31 | Optional Network 32 | *****************************************/ 33 | 34 | resource "google_compute_network" "tfc_agent_network" { 35 | count = var.create_network ? 1 : 0 36 | name = var.network_name 37 | project = var.project_id 38 | auto_create_subnetworks = false 39 | } 40 | 41 | resource "google_compute_subnetwork" "tfc_agent_subnetwork" { 42 | count = var.create_network ? 1 : 0 43 | project = var.project_id 44 | name = var.subnet_name 45 | ip_cidr_range = var.subnet_ip 46 | region = var.region 47 | network = google_compute_network.tfc_agent_network[0].name 48 | 49 | secondary_ip_range { 50 | range_name = var.ip_range_pods_name 51 | ip_cidr_range = var.ip_range_pods_cidr 52 | } 53 | 54 | secondary_ip_range { 55 | range_name = var.ip_range_services_name 56 | ip_cidr_range = var.ip_range_services_cider 57 | } 58 | } 59 | 60 | /***************************************** 61 | IAM Bindings GKE 62 | *****************************************/ 63 | 64 | resource "google_service_account" "tfc_agent_service_account" { 65 | count = var.create_service_account ? 1 : 0 66 | project = var.project_id 67 | account_id = "tfc-agent-gke" 68 | display_name = "Terraform Cloud agent GKE Service Account" 69 | } 70 | 71 | /***************************************** 72 | TFC agent GKE 73 | *****************************************/ 74 | 75 | module "tfc_agent_cluster" { 76 | source = "terraform-google-modules/kubernetes-engine/google//modules/beta-public-cluster/" 77 | version = "~> 34.0" 78 | project_id = var.project_id 79 | region = var.region 80 | zones = var.zones 81 | network = local.network_name 82 | name = local.tfc_agent_name 83 | subnetwork = local.subnet_name 84 | service_account = local.service_account_email 85 | network_project_id = var.network_project_id != "" ? var.network_project_id : var.project_id 86 | ip_range_pods = var.ip_range_pods_name 87 | ip_range_services = var.ip_range_services_name 88 | logging_service = "logging.googleapis.com/kubernetes" 89 | monitoring_service = "monitoring.googleapis.com/kubernetes" 90 | remove_default_node_pool = true 91 | regional = false 92 | gce_pd_csi_driver = true 93 | deletion_protection = false 94 | node_pools = [ 95 | { 96 | name = "tfc-agent-pool" 97 | min_count = var.min_node_count 98 | max_count = var.max_node_count 99 | auto_upgrade = true 100 | machine_type = var.machine_type 101 | } 102 | ] 103 | } 104 | 105 | /***************************************** 106 | K8S resources for configuring TFC agent 107 | *****************************************/ 108 | 109 | data "google_client_config" "default" { 110 | } 111 | 112 | resource "kubernetes_secret" "tfc_agent_secrets" { 113 | metadata { 114 | name = var.tfc_agent_k8s_secrets 115 | } 116 | data = { 117 | tfc_agent_address = var.tfc_agent_address 118 | tfc_agent_token = var.tfc_agent_token 119 | tfc_agent_single = var.tfc_agent_single 120 | tfc_agent_auto_update = var.tfc_agent_auto_update 121 | tfc_agent_name = local.tfc_agent_name 122 | } 123 | } 124 | 125 | # Deploy the agent 126 | resource "kubernetes_deployment" "tfc_agent_deployment" { 127 | metadata { 128 | name = "${local.tfc_agent_name}-deployment" 129 | } 130 | 131 | spec { 132 | selector { 133 | match_labels = { 134 | app = local.tfc_agent_name 135 | } 136 | } 137 | 138 | replicas = var.tfc_agent_min_replicas 139 | 140 | template { 141 | metadata { 142 | labels = { 143 | app = local.tfc_agent_name 144 | } 145 | } 146 | 147 | spec { 148 | container { 149 | name = local.tfc_agent_name 150 | image = var.tfc_agent_image 151 | 152 | env { 153 | name = "TFC_ADDRESS" 154 | value_from { 155 | secret_key_ref { 156 | name = var.tfc_agent_k8s_secrets 157 | key = "tfc_agent_address" 158 | } 159 | } 160 | } 161 | 162 | env { 163 | name = "TFC_AGENT_TOKEN" 164 | value_from { 165 | secret_key_ref { 166 | name = var.tfc_agent_k8s_secrets 167 | key = "tfc_agent_token" 168 | } 169 | } 170 | } 171 | 172 | env { 173 | name = "TFC_AGENT_NAME" 174 | value_from { 175 | secret_key_ref { 176 | name = var.tfc_agent_k8s_secrets 177 | key = "tfc_agent_name" 178 | } 179 | } 180 | } 181 | 182 | env { 183 | name = "TFC_AGENT_SINGLE" 184 | value_from { 185 | secret_key_ref { 186 | name = var.tfc_agent_k8s_secrets 187 | key = "tfc_agent_single" 188 | } 189 | } 190 | } 191 | 192 | env { 193 | name = "TFC_AGENT_AUTO_UPDATE" 194 | value_from { 195 | secret_key_ref { 196 | name = var.tfc_agent_k8s_secrets 197 | key = "tfc_agent_auto_update" 198 | } 199 | } 200 | } 201 | 202 | # https://developer.hashicorp.com/terraform/cloud-docs/agents/requirements 203 | resources { 204 | requests = { 205 | memory = var.tfc_agent_memory_request 206 | cpu = var.tfc_agent_cpu_request 207 | } 208 | } 209 | } 210 | } 211 | } 212 | } 213 | } 214 | 215 | # Deploy a horizontal pod autoscaler for the agent 216 | resource "kubernetes_horizontal_pod_autoscaler_v2" "tfc_agent_hpa" { 217 | metadata { 218 | name = "${local.tfc_agent_name}-deployment-hpa" 219 | } 220 | 221 | spec { 222 | scale_target_ref { 223 | kind = "Deployment" 224 | name = "${local.tfc_agent_name}-deployment" 225 | } 226 | 227 | min_replicas = var.tfc_agent_min_replicas 228 | max_replicas = var.tfc_agent_max_replicas 229 | 230 | metric { 231 | type = "Resource" 232 | 233 | resource { 234 | name = "cpu" 235 | 236 | target { 237 | type = "Utilization" 238 | average_utilization = 50 239 | } 240 | } 241 | } 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------
"iam.googleapis.com",
"cloudresourcemanager.googleapis.com",
"sts.googleapis.com",
"iamcredentials.googleapis.com"
]