├── module-sample ├── README.md ├── main.tf ├── outputs.tf ├── variables.tf ├── versions.tf └── modules │ ├── README.md │ ├── main.tf │ ├── outputs.tf │ ├── versions.tf │ └── variables.tf ├── lint-and-validation ├── terraform-validate │ ├── README.md │ └── main.tf ├── tflint │ ├── README.md │ ├── .tflint.hcl │ └── main.tf ├── terraform-fmt │ ├── README.md │ └── main.tf └── conftest │ ├── policy │ ├── tf.rego │ ├── tf_test.rego │ ├── plan.rego │ └── plan_test.rego │ ├── main.tf │ └── README.md ├── module-test ├── README.md ├── versions.tf ├── modules │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── variables.tf ├── outputs.tf ├── terraform.tfvars.sample ├── main.tf ├── variables.tf └── .terraform.lock.hcl ├── version-and-provider ├── README.md ├── main.tf └── .terraform.lock.hcl ├── terraformer-test ├── main.tf ├── generated │ └── google │ │ └── terraform-toshi0607 │ │ ├── instances │ │ └── asia-northeast1 │ │ │ ├── outputs.tf │ │ │ ├── provider.tf │ │ │ └── compute_instance.tf │ │ └── terraformer │ │ └── asia-northeast1 │ │ └── plan.json ├── .terraform.lock.hcl └── README.md ├── state-separation ├── modules │ ├── versions.tf │ ├── outputs.tf │ ├── main.tf │ └── variables.tf ├── development │ ├── versions.tf │ ├── outputs.tf │ ├── terraform.tfvars.sample │ ├── main.tf │ └── variables.tf ├── production │ ├── versions.tf │ ├── outputs.tf │ ├── terraform.tfvars.sample │ ├── main.tf │ └── variables.tf └── README.md ├── gke-microservice └── README.md ├── two-layer-architecture ├── outputs.tf ├── terraform.tfvars.sapmple ├── variables.tf ├── README.md ├── .terraform.lock.hcl ├── gceme.sh.tpl ├── main.tf └── graph ├── count ├── .terraform.lock.hcl ├── README.md └── main.tf ├── dynamic ├── .terraform.lock.hcl ├── README.md └── main.tf ├── locals ├── .terraform.lock.hcl ├── README.md └── main.tf ├── moved ├── .terraform.lock.hcl ├── main.tf └── README.md ├── output ├── .terraform.lock.hcl ├── README.md └── main.tf ├── condition ├── .terraform.lock.hcl ├── README.md └── main.tf ├── data-sources ├── .terraform.lock.hcl ├── README.md └── main.tf ├── for_each ├── .terraform.lock.hcl ├── README.md └── main.tf ├── remote-backend ├── README.md ├── main.tf └── .terraform.lock.hcl ├── variable ├── .terraform.lock.hcl ├── README.md └── main.tf ├── basic ├── README.md ├── main.tf └── .terraform.lock.hcl ├── .gitignore └── README.md /module-sample/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/main.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/outputs.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/versions.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/modules/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/modules/main.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/modules/outputs.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/modules/versions.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /module-sample/modules/variables.tf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lint-and-validation/terraform-validate/README.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ terraform init 3 | 4 | $ tf validate 5 | ``` -------------------------------------------------------------------------------- /lint-and-validation/tflint/README.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ brew install tflint 3 | $ tflint --init 4 | $ tflint 5 | ``` 6 | -------------------------------------------------------------------------------- /module-test/README.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | $ terraform init 3 | $ terraform plan 4 | $ terraform apply 5 | $ terraform destroy 6 | ``` 7 | -------------------------------------------------------------------------------- /lint-and-validation/terraform-fmt/README.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ terraform fmt -diff=true -check=true -recursive 3 | 4 | $ terraform fmt 5 | ``` -------------------------------------------------------------------------------- /module-test/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /version-and-provider/README.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | $ terraform init 3 | $ terraform plan 4 | $ terraform apply 5 | $ terraform destroy 6 | ``` 7 | -------------------------------------------------------------------------------- /terraformer-test/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | google = ">= 4.32.0" 4 | } 5 | required_version = ">= 0.13" 6 | } 7 | -------------------------------------------------------------------------------- /module-test/modules/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /state-separation/modules/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /gke-microservice/README.md: -------------------------------------------------------------------------------- 1 | [toshi0607/GKE-Microservices-Terraform-project-template](https://github.com/toshi0607/GKE-Microservices-Terraform-project-template) 2 | -------------------------------------------------------------------------------- /state-separation/development/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /state-separation/production/versions.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /module-test/modules/outputs.tf: -------------------------------------------------------------------------------- 1 | output "self_link" { 2 | description = "A self link of an instance" 3 | value = google_compute_instance.default.self_link 4 | } 5 | -------------------------------------------------------------------------------- /module-test/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_self_link" { 2 | description = "A self link of an instance in the module" 3 | value = module.test_instance.self_link 4 | } 5 | -------------------------------------------------------------------------------- /state-separation/modules/outputs.tf: -------------------------------------------------------------------------------- 1 | output "self_link" { 2 | description = "A self link of an instance" 3 | value = google_compute_instance.default.self_link 4 | } 5 | -------------------------------------------------------------------------------- /state-separation/development/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_self_link" { 2 | description = "A self link of an instance in the module" 3 | value = module.test_instance.self_link 4 | } 5 | -------------------------------------------------------------------------------- /state-separation/production/outputs.tf: -------------------------------------------------------------------------------- 1 | output "instance_self_link" { 2 | description = "A self link of an instance in the module" 3 | value = module.test_instance.self_link 4 | } 5 | -------------------------------------------------------------------------------- /lint-and-validation/conftest/policy/tf.rego: -------------------------------------------------------------------------------- 1 | package tf 2 | 3 | deny[msg] { 4 | p := input.provider[_] 5 | p.version 6 | msg := "Provider version must be specified in required_providers block" 7 | } 8 | -------------------------------------------------------------------------------- /two-layer-architecture/outputs.tf: -------------------------------------------------------------------------------- 1 | output "external_ip" { 2 | description = "The external IP assigned to the global fowarding rule." 3 | value = google_compute_global_forwarding_rule.default.ip_address 4 | } 5 | -------------------------------------------------------------------------------- /terraformer-test/generated/google/terraform-toshi0607/instances/asia-northeast1/outputs.tf: -------------------------------------------------------------------------------- 1 | output "google_compute_instance_tfer--test-terraformer_self_link" { 2 | value = "${google_compute_instance.tfer--test-terraformer.self_link}" 3 | } 4 | -------------------------------------------------------------------------------- /lint-and-validation/conftest/main.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | version = ">= 4.32.0" 3 | } 4 | 5 | resource "google_project_service" "gcp_api_service" { 6 | service = "iam.googleapis.com" 7 | 8 | disable_dependent_services = true 9 | } 10 | -------------------------------------------------------------------------------- /lint-and-validation/tflint/.tflint.hcl: -------------------------------------------------------------------------------- 1 | plugin "google" { 2 | enabled = true 3 | version = "0.19.0" 4 | source = "github.com/terraform-linters/tflint-ruleset-google" 5 | } 6 | 7 | rule "google_compute_address_invalid_address_type" { 8 | enabled = true 9 | } 10 | -------------------------------------------------------------------------------- /module-test/terraform.tfvars.sample: -------------------------------------------------------------------------------- 1 | # remove .sample when you try tfvars 2 | 3 | # replace 【YOUR PROJECT】 with your project 4 | # e.g. 5 | # project = "terraform-toshi0607" 6 | 7 | project = 【YOUR PROJECT】 8 | region = "asia-northeast1" 9 | zone = "asia-northeast1-c" 10 | -------------------------------------------------------------------------------- /terraformer-test/generated/google/terraform-toshi0607/instances/asia-northeast1/provider.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = "terraform-toshi0607" 3 | } 4 | 5 | terraform { 6 | required_providers { 7 | google = { 8 | version = "~> 4.32.0" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /two-layer-architecture/terraform.tfvars.sapmple: -------------------------------------------------------------------------------- 1 | # remove .sample when you try tfvars 2 | 3 | # replace 【YOUR PROJECT】 with your project 4 | # e.g. 5 | # project = "terraform-toshi0607" 6 | gcp_project = 【YOUR PROJECT】 7 | gcp_region = "asia-northeast1" 8 | gcp_zone = "asia-northeast1-c" 9 | -------------------------------------------------------------------------------- /state-separation/development/terraform.tfvars.sample: -------------------------------------------------------------------------------- 1 | # remove .sample when you try tfvars 2 | 3 | # replace 【YOUR PROJECT】 with your project 4 | # e.g. 5 | # project = "terraform-toshi0607" 6 | 7 | project = 【YOUR PROJECT】 8 | region = "asia-northeast1" 9 | zone = "asia-northeast1-c" 10 | -------------------------------------------------------------------------------- /count/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /dynamic/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /locals/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /moved/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /output/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /condition/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /data-sources/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /for_each/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /remote-backend/README.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | # Bucket name must be globally unique. Change toshi0607-20200827 to waht you like. 3 | $ gsutil mb -l ASIA-NORTHEAST1 gs://tf-state-toshi0607-20200827-dev 4 | # Update main.tf 5 | 6 | $ terraform init 7 | $ terraform plan 8 | $ terraform apply 9 | $ terraform destroy 10 | ``` 11 | -------------------------------------------------------------------------------- /variable/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /lint-and-validation/conftest/README.md: -------------------------------------------------------------------------------- 1 | ```console 2 | $ brew tap instrumenta/instrumenta 3 | $ brew install conftest 4 | 5 | $ conftest test --namespace tf main.tf 6 | 7 | $ terraform init 8 | $ terraform plan --out plan.out 2>&1 9 | $ terraform show -json plan.out > plan.out.json 10 | $ conftest test --namespace plan plan.out.json 11 | ``` -------------------------------------------------------------------------------- /module-test/main.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = var.project 3 | region = var.region 4 | zone = var.zone 5 | } 6 | 7 | module "test_instance" { 8 | source = "./modules" 9 | 10 | project = var.project 11 | zone = var.zone 12 | service_name = "test-service" 13 | environment = "development" 14 | } 15 | -------------------------------------------------------------------------------- /state-separation/production/terraform.tfvars.sample: -------------------------------------------------------------------------------- 1 | # remove .sample when you try tfvars 2 | 3 | # replace 【YOUR PROJECT】 with your project 4 | # e.g. 5 | # project = "terraform-toshi0607" 6 | # it is better to use different dev project from prod for isolation 7 | project = 【YOUR PROJECT】 8 | region = "asia-northeast1" 9 | zone = "asia-northeast1-c" 10 | -------------------------------------------------------------------------------- /terraformer-test/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | constraints = ">= 4.32.0" 7 | hashes = [ 8 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /lint-and-validation/terraform-fmt/main.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "tf_fmt_example" { 2 | name = "tf-fmt-test" 3 | machine_type = "f1-micro" 4 | zone = "asia-northeast1-c" 5 | 6 | boot_disk { 7 | initialize_params { 8 | image = "debian-cloud/debian-11" 9 | } 10 | } 11 | 12 | network_interface { 13 | network = "default" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /two-layer-architecture/variables.tf: -------------------------------------------------------------------------------- 1 | variable "gcp_project" { 2 | type = string 3 | description = "GCP project name" 4 | } 5 | 6 | # https://cloud.google.com/compute/docs/regions-zones 7 | variable "gcp_region" { 8 | type = string 9 | description = "GCP region" 10 | } 11 | 12 | variable "gcp_zone" { 13 | type = string 14 | description = "GCP zone" 15 | } 16 | -------------------------------------------------------------------------------- /basic/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | ``` -------------------------------------------------------------------------------- /count/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | ``` 16 | -------------------------------------------------------------------------------- /for_each/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | ``` 16 | -------------------------------------------------------------------------------- /lint-and-validation/terraform-validate/main.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "tf_validate_example" { 2 | name = "tf-validate-test" 3 | machine_type = "f1-micro" 4 | zone = "asia-northeast1-c" 5 | 6 | boot_disk { 7 | initialize_params = { 8 | image = "debian-cloud/debian-11" 9 | } 10 | } 11 | 12 | network_interface { 13 | network = var.hoge 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /output/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | ``` 16 | -------------------------------------------------------------------------------- /data-sources/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | ``` 16 | -------------------------------------------------------------------------------- /locals/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | Terraform 0.13.0 or later is required. 3 | 4 | ```shell 5 | $ gcloud auth application-default login 6 | 7 | # replace 【YOUR PROJECT】 with your project 8 | # e.g. 9 | # export GOOGLE_PROJECT=terraform-toshi0607 10 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 11 | 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | $ terraform destroy 16 | ``` 17 | -------------------------------------------------------------------------------- /variable/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | Terraform 0.13.0 or later is required. 3 | 4 | ```shell 5 | $ gcloud auth application-default login 6 | 7 | # replace 【YOUR PROJECT】 with your project 8 | # e.g. 9 | # export GOOGLE_PROJECT=terraform-toshi0607 10 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 11 | 12 | $ terraform init 13 | $ terraform plan 14 | $ terraform apply 15 | $ terraform destroy 16 | ``` 17 | -------------------------------------------------------------------------------- /condition/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | 14 | $ terraform plan -var="vm_enable=true" 15 | $ terraform apply -var="vm_enable=true" 16 | 17 | $ terraform destroy 18 | ``` 19 | -------------------------------------------------------------------------------- /condition/main.tf: -------------------------------------------------------------------------------- 1 | variable "vm_enable" { 2 | type = bool 3 | default = false 4 | } 5 | 6 | resource "google_compute_instance" "default" { 7 | count = var.vm_enable ? 1 : 0 8 | 9 | name = "test" 10 | machine_type = "n2-standard-2" 11 | zone = "asia-northeast1-c" 12 | 13 | boot_disk { 14 | initialize_params { 15 | image = "debian-cloud/debian-11" 16 | } 17 | } 18 | 19 | network_interface { 20 | network = "default" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /data-sources/main.tf: -------------------------------------------------------------------------------- 1 | data "google_compute_zones" "available" { 2 | region = "asia-northeast1" 3 | status = "UP" 4 | } 5 | 6 | resource "google_compute_instance" "default" { 7 | name = "test" 8 | machine_type = "f1-micro" 9 | zone = data.google_compute_zones.available.names[0] 10 | 11 | boot_disk { 12 | initialize_params { 13 | image = "debian-cloud/debian-11" 14 | } 15 | } 16 | 17 | network_interface { 18 | network = "default" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /output/main.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "default" { 2 | name = "test" 3 | machine_type = "f1-micro" 4 | zone = "asia-northeast1-c" 5 | 6 | boot_disk { 7 | initialize_params { 8 | image = "debian-cloud/debian-11" 9 | } 10 | } 11 | 12 | network_interface { 13 | network = "default" 14 | } 15 | } 16 | 17 | output "cpu_platform" { 18 | description = "CPU platform of the instance" 19 | value = google_compute_instance.default.cpu_platform 20 | } 21 | -------------------------------------------------------------------------------- /two-layer-architecture/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | 16 | # Exec the folowing command to output show dependency 17 | $ terraform graph 18 | ``` 19 | -------------------------------------------------------------------------------- /dynamic/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # replace 【YOUR PROJECT】 with your project 7 | # e.g. 8 | # export GOOGLE_PROJECT=terraform-toshi0607 9 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 10 | 11 | $ terraform init 12 | $ terraform plan 13 | 14 | # If you want to apply this google_compute_instance resource with node_affinities, you need sole tenant. 15 | # See https://cloud.google.com/compute/docs/nodes/provisioning-sole-tenant-vms 16 | ``` 17 | -------------------------------------------------------------------------------- /module-test/modules/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | common_labels = { 3 | service = var.service_name 4 | environment = var.environment 5 | } 6 | } 7 | 8 | resource "google_compute_instance" "default" { 9 | project = var.project 10 | zone = var.zone 11 | 12 | name = "${var.service_name}-vm" 13 | 14 | machine_type = var.machine_type 15 | 16 | labels = local.common_labels 17 | 18 | boot_disk { 19 | initialize_params { 20 | image = "debian-cloud/debian-11" 21 | } 22 | } 23 | 24 | network_interface { 25 | network = "default" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /state-separation/modules/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | common_labels = { 3 | service = var.service_name 4 | environment = var.environment 5 | } 6 | } 7 | 8 | resource "google_compute_instance" "default" { 9 | project = var.project 10 | zone = var.zone 11 | 12 | name = "${var.service_name}-vm" 13 | 14 | machine_type = var.machine_type 15 | 16 | labels = local.common_labels 17 | 18 | boot_disk { 19 | initialize_params { 20 | image = "debian-cloud/debian-11" 21 | } 22 | } 23 | 24 | network_interface { 25 | network = "default" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /moved/main.tf: -------------------------------------------------------------------------------- 1 | moved { 2 | from = google_compute_instance.before-move 3 | to = google_compute_instance.after-move 4 | } 5 | 6 | resource "google_compute_instance" "after-move" { 7 | # resource "google_compute_instance" "before-move" { 8 | name = "moved" 9 | machine_type = "f1-micro" 10 | zone = "asia-northeast1-c" 11 | 12 | boot_disk { 13 | initialize_params { 14 | # gcloud compute images list | grep debian, if the image can't be found 15 | image = "debian-cloud/debian-11" 16 | } 17 | } 18 | 19 | network_interface { 20 | network = "default" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /state-separation/development/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | backend "gcs" { 3 | # replace 【YOUR BUCKET】 with your project 4 | # e.g. 5 | # bucket = "tf-state-toshi0607-20200827-dev" 6 | bucket = 【YOUR BUCKET】 7 | prefix = "terraform/test_instance/state" 8 | } 9 | } 10 | 11 | provider "google" { 12 | project = var.project 13 | region = var.region 14 | zone = var.zone 15 | } 16 | 17 | module "test_instance" { 18 | source = "../modules" 19 | 20 | project = var.project 21 | zone = var.zone 22 | service_name = "test-development" 23 | environment = "development" 24 | } 25 | -------------------------------------------------------------------------------- /state-separation/production/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | backend "gcs" { 3 | # replace 【YOUR BUCKET】 with your project 4 | # e.g. 5 | # bucket = "tf-state-toshi0607-20200827-prod" 6 | bucket = 【YOUR BUCKET】 7 | prefix = "terraform/test_instance/state" 8 | } 9 | } 10 | 11 | provider "google" { 12 | project = var.project 13 | region = var.region 14 | zone = var.zone 15 | } 16 | 17 | module "test_instance" { 18 | source = "../modules" 19 | 20 | project = var.project 21 | zone = var.zone 22 | service_name = "test-production" 23 | environment = "production" 24 | } 25 | -------------------------------------------------------------------------------- /basic/main.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "default" { 2 | // Change when trying create_before_destroy sample 3 | // name = "test2" 4 | name = "test" 5 | machine_type = "f1-micro" 6 | zone = "asia-northeast1-c" 7 | 8 | boot_disk { 9 | initialize_params { 10 | # gcloud compute images list | grep debian, if the image can't be found 11 | image = "debian-cloud/debian-11" 12 | } 13 | } 14 | 15 | network_interface { 16 | network = "default" 17 | } 18 | 19 | # create_before_destroy sample 20 | # lifecycle { 21 | # create_before_destroy = true 22 | # } 23 | } 24 | -------------------------------------------------------------------------------- /lint-and-validation/conftest/policy/tf_test.rego: -------------------------------------------------------------------------------- 1 | package tf 2 | 3 | empty(value) { 4 | count(value) == 0 5 | } 6 | 7 | non_empty(value) { 8 | count(value) > 0 9 | } 10 | 11 | violations { 12 | non_empty(deny) 13 | } 14 | 15 | no_violations { 16 | empty(deny) 17 | } 18 | 19 | test_provider_with_version_is_denied { 20 | input := { 21 | "provider": { { "version": ">= 4.32.0", "region": "somewhere" } } 22 | } 23 | violations with input as input 24 | } 25 | 26 | test_provider_without_version_is_allowed { 27 | input := { 28 | "provider": { { "region": "somewhere" } } 29 | } 30 | no_violations with input as input 31 | } 32 | -------------------------------------------------------------------------------- /moved/README.md: -------------------------------------------------------------------------------- 1 | This example doesn't specify a credential and a project intentionally. 2 | 3 | ```shell 4 | $ gcloud auth application-default login 5 | 6 | # export GOOGLE_PROJECT=terraform-toshi0607 7 | # 【YOUR PROJECT】をあなたのGCPプロジェクトに置き換えてください。 8 | $ export GOOGLE_PROJECT=【YOUR PROJECT】 9 | 10 | $ terraform init 11 | $ terraform plan 12 | $ terraform apply 13 | 14 | # Change resource name from before-move to after-move 15 | # Confirm resource recreation (+ create and -destroy) would happen 16 | $ terraform plan 17 | 18 | # Enable (comment in moved block) 19 | # Confirm resource recreation would NOT happen 20 | $ terraform plan 21 | $ terraform apply 22 | 23 | $ terraform destroy 24 | ``` -------------------------------------------------------------------------------- /lint-and-validation/conftest/policy/plan.rego: -------------------------------------------------------------------------------- 1 | package plan 2 | 3 | deny[msg] { 4 | changes := input.resource_changes[_] 5 | changes.type = "google_project_service" 6 | changes[_].after.disable_on_destroy == true 7 | 8 | msg := "google_project_service.disable_on_destroy must be false not to disable APIs unintentionally." 9 | } 10 | 11 | warning[msg] { 12 | changes := input.resource_changes[_] 13 | changes.type = "google_project_iam_member" 14 | changes[_].after.role == "roles/admin" 15 | is_production(changes[_].after.project) 16 | 17 | msg := "Admin role is not allowed in prod because of zero touch production." 18 | } 19 | 20 | is_production(project) { 21 | endswith(project, "prod") 22 | } 23 | -------------------------------------------------------------------------------- /state-separation/README.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | # Bucket name must be globally unique. Change toshi0607-20200827 to waht you like. 3 | $ gsutil mb -l ASIA-NORTHEAST1 gs://tf-state-toshi0607-20200827-dev 4 | 5 | # 6 | # development 7 | # 8 | $ cd development 9 | # Update main.tf 10 | 11 | $ terraform init 12 | $ terraform plan 13 | $ terraform apply 14 | $ terraform destroy 15 | 16 | # 17 | # production 18 | # 19 | $ cd ../production 20 | # Bucket name must be globally unique. Change toshi0607-20200827 to waht you like. 21 | $ gsutil mb -l ASIA-NORTHEAST1 gs://tf-state-toshi0607-20200827-prod 22 | Creating gs://tf-state-toshi0607-0827-prod/... 23 | # Update main.tf 24 | 25 | $ terraform init 26 | $ terraform plan 27 | $ terraform apply 28 | $ terraform destroy 29 | ``` 30 | -------------------------------------------------------------------------------- /variable/main.tf: -------------------------------------------------------------------------------- 1 | variable "compute_instance_zone" { 2 | type = string 3 | description = "A zone used in compute instance" 4 | default = "asia-northeast1-c" 5 | 6 | validation { 7 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.compute_instance_zone) 8 | error_message = "The compute_instance_zone must be in asia-northeast1 region." 9 | } 10 | } 11 | 12 | resource "google_compute_instance" "default" { 13 | name = "test" 14 | machine_type = "f1-micro" 15 | zone = var.compute_instance_zone 16 | 17 | boot_disk { 18 | initialize_params { 19 | image = "debian-cloud/debian-11" 20 | } 21 | } 22 | 23 | network_interface { 24 | network = "default" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /module-test/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project" { 2 | description = "A name of a GCP project" 3 | type = string 4 | default = null 5 | } 6 | 7 | variable "region" { 8 | description = "A region to use the module" 9 | type = string 10 | default = "asia-northeast1" 11 | 12 | validation { 13 | condition = var.region == "asia-northeast1" 14 | error_message = "The region must be asia-northeast1." 15 | } 16 | } 17 | 18 | variable "zone" { 19 | description = "A zone to use the module" 20 | type = string 21 | default = "asia-northeast1-c" 22 | 23 | validation { 24 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.zone) 25 | error_message = "The zone must be in asia-northeast1 region." 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /terraformer-test/README.md: -------------------------------------------------------------------------------- 1 | ```shell 2 | $ terraform init 3 | 4 | $ mkdir -p $HOME/.terraform.d/plugins/darwin_amd64 5 | # plugin path is not propely handled at the time of writing 6 | $ cp .terraform/providers/registry.terraform.io/hashicorp/google/4.32.0/darwin_arm64/terraform-provider-google_v4.32.0_x5 \ 7 | $HOME/.terraform.d/plugins/darwin_amd64/terraform-provider-google_v4.32.0_x5 8 | 9 | # specify your project with --projects option 10 | $ terraformer plan google --resources=instances --filter=google_compute_instance=test-terraformer --projects=terraform-toshi0607 --regions=asia-northeast1 11 | 12 | # specify your project with --projects option 13 | $ terraformer import google --resources=instances --filter="google_compute_instance=test-terraformer" --projects=terraform-toshi0607 --regions=asia-northeast1 14 | ``` -------------------------------------------------------------------------------- /state-separation/production/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project" { 2 | description = "A name of a GCP project" 3 | type = string 4 | default = null 5 | } 6 | 7 | variable "region" { 8 | description = "A region to use the module" 9 | type = string 10 | default = "asia-northeast1" 11 | 12 | validation { 13 | condition = var.region == "asia-northeast1" 14 | error_message = "The region must be asia-northeast1." 15 | } 16 | } 17 | 18 | variable "zone" { 19 | description = "A zone to use the module" 20 | type = string 21 | default = "asia-northeast1-c" 22 | 23 | validation { 24 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.zone) 25 | error_message = "The zone must be in asia-northeast1 region." 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dynamic/main.tf: -------------------------------------------------------------------------------- 1 | variable node_affinities { 2 | type = list(object({ key = string, value= string})) 3 | default = [{key = "env", value = "dev"}, {key = "layer", value = "front"}] 4 | } 5 | 6 | resource "google_compute_instance" "default" { 7 | name = "test" 8 | machine_type = "n2-standard-2" 9 | zone = "asia-northeast1-c" 10 | 11 | boot_disk { 12 | initialize_params { 13 | image = "debian-cloud/debian-11" 14 | } 15 | } 16 | 17 | network_interface { 18 | network = "default" 19 | } 20 | 21 | scheduling { 22 | dynamic "node_affinities" { 23 | for_each = var.node_affinities 24 | content { 25 | key = node_affinities.value["key"] 26 | operator = "IN" 27 | values = [node_affinities.value["value"]] 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /state-separation/development/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project" { 2 | description = "A name of a GCP project" 3 | type = string 4 | default = null 5 | } 6 | 7 | variable "region" { 8 | description = "A region to use the module" 9 | type = string 10 | default = "asia-northeast1" 11 | 12 | validation { 13 | condition = var.region == "asia-northeast1" 14 | error_message = "The region must be asia-northeast1." 15 | } 16 | } 17 | 18 | variable "zone" { 19 | description = "A zone to use the module" 20 | type = string 21 | default = "asia-northeast1-c" 22 | 23 | validation { 24 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.zone) 25 | error_message = "The zone must be in asia-northeast1 region." 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /for_each/main.tf: -------------------------------------------------------------------------------- 1 | data "google_compute_zones" "available" { 2 | region = "asia-northeast1" 3 | status = "UP" 4 | } 5 | 6 | resource "google_compute_instance" "default" { 7 | for_each = toset(data.google_compute_zones.available.names) 8 | 9 | name = "test-${each.key}" 10 | machine_type = "f1-micro" 11 | zone = each.value 12 | 13 | boot_disk { 14 | initialize_params { 15 | image = "debian-cloud/debian-11" 16 | } 17 | } 18 | 19 | network_interface { 20 | network = "default" 21 | } 22 | } 23 | 24 | output "instance_names" { 25 | description = "Names of instances" 26 | value = values(google_compute_instance.default)[*].name 27 | } 28 | 29 | output "instance_zones" { 30 | description = "Zones of instances" 31 | value = values(google_compute_instance.default)[*].zone 32 | } 33 | -------------------------------------------------------------------------------- /count/main.tf: -------------------------------------------------------------------------------- 1 | data "google_compute_zones" "available" { 2 | region = "asia-northeast1" 3 | status = "UP" 4 | } 5 | 6 | resource "google_compute_instance" "default" { 7 | count = length(data.google_compute_zones.available.names) 8 | 9 | name = "test-${count.index}" 10 | machine_type = "f1-micro" 11 | zone = data.google_compute_zones.available.names[count.index] 12 | 13 | boot_disk { 14 | initialize_params { 15 | image = "debian-cloud/debian-11" 16 | } 17 | } 18 | 19 | network_interface { 20 | network = "default" 21 | } 22 | } 23 | 24 | output "instance_names" { 25 | description = "Names of instances" 26 | value = google_compute_instance.default[*].name 27 | } 28 | 29 | output "instance_zones" { 30 | description = "Zone of instances" 31 | value = google_compute_instance.default[*].zone 32 | } 33 | -------------------------------------------------------------------------------- /remote-backend/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | backend "gcs" { 3 | # replace 【YOUR BUCKET】 with your project 4 | # e.g. 5 | # bucket = "tf-state-toshi0607-20200827-dev" 6 | bucket = 【YOUR BUCKET】 7 | prefix = "terraform/state" 8 | } 9 | 10 | required_providers { 11 | google = ">= 4.32.0" 12 | } 13 | } 14 | 15 | provider "google" { 16 | # replace 【YOUR PROJECT】 with your project 17 | # e.g. 18 | # project = "terraform-toshi0607" 19 | project = 【YOUR PROJECT】 20 | region = "asia-northeast1" 21 | zone = "asia-northeast1-c" 22 | } 23 | 24 | resource "google_compute_instance" "default" { 25 | name = "test" 26 | machine_type = "f1-micro" 27 | 28 | boot_disk { 29 | initialize_params { 30 | image = "debian-cloud/debian-11" 31 | } 32 | } 33 | 34 | network_interface { 35 | network = "default" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /version-and-provider/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "~> 1.2" 3 | required_providers { 4 | google = ">= 4.32.0" 5 | } 6 | } 7 | 8 | provider "google" { 9 | # replace 【YOUR PROJECT】 with your project 10 | # e.g. 11 | # project = "terraform-toshi0607" 12 | project = 【YOUR PROJECT】 13 | zone = "asia-northeast1-c" 14 | } 15 | 16 | resource "google_compute_instance" "default" { 17 | name = "test" 18 | machine_type = "f1-micro" 19 | 20 | boot_disk { 21 | initialize_params { 22 | image = "debian-cloud/debian-11" 23 | } 24 | } 25 | 26 | network_interface { 27 | network = "default" 28 | } 29 | } 30 | 31 | output "project" { 32 | description = "Names of project" 33 | value = google_compute_instance.default.project 34 | } 35 | 36 | output "zone" { 37 | description = "Names of zone" 38 | value = google_compute_instance.default.zone 39 | } 40 | -------------------------------------------------------------------------------- /locals/main.tf: -------------------------------------------------------------------------------- 1 | variable "service_name" { 2 | description = "A name of the service" 3 | type = string 4 | default = "default" 5 | } 6 | 7 | variable "environment" { 8 | description = "An environment of the service" 9 | type = string 10 | default = "dev" 11 | 12 | validation { 13 | condition = contains(["dev", "stg", "prod"], var.environment) 14 | error_message = "The environment must be dev, stg or prod." 15 | } 16 | } 17 | 18 | locals { 19 | common_labels = { 20 | service = var.service_name 21 | environment = var.environment 22 | } 23 | } 24 | 25 | resource "google_compute_instance" "default" { 26 | name = "test" 27 | machine_type = "f1-micro" 28 | zone = "asia-northeast1-c" 29 | 30 | labels = local.common_labels 31 | 32 | boot_disk { 33 | initialize_params { 34 | image = "debian-cloud/debian-11" 35 | } 36 | } 37 | 38 | network_interface { 39 | network = "default" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Exclude all .tfvars files, which are likely to contain sentitive data, such as 12 | # password, private keys, and other secrets. These should not be part of version 13 | # control as they are data points which are potentially sensitive and subject 14 | # to change depending on the environment. 15 | # 16 | *.tfvars 17 | 18 | # Ignore override files as they are usually used to override resources locally and so 19 | # are not checked in 20 | override.tf 21 | override.tf.json 22 | *_override.tf 23 | *_override.tf.json 24 | 25 | # Include override files you do wish to add to version control using negated pattern 26 | # 27 | # !example_override.tf 28 | 29 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 30 | # example: *tfplan* 31 | 32 | # Ignore CLI configuration files 33 | .terraformrc 34 | terraform.rc 35 | 36 | config_cft-training.json 37 | -------------------------------------------------------------------------------- /lint-and-validation/tflint/main.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "tflint_example" { 2 | name = "tflint-test" 3 | machine_type = "invalid-machine-type" 4 | zone = "asia-northeast1-c" 5 | 6 | boot_disk { 7 | initialize_params { 8 | image = "debian-cloud/debian-11" 9 | } 10 | } 11 | 12 | network_interface { 13 | network = "default" 14 | } 15 | } 16 | 17 | resource "google_storage_bucket" "static_site" { 18 | name = "image-store.com" 19 | location = "EU" 20 | force_destroy = true 21 | 22 | uniform_bucket_level_access = true 23 | 24 | website { 25 | main_page_suffix = "index.html" 26 | not_found_page = "404.html" 27 | } 28 | cors { 29 | origin = ["http://image-store.com"] 30 | method = ["GET", "HEAD", "PUT", "POST", "DELETE"] 31 | response_header = ["*"] 32 | max_age_seconds = 3600 33 | } 34 | } 35 | 36 | resource "google_storage_default_object_access_control" "public_rule" { 37 | bucket = google_storage_bucket.static-site.name 38 | role = "READE" 39 | entity = "allUsers" 40 | } 41 | -------------------------------------------------------------------------------- /module-test/modules/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project" { 2 | description = "A name of a GCP project" 3 | type = string 4 | default = null 5 | } 6 | 7 | 8 | variable "zone" { 9 | description = "A zone used in a compute instance" 10 | type = string 11 | default = "asia-northeast1-c" 12 | 13 | validation { 14 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.zone) 15 | error_message = "The zone must be in asia-northeast1 region." 16 | } 17 | } 18 | 19 | variable "service_name" { 20 | description = "A name of a service" 21 | type = string 22 | } 23 | 24 | variable "environment" { 25 | description = "An environment of a service" 26 | type = string 27 | default = "development" 28 | 29 | validation { 30 | condition = contains(["development", "staging", "production"], var.environment) 31 | error_message = "The environment must be development, staging or production." 32 | } 33 | } 34 | 35 | variable "machine_type" { 36 | description = "A machine type of a compute instance" 37 | type = string 38 | default = "f1-micro" 39 | } 40 | -------------------------------------------------------------------------------- /state-separation/modules/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project" { 2 | description = "A name of a GCP project" 3 | type = string 4 | default = null 5 | } 6 | 7 | 8 | variable "zone" { 9 | description = "A zone used in a compute instance" 10 | type = string 11 | default = "asia-northeast1-c" 12 | 13 | validation { 14 | condition = contains(["asia-northeast1-a", "asia-northeast1-b", "asia-northeast1-c"], var.zone) 15 | error_message = "The zone must be in asia-northeast1 region." 16 | } 17 | } 18 | 19 | variable "service_name" { 20 | description = "A name of a service" 21 | type = string 22 | } 23 | 24 | variable "environment" { 25 | description = "An environment of a service" 26 | type = string 27 | default = "development" 28 | 29 | validation { 30 | condition = contains(["development", "staging", "production"], var.environment) 31 | error_message = "The environment must be development, staging or production." 32 | } 33 | } 34 | 35 | variable "machine_type" { 36 | description = "A machine type of a compute instance" 37 | type = string 38 | default = "f1-micro" 39 | } 40 | -------------------------------------------------------------------------------- /basic/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | "zh:03fa16d2811fc3ef523b8afad5ce4c1c72e686a425f48f9432f21b16c55c2872", 9 | "zh:23ad507dad0b3478c46b050f9d4660251e20b2ae6f334f4904af9aeef7e6f5d2", 10 | "zh:2a20c8c6bb1c8185c7c4b6e418cbdb36ab212c549ffa7ab4c027f929224798bc", 11 | "zh:53b8cd6ecc73c6fc1570dfbf9a549af975741c25cf544d6fec13d96c7312bd93", 12 | "zh:5856c11c35636c362e04ddaf3cce7ed94e0aea74f22b6d3fc2449f1c0ce4b159", 13 | "zh:68cda07855d20984d4fce6959a760392b1ef4e09e4f8e74bf10765b020727f0c", 14 | "zh:84b501635c135a692f378dec2e56beca088d25f5e6c98276dbab8de30d27ce5e", 15 | "zh:972e990c88f1b4c9bfe501e3a829c02bd89a494b3b445900216906365397a672", 16 | "zh:a47acfb0b07d83687fab00275381755817aacec6f9f949e8d52e0bcae45e870f", 17 | "zh:dcb078b2be1d8527e7bf9283112ba1214bb76d2279d78d921bebd413fb0310e0", 18 | "zh:e00a1b11f0782e389b02c8a4487b2f25c42647714adcb56770f87883440997e9", 19 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /module-test/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | constraints = ">= 4.32.0" 7 | hashes = [ 8 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 9 | "zh:03fa16d2811fc3ef523b8afad5ce4c1c72e686a425f48f9432f21b16c55c2872", 10 | "zh:23ad507dad0b3478c46b050f9d4660251e20b2ae6f334f4904af9aeef7e6f5d2", 11 | "zh:2a20c8c6bb1c8185c7c4b6e418cbdb36ab212c549ffa7ab4c027f929224798bc", 12 | "zh:53b8cd6ecc73c6fc1570dfbf9a549af975741c25cf544d6fec13d96c7312bd93", 13 | "zh:5856c11c35636c362e04ddaf3cce7ed94e0aea74f22b6d3fc2449f1c0ce4b159", 14 | "zh:68cda07855d20984d4fce6959a760392b1ef4e09e4f8e74bf10765b020727f0c", 15 | "zh:84b501635c135a692f378dec2e56beca088d25f5e6c98276dbab8de30d27ce5e", 16 | "zh:972e990c88f1b4c9bfe501e3a829c02bd89a494b3b445900216906365397a672", 17 | "zh:a47acfb0b07d83687fab00275381755817aacec6f9f949e8d52e0bcae45e870f", 18 | "zh:dcb078b2be1d8527e7bf9283112ba1214bb76d2279d78d921bebd413fb0310e0", 19 | "zh:e00a1b11f0782e389b02c8a4487b2f25c42647714adcb56770f87883440997e9", 20 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /remote-backend/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | constraints = ">= 4.32.0" 7 | hashes = [ 8 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 9 | "zh:03fa16d2811fc3ef523b8afad5ce4c1c72e686a425f48f9432f21b16c55c2872", 10 | "zh:23ad507dad0b3478c46b050f9d4660251e20b2ae6f334f4904af9aeef7e6f5d2", 11 | "zh:2a20c8c6bb1c8185c7c4b6e418cbdb36ab212c549ffa7ab4c027f929224798bc", 12 | "zh:53b8cd6ecc73c6fc1570dfbf9a549af975741c25cf544d6fec13d96c7312bd93", 13 | "zh:5856c11c35636c362e04ddaf3cce7ed94e0aea74f22b6d3fc2449f1c0ce4b159", 14 | "zh:68cda07855d20984d4fce6959a760392b1ef4e09e4f8e74bf10765b020727f0c", 15 | "zh:84b501635c135a692f378dec2e56beca088d25f5e6c98276dbab8de30d27ce5e", 16 | "zh:972e990c88f1b4c9bfe501e3a829c02bd89a494b3b445900216906365397a672", 17 | "zh:a47acfb0b07d83687fab00275381755817aacec6f9f949e8d52e0bcae45e870f", 18 | "zh:dcb078b2be1d8527e7bf9283112ba1214bb76d2279d78d921bebd413fb0310e0", 19 | "zh:e00a1b11f0782e389b02c8a4487b2f25c42647714adcb56770f87883440997e9", 20 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /version-and-provider/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | constraints = ">= 4.32.0" 7 | hashes = [ 8 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 9 | "zh:03fa16d2811fc3ef523b8afad5ce4c1c72e686a425f48f9432f21b16c55c2872", 10 | "zh:23ad507dad0b3478c46b050f9d4660251e20b2ae6f334f4904af9aeef7e6f5d2", 11 | "zh:2a20c8c6bb1c8185c7c4b6e418cbdb36ab212c549ffa7ab4c027f929224798bc", 12 | "zh:53b8cd6ecc73c6fc1570dfbf9a549af975741c25cf544d6fec13d96c7312bd93", 13 | "zh:5856c11c35636c362e04ddaf3cce7ed94e0aea74f22b6d3fc2449f1c0ce4b159", 14 | "zh:68cda07855d20984d4fce6959a760392b1ef4e09e4f8e74bf10765b020727f0c", 15 | "zh:84b501635c135a692f378dec2e56beca088d25f5e6c98276dbab8de30d27ce5e", 16 | "zh:972e990c88f1b4c9bfe501e3a829c02bd89a494b3b445900216906365397a672", 17 | "zh:a47acfb0b07d83687fab00275381755817aacec6f9f949e8d52e0bcae45e870f", 18 | "zh:dcb078b2be1d8527e7bf9283112ba1214bb76d2279d78d921bebd413fb0310e0", 19 | "zh:e00a1b11f0782e389b02c8a4487b2f25c42647714adcb56770f87883440997e9", 20 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /two-layer-architecture/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/google" { 5 | version = "4.32.0" 6 | hashes = [ 7 | "h1:hGZiuBPYAQyjp4D8/nLNcNM6T+FYn1YHGM1NdBPGojQ=", 8 | ] 9 | } 10 | 11 | provider "registry.terraform.io/hashicorp/tls" { 12 | version = "4.0.1" 13 | hashes = [ 14 | "h1:suLkTTvsuB5kqV5gc12PyGT4zY0J9G0RTyWMlZDwSVY=", 15 | "zh:1aa2e4c07ddf87f7bda65a4a0f3b45c3edfbe983768d49a105f7ab9f2e4f8320", 16 | "zh:1b7993daaf659dec421043ccf2dea021972ebacf47e5da3387e1ef35a0ffecbe", 17 | "zh:1c40b056af93fe792fd468a96f317a6ce918849799906cf619a1b8cf01e79ccb", 18 | "zh:3874421e4c975e987ade5bdece6d1eacd41065841c82856cc12fde405ea2fe38", 19 | "zh:4f27e1a90d779ac4bbdbd3db735b4777a90aefc8005905a8ed450bb517c323db", 20 | "zh:b4eb5438dc4bfbed7223c0044b775a210d52b631a9f37d884d567a3eacc31b92", 21 | "zh:b9808ee16fa06b7113a72c8d74f1cb322d0e7364fc34ba4bfdd0424ef7fd93d8", 22 | "zh:bc5b1913fe841a0d40f28ff70d76e1c22fa3f469ae28011422d12c6001dcb954", 23 | "zh:bdba092ae2939cb7e28380c5fd4a33ee96bead1abadbf9ec95d559cea8c04c3c", 24 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 25 | "zh:f80791f95f0ea5b332913e533c79ed4820e8c9243c508d8c7d6240b212160aaa", 26 | "zh:fe34ecc33c990f045ca5e3828e8aeb8ee86c9072e098e0ac0e4b47cbcb01edc0", 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learning-Terraform-with-GCP 2 | 3 | This repository is sample codes to learn Terraform with GCP. 4 | 5 | Samples are explained in the below books. 6 | 7 | * 『[Google Cloud Platformで学ぶTerraform 〜基礎編〜 @技術書典マーケット](https://techbookfest.org/product/6331235183886336)』 8 | * 『[Google Cloud Platformで学ぶTerraform 〜基礎編〜(PDF、ePubセット) #技術書典 @BOOTH](https://toshi0607.booth.pm/items/2354817)』 9 | * 『[Google Cloud Platformで学ぶTerraform 〜実践編〜 @技術書典マーケット](https://techbookfest.org/product/6366164626178048)』 10 | * 『[Google Cloud Platformで学ぶTerraform 〜実践編〜(PDF、ePubセット) #技術書典 @BOOTH](https://toshi0607.booth.pm/items/2629085)』 11 | 12 | ## Basic edition 13 | 14 | ### Chapter 4 Resource and terraform command 15 | 16 | * [basic](./basic) 17 | 18 | ### Chapter 5 How to write a configuration 19 | 20 | * [variable](./variable) 21 | * [output](./output) 22 | * [locals](./locals) 23 | * [Data sources](./data-sources) 24 | * [count](./count) 25 | * [for_each](./for_each) 26 | * [dynamic](./dynamic) 27 | * [Condition expression](./condition) 28 | * [Version and Provider](./version-and-provider) 29 | * [Module structure](./module-sample) 30 | * [Module](./module-test) 31 | 32 | ### Chapter 6 State management 33 | 34 | * [Remote backend](./remote-backend) 35 | * [Separate state by backend end environment](./state-separation) 36 | * [terraformer](./terraformer-test) 37 | * [moved](./moved) 38 | 39 | ## Practical edition 40 | 41 | ### Chapter 3 Two-layer architecture 42 | 43 | * [Two-layer architecture](./two-layer-architecture) 44 | 45 | ### Chapter 4 ~ 7, 9, 10 GKE + Microservices template 46 | 47 | Diffrent repository: [toshi0607/GKE-Microservices-Terraform-project-template](https://github.com/toshi0607/GKE-Microservices-Terraform-project-template) 48 | 49 | ### Chapter 8 Lint and validation 50 | 51 | * [Lint and validation](./lint-and-validation/) 52 | * [terraform fmt](./lint-and-validation/terraform-fmt) 53 | * [terraform validate](./lint-and-validation/terraform-validate) 54 | * [TFLint](./lint-and-validation/tflint) 55 | * [Conftest](./lint-and-validation/conftest) 56 | -------------------------------------------------------------------------------- /terraformer-test/generated/google/terraform-toshi0607/instances/asia-northeast1/compute_instance.tf: -------------------------------------------------------------------------------- 1 | resource "google_compute_instance" "tfer--test-terraformer" { 2 | boot_disk { 3 | auto_delete = "true" 4 | device_name = "persistent-disk-0" 5 | mode = "READ_WRITE" 6 | source = "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/zones/asia-northeast1-c/disks/test-terraformer" 7 | } 8 | 9 | can_ip_forward = "false" 10 | deletion_protection = "false" 11 | enable_display = "false" 12 | machine_type = "f1-micro" 13 | name = "test-terraformer" 14 | 15 | network_interface { 16 | access_config { 17 | nat_ip = "34.85.42.30" 18 | network_tier = "PREMIUM" 19 | } 20 | 21 | network = "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/global/networks/default" 22 | network_ip = "10.146.15.207" 23 | queue_count = "0" 24 | stack_type = "IPV4_ONLY" 25 | subnetwork = "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/regions/asia-northeast1/subnetworks/default" 26 | subnetwork_project = "terraform-toshi0607" 27 | } 28 | 29 | project = "terraform-toshi0607" 30 | 31 | scheduling { 32 | automatic_restart = "true" 33 | min_node_cpus = "0" 34 | on_host_maintenance = "MIGRATE" 35 | preemptible = "false" 36 | provisioning_model = "STANDARD" 37 | } 38 | 39 | service_account { 40 | email = "474715178574-compute@developer.gserviceaccount.com" 41 | scopes = ["https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/pubsub", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append"] 42 | } 43 | 44 | shielded_instance_config { 45 | enable_integrity_monitoring = "true" 46 | enable_secure_boot = "false" 47 | enable_vtpm = "true" 48 | } 49 | 50 | zone = "asia-northeast1-c" 51 | } 52 | -------------------------------------------------------------------------------- /lint-and-validation/conftest/policy/plan_test.rego: -------------------------------------------------------------------------------- 1 | package plan 2 | 3 | # $ conftest verify 4 | # empty and no_violations idea borrowed from https://github.com/instrumenta/conftest/blob/master/examples/kubernetes/policy/base_test.rego 5 | 6 | empty(value) { 7 | count(value) == 0 8 | } 9 | 10 | non_empty(value) { 11 | count(value) > 0 12 | } 13 | 14 | violations { 15 | non_empty(deny) 16 | } 17 | 18 | no_violations { 19 | empty(deny) 20 | } 21 | 22 | test_google_project_service_with_disable_on_destroy_false_is_allowed { 23 | input := { 24 | "resource_changes": [ 25 | { 26 | "type": "google_project_service", 27 | "change": { 28 | "after": { 29 | "disable_on_destroy": false 30 | } 31 | } 32 | } 33 | ] 34 | } 35 | 36 | no_violations with input as input 37 | } 38 | 39 | test_google_project_service_with_disable_on_destroy_true_is_denied { 40 | input := { 41 | "resource_changes": [ 42 | { 43 | "type": "google_project_service", 44 | "change": { 45 | "after": { 46 | "disable_on_destroy": true 47 | } 48 | } 49 | } 50 | ] 51 | } 52 | 53 | violations with input as input 54 | } 55 | 56 | test_google_project_iam_member_with_roles_admin_in_non_prod_is_denied { 57 | input := { 58 | "resource_changes": [ 59 | { 60 | "type": "google_project_iam_member", 61 | "change": { 62 | "after": { 63 | "member": "hoge@example.com", 64 | "project": "hoge-dev", 65 | "role": "roles/admin" 66 | } 67 | } 68 | } 69 | ] 70 | } 71 | 72 | no_violations with input as input 73 | } 74 | 75 | test_google_project_iam_member_with_roles_admin_in_prod_is_denied { 76 | input := { 77 | "resource_changes": [ 78 | { 79 | "type": "google_project_iam_member", 80 | "change": { 81 | "after": { 82 | "member": "hoge@example.com", 83 | "project": "hoge-prod", 84 | "role": "roles/admin" 85 | } 86 | } 87 | } 88 | ] 89 | } 90 | 91 | no_violations with input as input 92 | } 93 | -------------------------------------------------------------------------------- /two-layer-architecture/gceme.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | 3 | apt-get update 4 | apt-get install -y apache2 libapache2-mod-php 5 | 6 | # install lookbusy script to test autoscaling 7 | apt-get install -y build-essential git 8 | cd /tmp 9 | git clone https://github.com/beloglazov/cpu-load-generator.git 10 | ./cpu-load-generator/install-lookbusy.sh 11 | cd - 12 | 13 | cat > /var/www/html/index.php <<'EOF' 14 | [ 18 | "method" => "GET", 19 | "header" => "Metadata-Flavor: Google" 20 | ] 21 | ]; 22 | $context = stream_context_create($opts); 23 | $content = file_get_contents("http://metadata/computeMetadata/v1/$value", false, $context); 24 | return $content; 25 | } 26 | ?> 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Frontend Web Server 35 | 36 | 37 |
38 |
39 |
 
