[GCP上的Terraform入门] 第一部分

看到了”Infrastructure as Code”变得更加容易的”terraformer”,虽然有点晚,但是看了这篇文章后,开始想着是不是该开始尝试一下了。

环境

    • Terraform v0.12.6

 

    provider.google v2.12.0

准备环境

安装terraform

$ brew install terraform
...
$ terraform -v
Terraform v0.12.6

创建服务账号

    • gcloudコマンドはインストール済み

 

    • terraform実行用のサービスアカウトを作成します。

 

    • 権限は「Project > 編集者」をつけました

 

    • 鍵をjson形式でダウンロード

credentials.json として置いておきます
名前は適当です

service accounntをactivateします

  gcloud auth activate-service-account --key-file=credentials.json
    projectをセットしておきます
  $ gcloud config set project xxxxx

创建GCS存储桶

为了保存 xxx.tfstate 文件,需要在GCS上创建一个存储桶。
* 该文件用于保存管理基础设施的状态。

$ gsutil mb -c multi_regional -l Asia gs://xxxx-tf-state

写下Provider的设置

provider "google" {
  credentials = "${file("credentials.json")}"
  project     = "${var.project}"
  region      = "${var.region}"
}
variable "project" {
  default = "xxx"
}

variable "region" {
  default = "asia-northeast1"
}
    • project,regionはvariables.tfに外だししました

 

    credentials.jsonはさっきつくったservice accountの鍵ファイルです

写后端设置

在Google云存储(GCS)上配置以管理tfstate文件。

terraform {
  backend "gcs" {
    bucket      = "xxxx-tf-state"
    path        = "practice.tfstate"
    credentials = "credentials.json"
  }
}

进行Terraform的初始化。

$ terraform init

Initializing the backend...

Initializing provider plugins...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.google: version = "~> 2.12"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

嗯,有出现了什么警告。

你是在说建议我给提供者指定一个版本吗?那我会尝试安装。

diff --git a/provider.tf b/provider.tf
index 1e8066b..ec409f4 100644
--- a/provider.tf
+++ b/provider.tf
@@ -2,4 +2,5 @@ provider "google" {
   credentials = "${file("credentials.json")}"
   project     = "${var.project}"
   region      = "${var.region}"
+  version     = "~> 2.12"
 }
$ terraform init

Initializing the backend...

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

警告不再存在了呢。

$ gsutil ls gs://xxxx-tf-state
gs://xxxx-tf-state/practice.tfstate

已经生成了完整的tfstate文件。

试着创建一个虚拟私有云(VPC)。

我想试试做点什么,所以我决定创建一个VPC。

资源定义

resource "google_compute_network" "vpc" {
  name = "terraform-practice-network"
}

resource "google_compute_subnetwork" "vpc_subnet1" {
  name          = "terraform-practice-network-subnet1"
  ip_cidr_range = "${var.subnet_cidr_range}"
  network       = "${google_compute_network.vpc.name}"
  description   = "example.subnet1"
  region        = "${var.region}"
}
variable "project" {
  default = "xxxx"
}

variable "region" {
  default = "asia-northeast1"
}

variable "subnet_cidr_range" {
  default = "192.168.10.0/24"
}

计划

