Terraform + GCP をもう少しやってみる #2
前回の状態で、とりあえずGCP上にデプロイする方法はわかったので内容をもっと整理していく。
terraform workspace
ドキュメントは ここ、別ディレクトリを作成して provider.tf
、backend.tf
を再作成する。
$ mkdir ~/terraform-example2 ; cd $_ $ export GOOGLE_APPLICATION_CREDENTIALS='account.json' #<-サービスアカウントのJSONを指定 $ vi provider.tf $ vi backend.tf #<-GCSバケットは前回と違う場所を指定 $ terraform init
この時点で workspace を確認すると default
が使用されていることがわかる。
$ terraform workspace list * default
試しに dev
を作成し、環境が切り替わることを確認
$ terraform workspace new dev #<- dev を作成 $ terraform workspace list #<- 環境が dev に切り替わった事がわかる default * dev $ terraform workspace show dev
続けて staging
と production
を作成してから、workspace を dev
に戻して見てみる。
$ terraform workspace new staging $ terraform workspace new production $ terraform workspace select dev $ terraform workspace show dev
Cloud Storage 上にはそれぞれの .tfstate ファイルが作成されている。
$ gsutil ls gs://BACKET/DIRECTORY gs://BACKET/DIRECTORY/default.tfstate gs://BACKET/DIRECTORY/dev.tfstate gs://BACKET/DIRECTORY/production.tfstate gs://BACKET/DIRECTORY/staging.tfstate
workspace の利用
${terraform.workspace}
という変数に workspace の値が入るので、これを利用してプロジェクトを切り替える事ができる。
provider "google" { project = "example-${terraform.workspace}" region = "asia-northeast1" }
また ${terraform.workspace == "production" ? 3 : 1}
のように特定の環境のみ大きくすることもできる。
前回の更新
前回の状態から更新してみる。ドキュメントによると変数は下記の方法で渡せる模様
- コマンドラインフラグ
- tfvars ファイルで読み込み
- 環境変数 (string-type しか渡せない)
- UI入力 (string-type しか渡せない)
- tf ファイル内に記述
前の記事に書いた通り、ベストプラクティスといてはこの辺が参考になりそうだけど・・・
- Terraform Best Practices in 2017 (Qiita)
- Terraform Module Registry
- hashicorp / best-practics (GitHub)
それなりに辛そう(;´∀`) とりあえず・・・
- 前回のベタ書きから変更しそうな値だけ変数で渡すように修正
- 用途別にモジュール化
- GCPの場合プロジェクト毎にリソースグループを分けられるのでもう少しシンプルに
ってことをやってみた。
. ├── main.tf ├── variable.tf └── module ├── cloudsql │ ├── main.tf │ └── variable.tf ├── http-proxy │ ├── main.tf │ └── variable.tf ├── instance-template │ ├── main.tf │ ├── output.tf │ └── variable.tf └── instance-group ├── main.tf ├── output.tf └── variable.tf
module/DIRECTORY 下の variable.tf
には既定値を設定
variable "region" { default = "asia-northeast1"} ...
main.tf
からモジュールとして呼び出す際に、変更したい値を渡す事ができた。
module "cloudsql_users" { source = "./module/cloudsql" region = "${var.region}" ... }
あと CloudSQL のユーザとかリストで渡してループさせて作るのは こちらを参考に count
, length
, element
などを使うことで実装できた。
resource "google_sql_user" "users" { depends_on = [ "google_sql_database_instance.master" ] count = "${length(var.database_users)}" name = "${element(var.database_users, count.index)}" instance = "${google_sql_database_instance.master.name}" host = "%" password = "${element(var.database_password, count.index)}" }
モジュールからモジュールに渡したい値は output.tf
で渡した。
output "instance_template_link" { value = "${google_compute_instance_template.instance_template.self_link}" }
main.tf
からモジュールを呼び出した際に output.tf
の出力を受け取り、それを別のモジュールに渡す感じ。 受け取る側では空の変数 または デフォルト値 を宣言しとく。
variable instance_template_link {} ... module "instange-group" { source = "./module/instance-group" instance_template_link = "${module.instance-template.instance_template_link}" ... }
とりあえず自分の使いたい用途ではこんな感じで、後は Map 使ったり、HTTPS Proxy対応とか、SSL証明書とかもしたいけど、とりあえず一旦満足かな。
次にやること
- Terraform
ベストプラクティス や Terraform Module Registory 、HashiCorp BestPractice に沿った構成・変数使うように修正dev, std, prod で分ける#<-GCPだとプロジェクト毎に分けられるんだけど、この辺アプリ屋さんにも話を聞かないとわからない。- 新規VPCの作成からやる
- ネットワークセグメントの設定
- ファイアウォールルールの作成 (Health Check ほか)
- HTTPS Proxy対応、証明書の更新とか
- 整理してから GitHub に上げる
- 非マネージドなインスタンス・グループの構成
- その他 Terrafrom / GCP設定の追加・連携
- Ansible 含む (SendGridの設定とかも)
- Git, CI/CD と連携したコンテンツの配信・更新
- Angular の講座の続き
- PyQ の続き
以上