40 |
41 |
42 |
43 |
Backend that serviced this request
44 |
45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
Name
ID
Hostname
Zone
Machine Type
Project
Internal IP
External IP
82 |
83 |
84 |
85 |
86 |
Proxy that handled this request
87 |
88 |
89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 |
Address
97 |
98 |
99 |
100 |
 
101 |
102 |
103 | 104 | EOF 105 | sudo mv /var/www/html/index.html /var/www/html/index.html.old 106 | 107 | [[ -n "${PROXY_PATH}" ]] && mkdir -p /var/www/html/${PROXY_PATH} && cp /var/www/html/index.php /var/www/html/${PROXY_PATH}/index.php 108 | 109 | systemctl enable apache2 110 | systemctl restart apache2 111 | -------------------------------------------------------------------------------- /two-layer-architecture/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.2" 3 | } 4 | 5 | # https://www.terraform.io/docs/providers/google/index.html 6 | provider "google" { 7 | project = var.gcp_project 8 | region = var.gcp_region 9 | zone = var.gcp_zone 10 | } 11 | 12 | resource "google_compute_instance_template" "default" { 13 | name_prefix = "default-" 14 | machine_type = "f1-micro" 15 | region = var.gcp_region 16 | 17 | metadata_startup_script = file("./gceme.sh.tpl") 18 | 19 | tags = ["allow-ssh", "allow-service"] 20 | 21 | disk { 22 | source_image = "debian-cloud/debian-11" 23 | } 24 | 25 | service_account { 26 | # https://cloud.google.com/compute/docs/access/service-accounts#authorization 27 | scopes = ["cloud-platform"] 28 | } 29 | 30 | network_interface { 31 | network = "default" 32 | subnetwork = "default" 33 | } 34 | 35 | # Instance Templates cannot be updated after creation with the Google Cloud Platform API 36 | lifecycle { 37 | create_before_destroy = true 38 | } 39 | } 40 | 41 | # Router and Cloud NAT are required for installing packages from repos (apache, php etc) 42 | resource "google_compute_router" "default" { 43 | name = "default" 44 | network = "default" 45 | region = var.gcp_region 46 | } 47 | 48 | resource "google_compute_router_nat" "default" { 49 | name = "default" 50 | router = google_compute_router.default.name 51 | region = google_compute_router.default.region 52 | # https://www.terraform.io/docs/providers/google/r/compute_router_nat.html#source_subnetwork_ip_ranges_to_nat 53 | source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" 54 | # https://www.terraform.io/docs/providers/google/r/compute_router_nat.html#nat_ip_allocate_option 55 | nat_ip_allocate_option = "AUTO_ONLY" 56 | } 57 | 58 | resource "google_compute_region_instance_group_manager" "default" { 59 | name = "default" 60 | region = var.gcp_region 61 | version { 62 | instance_template = google_compute_instance_template.default.self_link 63 | } 64 | 65 | base_instance_name = "mig" 66 | target_size = null 67 | 68 | auto_healing_policies { 69 | health_check = google_compute_health_check.mig_health_check.self_link 70 | initial_delay_sec = 30 71 | } 72 | 73 | // Initial instance verification can take 10-15m when a health check is present. 74 | timeouts { 75 | create = "15m" 76 | } 77 | } 78 | 79 | resource "google_compute_region_autoscaler" "default" { 80 | name = "default" 81 | 82 | target = google_compute_region_instance_group_manager.default.self_link 83 | autoscaling_policy { 84 | max_replicas = 3 85 | min_replicas = 1 86 | } 87 | } 88 | 89 | resource "google_compute_health_check" "mig_health_check" { 90 | name = "default" 91 | 92 | http_health_check { 93 | port = 80 94 | } 95 | } 96 | 97 | resource "google_compute_firewall" "mig_health_check" { 98 | name = "health-check" 99 | 100 | network = "default" 101 | 102 | allow { 103 | protocol = "tcp" 104 | ports = [80] 105 | } 106 | 107 | source_ranges = ["130.211.0.0/22", "35.191.0.0/16"] 108 | target_tags = ["allow-service"] 109 | } 110 | 111 | resource "google_compute_firewall" "default_ssh" { 112 | name = "default-ssh" 113 | network = "default" 114 | 115 | allow { 116 | protocol = "tcp" 117 | ports = [22] 118 | } 119 | 120 | source_ranges = ["0.0.0.0/0"] 121 | } 122 | 123 | resource "google_compute_backend_service" "backend1" { 124 | name = "backend1" 125 | backend { 126 | group = google_compute_region_instance_group_manager.default.instance_group 127 | } 128 | health_checks = [google_compute_health_check.mig_health_check.self_link] 129 | } 130 | 131 | resource "google_compute_url_map" "default" { 132 | name = "default" 133 | default_service = google_compute_backend_service.backend1.self_link 134 | } 135 | 136 | resource "google_compute_target_https_proxy" "default" { 137 | name = "default" 138 | url_map = google_compute_url_map.default.self_link 139 | ssl_certificates = [google_compute_ssl_certificate.example.self_link] 140 | } 141 | 142 | resource "google_compute_ssl_certificate" "example" { 143 | name = "example" 144 | private_key = tls_private_key.example.private_key_pem 145 | certificate = tls_self_signed_cert.example.cert_pem 146 | } 147 | 148 | resource "tls_private_key" "example" { 149 | algorithm = "RSA" 150 | rsa_bits = 2048 151 | } 152 | 153 | # https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/self_signed_cert 154 | resource "tls_self_signed_cert" "example" { 155 | private_key_pem = tls_private_key.example.private_key_pem 156 | 157 | # Certificate expires after 12 hours. 158 | validity_period_hours = 12 159 | 160 | # Generate a new certificate if Terraform is run within three 161 | # hours of the certificate's expiration time. 162 | early_renewal_hours = 3 163 | 164 | # Reasonable set of uses for a server SSL certificate. 165 | allowed_uses = [ 166 | "key_encipherment", 167 | "digital_signature", 168 | "server_auth", 169 | ] 170 | 171 | dns_names = ["example.com", "example.net"] 172 | 173 | subject { 174 | common_name = "example.com" 175 | organization = "ACME Examples, Inc" 176 | } 177 | } 178 | 179 | resource "google_compute_global_forwarding_rule" "default" { 180 | name = "default" 181 | target = google_compute_target_https_proxy.default.self_link 182 | # https://www.terraform.io/docs/providers/google/r/compute_global_forwarding_rule.html#port_range 183 | port_range = "443" 184 | } 185 | -------------------------------------------------------------------------------- /two-layer-architecture/graph: -------------------------------------------------------------------------------- 1 | digraph { 2 | compound = "true" 3 | newrank = "true" 4 | subgraph "root" { 5 | "[root] google_compute_backend_service.backend1 (expand)" [label = "google_compute_backend_service.backend1", shape = "box"] 6 | "[root] google_compute_firewall.default_ssh (expand)" [label = "google_compute_firewall.default_ssh", shape = "box"] 7 | "[root] google_compute_firewall.mig_health_check (expand)" [label = "google_compute_firewall.mig_health_check", shape = "box"] 8 | "[root] google_compute_global_forwarding_rule.default (expand)" [label = "google_compute_global_forwarding_rule.default", shape = "box"] 9 | "[root] google_compute_health_check.mig_health_check (expand)" [label = "google_compute_health_check.mig_health_check", shape = "box"] 10 | "[root] google_compute_instance_template.default (expand)" [label = "google_compute_instance_template.default", shape = "box"] 11 | "[root] google_compute_region_autoscaler.default (expand)" [label = "google_compute_region_autoscaler.default", shape = "box"] 12 | "[root] google_compute_region_instance_group_manager.default (expand)" [label = "google_compute_region_instance_group_manager.default", shape = "box"] 13 | "[root] google_compute_router.default (expand)" [label = "google_compute_router.default", shape = "box"] 14 | "[root] google_compute_router_nat.default (expand)" [label = "google_compute_router_nat.default", shape = "box"] 15 | "[root] google_compute_ssl_certificate.example (expand)" [label = "google_compute_ssl_certificate.example", shape = "box"] 16 | "[root] google_compute_target_https_proxy.default (expand)" [label = "google_compute_target_https_proxy.default", shape = "box"] 17 | "[root] google_compute_url_map.default (expand)" [label = "google_compute_url_map.default", shape = "box"] 18 | "[root] provider[\"registry.terraform.io/hashicorp/google\"]" [label = "provider[\"registry.terraform.io/hashicorp/google\"]", shape = "diamond"] 19 | "[root] provider[\"registry.terraform.io/hashicorp/tls\"]" [label = "provider[\"registry.terraform.io/hashicorp/tls\"]", shape = "diamond"] 20 | "[root] tls_private_key.example (expand)" [label = "tls_private_key.example", shape = "box"] 21 | "[root] tls_self_signed_cert.example (expand)" [label = "tls_self_signed_cert.example", shape = "box"] 22 | "[root] var.gcp_project" [label = "var.gcp_project", shape = "note"] 23 | "[root] var.gcp_region" [label = "var.gcp_region", shape = "note"] 24 | "[root] var.gcp_zone" [label = "var.gcp_zone", shape = "note"] 25 | "[root] google_compute_backend_service.backend1 (expand)" -> "[root] google_compute_region_instance_group_manager.default (expand)" 26 | "[root] google_compute_firewall.default_ssh (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 27 | "[root] google_compute_firewall.mig_health_check (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 28 | "[root] google_compute_global_forwarding_rule.default (expand)" -> "[root] google_compute_target_https_proxy.default (expand)" 29 | "[root] google_compute_health_check.mig_health_check (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 30 | "[root] google_compute_instance_template.default (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 31 | "[root] google_compute_region_autoscaler.default (expand)" -> "[root] google_compute_region_instance_group_manager.default (expand)" 32 | "[root] google_compute_region_instance_group_manager.default (expand)" -> "[root] google_compute_health_check.mig_health_check (expand)" 33 | "[root] google_compute_region_instance_group_manager.default (expand)" -> "[root] google_compute_instance_template.default (expand)" 34 | "[root] google_compute_router.default (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 35 | "[root] google_compute_router_nat.default (expand)" -> "[root] google_compute_router.default (expand)" 36 | "[root] google_compute_ssl_certificate.example (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"]" 37 | "[root] google_compute_ssl_certificate.example (expand)" -> "[root] tls_self_signed_cert.example (expand)" 38 | "[root] google_compute_target_https_proxy.default (expand)" -> "[root] google_compute_ssl_certificate.example (expand)" 39 | "[root] google_compute_target_https_proxy.default (expand)" -> "[root] google_compute_url_map.default (expand)" 40 | "[root] google_compute_url_map.default (expand)" -> "[root] google_compute_backend_service.backend1 (expand)" 41 | "[root] meta.count-boundary (EachMode fixup)" -> "[root] google_compute_firewall.default_ssh (expand)" 42 | "[root] meta.count-boundary (EachMode fixup)" -> "[root] google_compute_firewall.mig_health_check (expand)" 43 | "[root] meta.count-boundary (EachMode fixup)" -> "[root] google_compute_region_autoscaler.default (expand)" 44 | "[root] meta.count-boundary (EachMode fixup)" -> "[root] google_compute_router_nat.default (expand)" 45 | "[root] meta.count-boundary (EachMode fixup)" -> "[root] output.external_ip (expand)" 46 | "[root] output.external_ip (expand)" -> "[root] google_compute_global_forwarding_rule.default (expand)" 47 | "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" -> "[root] google_compute_firewall.default_ssh (expand)" 48 | "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" -> "[root] google_compute_firewall.mig_health_check (expand)" 49 | "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" -> "[root] google_compute_global_forwarding_rule.default (expand)" 50 | "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" -> "[root] google_compute_region_autoscaler.default (expand)" 51 | "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" -> "[root] google_compute_router_nat.default (expand)" 52 | "[root] provider[\"registry.terraform.io/hashicorp/google\"]" -> "[root] var.gcp_project" 53 | "[root] provider[\"registry.terraform.io/hashicorp/google\"]" -> "[root] var.gcp_region" 54 | "[root] provider[\"registry.terraform.io/hashicorp/google\"]" -> "[root] var.gcp_zone" 55 | "[root] provider[\"registry.terraform.io/hashicorp/tls\"] (close)" -> "[root] tls_self_signed_cert.example (expand)" 56 | "[root] root" -> "[root] meta.count-boundary (EachMode fixup)" 57 | "[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/google\"] (close)" 58 | "[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/tls\"] (close)" 59 | "[root] tls_private_key.example (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/tls\"]" 60 | "[root] tls_self_signed_cert.example (expand)" -> "[root] tls_private_key.example (expand)" 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /terraformer-test/generated/google/terraform-toshi0607/terraformer/asia-northeast1/plan.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "v0.8.21", 3 | "Provider": "google", 4 | "Options": { 5 | "Resources": [ 6 | "instances" 7 | ], 8 | "Excludes": [], 9 | "PathPattern": "{output}/{provider}/terraform-toshi0607/{service}/asia-northeast1/", 10 | "PathOutput": "generated", 11 | "State": "local", 12 | "Bucket": "", 13 | "Profile": "", 14 | "Verbose": false, 15 | "Zone": "", 16 | "Regions": [ 17 | "asia-northeast1" 18 | ], 19 | "Projects": [ 20 | "terraform-toshi0607" 21 | ], 22 | "ResourceGroup": "", 23 | "Connect": true, 24 | "Compact": false, 25 | "Filter": [ 26 | "google_compute_instance=test-terraformer" 27 | ], 28 | "Output": "hcl", 29 | "RetryCount": 5, 30 | "RetrySleepMs": 300 31 | }, 32 | "Args": [ 33 | "asia-northeast1", 34 | "terraform-toshi0607", 35 | "" 36 | ], 37 | "ImportedResource": { 38 | "instances": [ 39 | { 40 | "InstanceInfo": { 41 | "Id": "google_compute_instance.tfer--test-terraformer", 42 | "ModulePath": null, 43 | "Type": "google_compute_instance" 44 | }, 45 | "InstanceState": { 46 | "id": "projects/terraform-toshi0607/zones/asia-northeast1-c/instances/test-terraformer", 47 | "attributes": { 48 | "advanced_machine_features.#": "0", 49 | "attached_disk.#": "0", 50 | "boot_disk.#": "1", 51 | "boot_disk.0.auto_delete": "true", 52 | "boot_disk.0.device_name": "persistent-disk-0", 53 | "boot_disk.0.disk_encryption_key_raw": "", 54 | "boot_disk.0.disk_encryption_key_sha256": "", 55 | "boot_disk.0.initialize_params.#": "1", 56 | "boot_disk.0.initialize_params.0.image": "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-11-bullseye-v20220719", 57 | "boot_disk.0.initialize_params.0.labels.%": "0", 58 | "boot_disk.0.initialize_params.0.size": "10", 59 | "boot_disk.0.initialize_params.0.type": "pd-standard", 60 | "boot_disk.0.kms_key_self_link": "", 61 | "boot_disk.0.mode": "READ_WRITE", 62 | "boot_disk.0.source": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/zones/asia-northeast1-c/disks/test-terraformer", 63 | "can_ip_forward": "false", 64 | "confidential_instance_config.#": "0", 65 | "cpu_platform": "Intel Broadwell", 66 | "current_status": "RUNNING", 67 | "deletion_protection": "false", 68 | "description": "", 69 | "enable_display": "false", 70 | "guest_accelerator.#": "0", 71 | "hostname": "", 72 | "id": "projects/terraform-toshi0607/zones/asia-northeast1-c/instances/test-terraformer", 73 | "instance_id": "7567028012687683419", 74 | "label_fingerprint": "42WmSpB8rSM=", 75 | "labels.%": "0", 76 | "machine_type": "f1-micro", 77 | "metadata.%": "0", 78 | "metadata_fingerprint": "aXCuda9UPV4=", 79 | "min_cpu_platform": "", 80 | "name": "test-terraformer", 81 | "network_interface.#": "1", 82 | "network_interface.0.access_config.#": "1", 83 | "network_interface.0.access_config.0.nat_ip": "34.85.42.30", 84 | "network_interface.0.access_config.0.network_tier": "PREMIUM", 85 | "network_interface.0.access_config.0.public_ptr_domain_name": "", 86 | "network_interface.0.alias_ip_range.#": "0", 87 | "network_interface.0.ipv6_access_config.#": "0", 88 | "network_interface.0.ipv6_access_type": "", 89 | "network_interface.0.name": "nic0", 90 | "network_interface.0.network": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/global/networks/default", 91 | "network_interface.0.network_ip": "10.146.15.207", 92 | "network_interface.0.nic_type": "", 93 | "network_interface.0.queue_count": "0", 94 | "network_interface.0.stack_type": "IPV4_ONLY", 95 | "network_interface.0.subnetwork": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/regions/asia-northeast1/subnetworks/default", 96 | "network_interface.0.subnetwork_project": "terraform-toshi0607", 97 | "project": "terraform-toshi0607", 98 | "reservation_affinity.#": "0", 99 | "resource_policies.#": "0", 100 | "scheduling.#": "1", 101 | "scheduling.0.automatic_restart": "true", 102 | "scheduling.0.instance_termination_action": "", 103 | "scheduling.0.min_node_cpus": "0", 104 | "scheduling.0.node_affinities.#": "0", 105 | "scheduling.0.on_host_maintenance": "MIGRATE", 106 | "scheduling.0.preemptible": "false", 107 | "scheduling.0.provisioning_model": "STANDARD", 108 | "scratch_disk.#": "0", 109 | "self_link": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/zones/asia-northeast1-c/instances/test-terraformer", 110 | "service_account.#": "1", 111 | "service_account.0.email": "474715178574-compute@developer.gserviceaccount.com", 112 | "service_account.0.scopes.#": "7", 113 | "service_account.0.scopes.0": "https://www.googleapis.com/auth/devstorage.read_only", 114 | "service_account.0.scopes.1": "https://www.googleapis.com/auth/logging.write", 115 | "service_account.0.scopes.2": "https://www.googleapis.com/auth/monitoring.write", 116 | "service_account.0.scopes.3": "https://www.googleapis.com/auth/pubsub", 117 | "service_account.0.scopes.4": "https://www.googleapis.com/auth/service.management.readonly", 118 | "service_account.0.scopes.5": "https://www.googleapis.com/auth/servicecontrol", 119 | "service_account.0.scopes.6": "https://www.googleapis.com/auth/trace.append", 120 | "shielded_instance_config.#": "1", 121 | "shielded_instance_config.0.enable_integrity_monitoring": "true", 122 | "shielded_instance_config.0.enable_secure_boot": "false", 123 | "shielded_instance_config.0.enable_vtpm": "true", 124 | "tags.#": "0", 125 | "tags_fingerprint": "42WmSpB8rSM=", 126 | "zone": "asia-northeast1-c" 127 | }, 128 | "meta": { 129 | "schema_version": 6 130 | }, 131 | "tainted": false 132 | }, 133 | "ResourceName": "tfer--test-terraformer", 134 | "Provider": "google", 135 | "Item": { 136 | "boot_disk": [ 137 | { 138 | "auto_delete": "true", 139 | "device_name": "persistent-disk-0", 140 | "mode": "READ_WRITE", 141 | "source": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/zones/asia-northeast1-c/disks/test-terraformer" 142 | } 143 | ], 144 | "can_ip_forward": "false", 145 | "deletion_protection": "false", 146 | "enable_display": "false", 147 | "machine_type": "f1-micro", 148 | "name": "test-terraformer", 149 | "network_interface": [ 150 | { 151 | "access_config": [ 152 | { 153 | "nat_ip": "34.85.42.30", 154 | "network_tier": "PREMIUM" 155 | } 156 | ], 157 | "network": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/global/networks/default", 158 | "network_ip": "10.146.15.207", 159 | "queue_count": "0", 160 | "stack_type": "IPV4_ONLY", 161 | "subnetwork": "https://www.googleapis.com/compute/v1/projects/terraform-toshi0607/regions/asia-northeast1/subnetworks/default", 162 | "subnetwork_project": "terraform-toshi0607" 163 | } 164 | ], 165 | "project": "terraform-toshi0607", 166 | "scheduling": [ 167 | { 168 | "automatic_restart": "true", 169 | "min_node_cpus": "0", 170 | "on_host_maintenance": "MIGRATE", 171 | "preemptible": "false", 172 | "provisioning_model": "STANDARD" 173 | } 174 | ], 175 | "service_account": [ 176 | { 177 | "email": "474715178574-compute@developer.gserviceaccount.com", 178 | "scopes": [ 179 | "https://www.googleapis.com/auth/servicecontrol", 180 | "https://www.googleapis.com/auth/trace.append", 181 | "https://www.googleapis.com/auth/logging.write", 182 | "https://www.googleapis.com/auth/devstorage.read_only", 183 | "https://www.googleapis.com/auth/pubsub", 184 | "https://www.googleapis.com/auth/service.management.readonly", 185 | "https://www.googleapis.com/auth/monitoring.write" 186 | ] 187 | } 188 | ], 189 | "shielded_instance_config": [ 190 | { 191 | "enable_integrity_monitoring": "true", 192 | "enable_secure_boot": "false", 193 | "enable_vtpm": "true" 194 | } 195 | ], 196 | "zone": "asia-northeast1-c" 197 | }, 198 | "IgnoreKeys": [ 199 | "^boot_disk.[0-9].initialize_params\\.(.*)", 200 | "^id$", 201 | "^label_fingerprint$", 202 | "^metadata_fingerprint$", 203 | "^self_link$", 204 | "^cpu_platform$", 205 | "^instance_id$", 206 | "^current_status$", 207 | "^tags_fingerprint$", 208 | "^attached_disk\\.[0-9]+\\.disk_encryption_key_sha256($|\\.[0-9]+|\\.#)", 209 | "^boot_disk\\.[0-9]+\\.disk_encryption_key_sha256($|\\.[0-9]+|\\.#)", 210 | "^network_interface\\.(.*)\\.external_ipv6_prefix_length$", 211 | "^network_interface\\.(.*)\\.external_ipv6$", 212 | "^network_interface\\.[0-9]+\\.ipv6_access_type($|\\.[0-9]+|\\.#)", 213 | "^network_interface\\.[0-9]+\\.name($|\\.[0-9]+|\\.#)" 214 | ], 215 | "AllowEmptyValues": [ 216 | "labels." 217 | ], 218 | "SlowQueryRequired": false, 219 | "DataFiles": null 220 | } 221 | ] 222 | } 223 | } 224 | --------------------------------------------------------------------------------