やりたいこと
普段GCPを使っていて、コンソールからぽちぽちインスタンスなどを作っていくのが面倒になってきました。そこでIaCの出番です。
GCPのIaC「Cloud Deployment Manager」を使ってもよかったのですが、今回はより汎用性の高いTerraformを勉強したいと思います。
ここでは、TerraformでGCSのバケットを作り、削除するという簡単な例で入門していきます。
Terraformとは
クラウドのインフラ環境をコードで管理できるようにするのがIaC(Infrastructure as Code)。
コードでインフラを構築することで、コンソールでぽちぽち手作業でインフラを構築するとどうしても発生しうる作業ミスを防ぎます。
ソースコードをGitHub等で管理することにより、インフラのバージョン管理も可能となります。
IaCを実現するためのツールの一つが、HashiCorp社のTerraformです。
IaCツールとしては他にも、AWS専用の「CloudFormation」、Azure専用の「Azure Resource Manager」、GCP専用の「Cloud Deployment Manager」、様々なクラウドで汎用的に使える「Ansible」「Chef」などがあります。
各種IaCツールの比較はこちらの記事がわかりやすかったです。
Terraformでは「tf」という拡張子のファイルにインフラの設定を書いていきます。
現状のリソース(Terraformで管理されるインフラ)の状態は「tfstate」という拡張子のファイルで管理されます。
tfファイルは「HCL」(HashiCorp Configuration Language)という言語で記述します。
各クラウドの各サービスにおける書き方はこちらからクラウドを選択し、Documentationから確認することができます。
環境
windows10 pro
GCPのCloudSDKのインストールと認証は完了しているものとします。
インストール
(Windows)
こちらをダウンロードし、適当なフォルダに保存します。そのフォルダのパスを通せばOKです。
(macOS)
terraformのバージョン管理ツール「tfenv」をhomebrewでインストールし、そこから欲しいバージョンのterraformをインストールするのが良いそうです。
こちらの記事がわかりやすかったです。
terrform -v
を実行してバージョン情報が表示されれば、インストールは完了です。
手順
tfファイルの作成
今回はすべてmain.tf
に書いていきます。
Terraformはカレントディレクトリにあるすべてのtfファイルを見に行くため、複数ファイルに分割して書いても、一つのtfファイルにまとめて書いても挙動は一緒とのことでした。
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.5.0"
}
}
backend "gcs" {
bucket = "tf-state-hoge"
prefix = "terraform/state"
}
}
provider "google" {
credentials = file("./sample_key.json")
project = "sample-project"
}
resource "google_storage_bucket" "hoge" {
name = "sample_bucket_20220628"
location = "asia-northeast1"
storage_class = "STANDARD"
}
tfファイルの構成要素をブロックといいます。今回使用したブロックをざっと解説します。
(他にどんなブロックがあるかは公式ドキュメントがわかりやすいです)
terraformブロック
Terraformの設定を行います。
required_providers
ブロックではプロバイダーのバージョンを指定できます。
(バージョンを指定する理由についてはこちらの記事がわかりやすかったです。)
backend
ブロックでは、tfstateファイルを保管する場所を指定します。一般的にクラウドストレージを指定します。
今回は「tf-state-hoge」というGCSバケットに保管することにします。(あらかじめバケットを作成しておきましょう。これはコンソールでするしかない...?笑)
providerブロック
どのクラウドのインフラを作りたいのか記述します。
credentials
には、適切なロールを付与したterraform用のサービスアカウントの鍵JSONファイルのパスを指定します。(サービスアカウントについてはこちらをどうぞ。)
resourceブロック
作成するリソースを記述します。
GCP各種サービスの作成方法はこちらの公式ドキュメントにまとまっています。
今回は「sample_bucket_20220628」という名前の、ストレージクラス「STANDARD」のGCSバケットを東京リージョンに作成します。
tfファイルの整形
フォーマット機能が用意されているので、実行します。
$ terraform fmt
main.tf
初期化
実行したいtfファイルがあるディレクトリで初期化を行います。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/google versions matching "3.5.0"...
- Installing hashicorp/google v3.5.0...
- Installed hashicorp/google v3.5.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
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.
terraform show
で、Terraformで管理しているリソース一覧を確認できます。
今はまだ何も管理していないことがわかります。
$ terraform show
No state.
変更内容の確認
terraform plan
で、今回の変更内容を確認します。
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
Terraform will perform the following actions:
# google_storage_bucket.hoge will be created
+ resource "google_storage_bucket" "hoge" {
+ bucket_policy_only = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ location = "ASIA-NORTHEAST1"
+ name = "sample_bucket_20220628"
+ project = (known after apply)
+ self_link = (known after apply)
+ storage_class = "STANDARD"
+ url = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.
変更の実行
想定通り「GCSバケットが1個作られる」と教えてくれているので、terraform apply
で作成を実行します。
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create
Terraform will perform the following actions:
# google_storage_bucket.hoge will be created
+ resource "google_storage_bucket" "hoge" {
+ bucket_policy_only = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ location = "ASIA-NORTHEAST1"
+ name = "sample_bucket_20220628"
+ project = (known after apply)
+ self_link = (known after apply)
+ storage_class = "STANDARD"
+ url = (known after apply)
}
Plan: 1 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_storage_bucket.hoge: Creating...
google_storage_bucket.hoge: Creation complete after 1s [id=sample_bucket_20220628]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
GCSコンソール画面を確認すると...
無事GCSバケットが作られました。
リソース確認
terraform show
で、Terraformで管理するリソースを確認できます。
$ terraform show
# google_storage_bucket.hoge:
resource "google_storage_bucket" "hoge" {
bucket_policy_only = false
force_destroy = false
id = "sample_bucket_20220628"
location = "ASIA-NORTHEAST1"
name = "sample_bucket_20220628"
project = "sample-project"
requester_pays = false
self_link = "https://www.googleapis.com/storage/v1/b/sample_bucket_20220628"
storage_class = "STANDARD"
url = "gs://sample_bucket_20220628"
先ほど作ったバケットが表示されました。
ちなみに、このタイミングで再度 terraform plan
を実行すると...
$ terraform plan
google_storage_bucket.hoge: Refreshing state... [id=sample_bucket_20220628]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are
needed.
tfファイルの内容とGCPの内容が同じなので変更するものはないよ、と言ってくれてます。
リソース削除
tfファイルから削除したいリソースの記述を消しterraform plan
を行うと...
google_storage_bucket.hoge: Refreshing state... [id=sample_bucket_20220628]
Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# google_storage_bucket.hoge will be destroyed
- resource "google_storage_bucket" "hoge" {
- bucket_policy_only = false -> null
- force_destroy = false -> null
- id = "sample_bucket_20220628" -> null
- labels = {} -> null
- location = "ASIA-NORTHEAST1" -> null
- name = "sample_bucket_20220628" -> null
- project = "sample-project" -> null
- requester_pays = false -> null
- self_link = "https://www.googleapis.com/storage/v1/b/sample_bucket_20220628" -> null
- storage_class = "STANDARD" -> null
- url = "gs://sample_bucket_20220628" -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
1個削除(破壊)しますよ、と教えてくれました。
削除を実行するには terraform apply
を行います。
(中略)
Plan: 0 to add, 0 to change, 1 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_storage_bucket.hoge: Destroying... [id=sample_bucket_20220628]
google_storage_bucket.hoge: Destruction complete after 1s
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
コマンドまとめ
# 初期化
terraform init
# tfファイルのフォーマット
terraform fmt
# 何を作る・変更する・削除するか確認
terraform plan
# 実際に作成・変更・削除を実行
terraform apply
# terraform管理下のオブジェクトを確認
terraform show