├── 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 | | Name |
50 | |
51 |
52 |
53 | | ID |
54 | |
55 |
56 |
57 | | Hostname |
58 | |
59 |
60 |
61 | | Zone |
62 | |
63 |
64 |
65 | | Machine Type |
66 | |
67 |
68 |
69 | | Project |
70 | |
71 |
72 |
73 | | Internal IP |
74 | |
75 |
76 |
77 | | External IP |
78 | |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
Proxy that handled this request
87 |
88 |
89 |
90 |
91 |
92 | | Address |
93 | |
94 |
95 |
96 |
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 |
--------------------------------------------------------------------------------