$ terraform plan
terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_network.vpc will be created
  + resource "google_compute_network" "vpc" {
      + auto_create_subnetworks         = true
      + delete_default_routes_on_create = false
      + gateway_ipv4                    = (known after apply)
      + id                              = (known after apply)
      + name                            = "terraform-practice-network"
      + project                         = (known after apply)
      + routing_mode                    = (known after apply)
      + self_link                       = (known after apply)
    }

  # google_compute_subnetwork.vpc_subnet1 will be created
  + resource "google_compute_subnetwork" "vpc_subnet1" {
      + creation_timestamp = (known after apply)
      + description        = "example.subnet1"
      + fingerprint        = (known after apply)
      + gateway_address    = (known after apply)
      + id                 = (known after apply)
      + ip_cidr_range      = "192.168.10.0/24"
      + name               = "terraform-practice-network-subnet1"
      + network            = "terraform-practice-network"
      + project            = (known after apply)
      + region             = "asia-northeast1"
      + secondary_ip_range = (known after apply)
      + self_link          = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

申请

暂时看起来可以,我会尝试申请一下。

$ terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # google_compute_network.vpc will be created
  + resource "google_compute_network" "vpc" {
      + auto_create_subnetworks         = true
      + delete_default_routes_on_create = false
      + gateway_ipv4                    = (known after apply)
      + id                              = (known after apply)
      + name                            = "terraform-practice-network"
      + project                         = (known after apply)
      + routing_mode                    = (known after apply)
      + self_link                       = (known after apply)
    }

  # google_compute_subnetwork.vpc_subnet1 will be created
  + resource "google_compute_subnetwork" "vpc_subnet1" {
      + creation_timestamp = (known after apply)
      + description        = "example.subnet1"
      + fingerprint        = (known after apply)
      + gateway_address    = (known after apply)
      + id                 = (known after apply)
      + ip_cidr_range      = "192.168.10.0/24"
      + name               = "terraform-practice-network-subnet1"
      + network            = "terraform-practice-network"
      + project            = (known after apply)
      + region             = "asia-northeast1"
      + secondary_ip_range = (known after apply)
      + self_link          = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_network.vpc: Creating...
google_compute_network.vpc: Still creating... [10s elapsed]
google_compute_network.vpc: Still creating... [20s elapsed]
google_compute_network.vpc: Still creating... [30s elapsed]
google_compute_network.vpc: Still creating... [40s elapsed]
google_compute_network.vpc: Creation complete after 49s [id=terraform-practice-network]
google_compute_subnetwork.vpc_subnet1: Creating...
google_compute_subnetwork.vpc_subnet1: Still creating... [10s elapsed]
google_compute_subnetwork.vpc_subnet1: Still creating... [20s elapsed]
google_compute_subnetwork.vpc_subnet1: Still creating... [30s elapsed]
google_compute_subnetwork.vpc_subnet1: Still creating... [40s elapsed]
google_compute_subnetwork.vpc_subnet1: Still creating... [50s elapsed]
google_compute_subnetwork.vpc_subnet1: Creation complete after 59s [id=asia-northeast1/terraform-practice-network-subnet1]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

尽管花费了一些时间,但看起来已经成功完成了。

$ gcloud compute networks list
NAME                        SUBNET_MODE  BGP_ROUTING_MODE  IPV4_RANGE  GATEWAY_IPV4
default                     AUTO         REGIONAL
terraform-practice-network  AUTO         REGIONAL
$ gcloud compute networks subnets list | grep subnet1
terraform-practice-network-subnet1  asia-northeast1          terraform-practice-network  192.168.10.0/24

將”名字”命名為”變數”來試試看

resource "google_compute_network" "vpc" {
  name = "${var.vpc_name}"
}

resource "google_compute_subnetwork" "vpc_subnet1" {
  name          = "${var.subnetwork_name}"
  ip_cidr_range = "${var.subnet_cidr_range}"
  network       = "${google_compute_network.vpc.name}"
  description   = "example.subnet1"
  region        = "${var.region}"
}
variable "project" {
  default = "xxxx"
}

variable "region" {
  default = "asia-northeast1"
}

variable "subnet_cidr_range" {
  default = "192.168.10.0/24"
}

variable "vpc_name" {
  default = "terraform-practice-network"
}

variable "subnetwork_name" {
  default = "terraform-practice-network-subnet1"
}
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]
google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

没变化啊。

考虑每个环境的配置

考虑如何实现不同环境的配置,如生产、暂存等。这次参考了《Terraform运维最佳实践2019:尝试放弃工作空间等等》,这篇博客文章给我很大的启发。

目前只有生产这一个选项,但是我尝试了这种感觉。

$ tree
.
├── credentials.json
└── environments
    └── production
        ├── backend.tf
        ├── network.tf
        ├── provider.tf
        └── variables.tf

尝试将其模块化

既然已经在variables中定义了变量,那么我们希望能够将每个资源定义在staging中进行共享。我想将network的设置分离到module中试试看。

目录结构

$ tree
.
├── credentials.json
├── environments
│   └── production
│       ├── backend.tf
│       ├── main.tf
│       ├── provider.tf
│       └── variables.tf
└── modules
    └── network
        └── main.tf

重新编写资源定义

ariable "vpc_name" {}
variable "subnetwork_name" {}
variable "subnet_cidr_range" {}
variable "region" {}

resource "google_compute_network" "vpc" {
  name = "${var.vpc_name}"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "vpc_subnet1" {
  name          = "${var.subnetwork_name}"
  ip_cidr_range = "${var.subnet_cidr_range}"
  network       = "${google_compute_network.vpc.name}"
  description   = "example.subnet1"
  region        = "${var.region}"
}
module "network" {
  source = "../../modules/network"

  vpc_name          = "${var.vpc_name}"
  subnetwork_name   = "${var.subnetwork_name}"
  subnet_cidr_range = "${var.subnet_cidr_range}"
  region            = "${var.region}"
}

计划

我会用Plan进行确认。

terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]
google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # google_compute_network.vpc will be destroyed
  - resource "google_compute_network" "vpc" {
      - auto_create_subnetworks         = false -> null
      - delete_default_routes_on_create = false -> null
      - id                              = "terraform-practice-network" -> null
      - name                            = "terraform-practice-network" -> null
      - project                         = "xxxx" -> null
      - routing_mode                    = "REGIONAL" -> null
      - self_link                       = "https://www.googleapis.com/compute/v1/projects/xxxx/global/networks/terraform-practice-network" -> null
    }

  # google_compute_subnetwork.vpc_subnet1 will be destroyed
  - resource "google_compute_subnetwork" "vpc_subnet1" {
      - creation_timestamp       = "2019-08-05T08:17:21.744-07:00" -> null
      - description              = "example.subnet1" -> null
      - enable_flow_logs         = false -> null
      - fingerprint              = "9zINd1OQU44=" -> null
      - gateway_address          = "192.168.10.1" -> null
      - id                       = "asia-northeast1/terraform-practice-network-subnet1" -> null
      - ip_cidr_range            = "192.168.10.0/24" -> null
      - name                     = "terraform-practice-network-subnet1" -> null
      - network                  = "https://www.googleapis.com/compute/v1/projects/xxxx/global/networks/terraform-practice-network" -> null
      - private_ip_google_access = false -> null
      - project                  = "xxxx" -> null
      - region                   = "asia-northeast1" -> null
      - secondary_ip_range       = [] -> null
      - self_link                = "https://www.googleapis.com/compute/v1/projects/xxxx/regions/asia-northeast1/subnetworks/terraform-practice-network-subnet1" -> null
    }

  # module.network.google_compute_network.vpc will be created
  + resource "google_compute_network" "vpc" {
      + auto_create_subnetworks         = false
      + delete_default_routes_on_create = false
      + gateway_ipv4                    = (known after apply)
      + id                              = (known after apply)
      + name                            = "terraform-practice-network"
      + project                         = (known after apply)
      + routing_mode                    = (known after apply)
      + self_link                       = (known after apply)
    }

  # module.network.google_compute_subnetwork.vpc_subnet1 will be created
  + resource "google_compute_subnetwork" "vpc_subnet1" {
      + creation_timestamp = (known after apply)
      + description        = "example.subnet1"
      + fingerprint        = (known after apply)
      + gateway_address    = (known after apply)
      + id                 = (known after apply)
      + ip_cidr_range      = "192.168.10.0/24"
      + name               = "terraform-practice-network-subnet1"
      + network            = "terraform-practice-network"
      + project            = (known after apply)
      + region             = "asia-northeast1"
      + secondary_ip_range = (known after apply)
      + self_link          = (known after apply)
    }

Plan: 2 to add, 0 to change, 2 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

摧毁 -> 创造 に成为了。

将terraform状态移动

使用 Terraform 的 state mv 将纯文本资源移动到模块中的贴士 | 呼唤月球

听说在将资源模块化时,可以使用 terraform state mv 来移动原本硬编码的资源位置。我会尝试一下。

$ terraform state mv google_compute_network.vpc module.network.google_compute_network.vpc

Error: Invalid target address

Cannot move to module.network.google_compute_network.vpc: module.network does
not exist in the current state.

出了错误。
没有 module.network 这个东西。

不能将资源移动到新模块 · 问题 #21346 · hashicorp/terraform

发现了这个问题。

允许将资源迁移到状态中的新模块,由jbardin提出的Pull Request#22299,hashicorp/terraform。

这个问题现在解决了吗?
看起来在2019年08月02日已经进行了合并。
但是,似乎还没有发布。※截止到2019年08月06日22:32。

导入并声明rm

由于在解决方法中提到了”import”这个词,然后删除旧的,所以我会尝试这样做。

$ terraform import module.network.google_compute_network.vpc terraform-practice-network
module.network.google_compute_network.vpc: Importing from ID "terraform-practice-network"...
module.network.google_compute_network.vpc: Import prepared!
  Prepared google_compute_network for import
module.network.google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

$ terraform state rm google_compute_network.vpc
Removed google_compute_network.vpc
Successfully removed 1 resource instance(s).
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.network.google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]
google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  # google_compute_subnetwork.vpc_subnet1 will be destroyed
  - resource "google_compute_subnetwork" "vpc_subnet1" {
      - creation_timestamp       = "2019-08-05T08:17:21.744-07:00" -> null
      - description              = "example.subnet1" -> null
      - enable_flow_logs         = false -> null
      - fingerprint              = "9zINd1OQU44=" -> null
      - gateway_address          = "192.168.10.1" -> null
      - id                       = "asia-northeast1/terraform-practice-network-subnet1" -> null
      - ip_cidr_range            = "192.168.10.0/24" -> null
      - name                     = "terraform-practice-network-subnet1" -> null
      - network                  = "https://www.googleapis.com/compute/v1/projects/xxxx/global/networks/terraform-practice-network" -> null
      - private_ip_google_access = false -> null
      - project                  = "xxxx" -> null
      - region                   = "asia-northeast1" -> null
      - secondary_ip_range       = [] -> null
      - self_link                = "https://www.googleapis.com/compute/v1/projects/xxxx/regions/asia-northeast1/subnetworks/terraform-practice-network-subnet1" -> null
    }

  # module.network.google_compute_subnetwork.vpc_subnet1 will be created
  + resource "google_compute_subnetwork" "vpc_subnet1" {
      + creation_timestamp = (known after apply)
      + description        = "example.subnet1"
      + fingerprint        = (known after apply)
      + gateway_address    = (known after apply)
      + id                 = (known after apply)
      + ip_cidr_range      = "192.168.10.0/24"
      + name               = "terraform-practice-network-subnet1"
      + network            = "terraform-practice-network"
      + project            = (known after apply)
      + region             = "asia-northeast1"
      + secondary_ip_range = (known after apply)
      + self_link          = (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

VPC的销毁和创建都不见了!
明白了。
一旦这样做,子网络也会被影响到。

$ terraform import module.network.google_compute_subnetwork.vpc_subnet1 terraform-practice-network-subnet1
module.network.google_compute_subnetwork.vpc_subnet1: Importing from ID "terraform-practice-network-subnet1"...
module.network.google_compute_subnetwork.vpc_subnet1: Import prepared!
  Prepared google_compute_subnetwork for import
module.network.google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

$ terraform state rm google_compute_subnetwork.vpc_subnet1
Removed google_compute_subnetwork.vpc_subnet1
Successfully removed 1 resource instance(s).
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.network.google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]
module.network.google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

可以去了。

将存储在GCP上的现有资源放入terraform中。

已经使用了无法创建状态MV的部分,但使用import似乎可以将现有资源放入tfstate中。在将现有资源转移到Terraform进行管理时,可能会有所需,所以我会尝试一下。

创建GCE实例

首先,手动创建GCE实例。
VPC将使用刚创建的那个。

    • マシンタイプ

f1-micro(vCPU x 1、メモリ 0.6 GB)

ゾーン

asia-northeast1-a

network

terraform-practice-network

subnetwork

terraform-practice-network-subnet1

内部IP

192.168.10.2

boot disk image

ubuntu-1804-bionic-v20190722a

写资源定义

Google:google_compute_instance – Terraform by HashiCorp:谷歌:谷歌计算实例- Terraform by HashiCorp

由于是一种不容错过的机会,我会将它写在模块中。(假设在生产环境和分期环境中使用相同的模块)
这次我想要创建一个假设为跳转服务器的实例,所以我会将它命名为“bastion”。

variable "name" {}
variable "subnetwork_name" {}
variable "machine_type" {}
variable "region" {}
variable "zone" {}
variable "boot_disk_image" {}
variable "private_ip" {}
variable "service_account" {}

resource "google_compute_address" "bastion" {
  name         = "${var.name}"
  region       = "${var.region}"
}

resource "google_compute_instance" "bastion" {
  name         = "${var.name}"
  machine_type = "${var.machine_type}"
  zone         = "${var.zone}"
  tags         = ["server", "bastion"]

  boot_disk {
    initialize_params {
      image = "https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/${var.boot_disk_image}"
    }
  }

  network_interface {
    network_ip = "${var.private_ip}"
    subnetwork = "${var.subnetwork_name}"
    access_config {
      # static external ip
      nat_ip   = "${google_compute_address.bastion.address}"
    }
  }

  service_account {
    email  = "${var.service_account}"
    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/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
    ]
  }
}
module "network" {
  source = "../../modules/network"

  vpc_name          = "${var.vpc_name}"
  subnetwork_name   = "${var.subnetwork_name}"
  subnet_cidr_range = "${var.subnet_cidr_range}"
  region            = "${var.region}"
}

module "bastion" {
  source = "../../modules/bastion"

  name            = "${var.bastion_name}"
  subnetwork_name = "${var.subnetwork_name}"
  machine_type    = "f1-micro"
  region          = "${var.region}"
  zone            = "${var.region_zone}"
  boot_disk_image = "ubuntu-1804-bionic-v20190722a"
  private_ip      = "192.168.10.2"
  service_account = "xxx-compute"
}
variable "project" {
  default = "xxxx"
}

variable "region" {
  default = "asia-northeast1"
}

variable "region_zone" {
  default = "asia-northeast1-a"
}

variable "subnet_cidr_range" {
  default = "192.168.10.0/24"
}

variable "vpc_name" {
  default = "terraform-practice-network"
}

variable "subnetwork_name" {
  default = "terraform-practice-network-subnet1"
}

variable "bastion_name" {
  default = "terraform-practice-instance-1"
}

将变量完全独立出来存放在variables文件中,还是直接写在main.tf文件中,这是一个微妙的问题。但是,我们通常将可能在其他地方使用的值放在variables文件中。

导入

$ terraform import module.bastion.google_compute_instance.bastion xxxx/asia-northeast1-a/terraform-practice-instance-1
module.bastion.google_compute_instance.bastion: Importing from ID "xxxx/asia-northeast1-a/terraform-practice-instance-1"...
module.bastion.google_compute_instance.bastion: Import prepared!
  Prepared google_compute_instance for import
module.bastion.google_compute_instance.bastion: Refreshing state... [id=terraform-practice-instance-1]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

创建实例时会自动创建GCE实例的默认服务账号,所以我想将服务账号导入并定义为资源。但是,自动创建的服务账号的账号名以数字开头,而Terraform的google_service_account的account_id需要以[a-z]开头,所以我暂时放弃了这个想法。

如果要导入的话,需要启用身份和访问管理(IAM)API。已通过开发者控制台进行了启用。

计划

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.network.google_compute_network.vpc: Refreshing state... [id=terraform-practice-network]
module.bastion.google_compute_instance.bastion: Refreshing state... [id=terraform-practice-instance-1]
module.network.google_compute_subnetwork.vpc_subnet1: Refreshing state... [id=asia-northeast1/terraform-practice-network-subnet1]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
  ~ update in-place

Terraform will perform the following actions:

  # module.bastion.google_compute_address.bastion will be created
  + resource "google_compute_address" "bastion" {
      + address            = (known after apply)
      + address_type       = "EXTERNAL"
      + creation_timestamp = (known after apply)
      + id                 = (known after apply)
      + name               = "terraform-practice-instance-1"
      + network_tier       = (known after apply)
      + project            = (known after apply)
      + region             = "asia-northeast1"
      + self_link          = (known after apply)
      + subnetwork         = (known after apply)
      + users              = (known after apply)
    }

  # module.bastion.google_compute_instance.bastion will be updated in-place
  ~ resource "google_compute_instance" "bastion" {
        can_ip_forward       = false
        cpu_platform         = "Intel Broadwell"
        deletion_protection  = false
        guest_accelerator    = []
        id                   = "terraform-practice-instance-1"
        instance_id          = "xxx"
        label_fingerprint    = "xxx"
        labels               = {}
        machine_type         = "f1-micro"
        metadata             = {}
        metadata_fingerprint = "xxx"
        name                 = "terraform-practice-instance-1"
        project              = "xxxx"
        self_link            = "https://www.googleapis.com/compute/v1/projects/xxxx/zones/asia-northeast1-a/instances/terraform-practice-instance-1"
      ~ tags                 = [
          + "bastion",
          + "server",
        ]
        tags_fingerprint     = "xxx"
        zone                 = "asia-northeast1-a"

        boot_disk {
            auto_delete = true
            device_name = "terraform-practice-instance-1"
            source      = "https://www.googleapis.com/compute/v1/projects/xxxx/zones/asia-northeast1-a/disks/terraform-practice-instance-1"

            initialize_params {
                image  = "https://www.googleapis.com/compute/v1/projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20190722a"
                labels = {}
                size   = 10
                type   = "pd-standard"
            }
        }

      ~ network_interface {
            name               = "nic0"
            network            = "https://www.googleapis.com/compute/v1/projects/xxxx/global/networks/terraform-practice-network"
            network_ip         = "192.168.10.2"
            subnetwork         = "https://www.googleapis.com/compute/v1/projects/xxxx/regions/asia-northeast1/subnetworks/terraform-practice-network-subnet1"
            subnetwork_project = "xxxx"

          ~ access_config {
              ~ nat_ip       = "xxx.xxx.xxx.xxx" -> (known after apply)
                network_tier = "PREMIUM"
            }
        }

        scheduling {
            automatic_restart   = true
            on_host_maintenance = "MIGRATE"
            preemptible         = false
        }

        service_account {
            email  = "xxxx-compute@developer.gserviceaccount.com"
            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/service.management.readonly",
                "https://www.googleapis.com/auth/servicecontrol",
                "https://www.googleapis.com/auth/trace.append",
            ]
        }

        timeouts {}
    }

Plan: 1 to add, 1 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

感觉好像可以去哦。

申请

$ terraform apply
...
module.bastion.google_compute_address.bastion: Creating...
module.bastion.google_compute_address.bastion: Creation complete after 4s [id=xxxx/asia-northeast1/terraform-practice-instance-1]
module.bastion.google_compute_instance.bastion: Modifying... [id=terraform-practice-instance-1]
module.bastion.google_compute_instance.bastion: Still modifying... [id=terraform-practice-instance-1, 10s elapsed]
module.bastion.google_compute_instance.bastion: Still modifying... [id=terraform-practice-instance-1, 20s elapsed]
module.bastion.google_compute_instance.bastion: Still modifying... [id=terraform-practice-instance-1, 30s elapsed]
module.bastion.google_compute_instance.bastion: Modifications complete after 34s [id=terraform-practice-instance-1]

Apply complete! Resources: 1 added, 1 changed, 0 destroyed.

下一次

    • 既存の手動で作ったリソースをすべて手で書き起こしていくのはしんどいので、terraformerをつかってみたい

GoogleCloudPlatform/terraformer: CLI tool to generate terraform files from existing infrastructure (reverse Terraform). Infrastructure to Code

bannerAds