Terraform ベストプラクティス 2020 春 ~moduleやめてみた~
概要
#InfraStudy
に刺激を受け、書きます!
2019 年に以下記事を書いてから早 1 年、terraform 運用歴を重ね、2020 年春のベストプラクティスを更新しました。
例によって、まず結論、
#InfraStudy
に刺激を受け、書きます!
2019 年に以下記事を書いてから早 1 年、terraform 運用歴を重ね、2020 年春のベストプラクティスを更新しました。
例によって、まず結論、
Terraform 用の GitHub Actions として hashicorp 社にて以下リポジトリが用意されています。
hashicorp/terraform-github-actions
ですが、上記のリポジトリでは、 terraform の最新版 (2019-09-30 時点 0.12.9) にのみ適用しています。
hashicorp/terraform-github-actions を folk して
0.11 系がなかった為、 0.11 系に対応した terraform-github-actions を以下リポジトリに作成しました。
2020-05-05 追記 2020 年春のベストプラクティス更新しています。
以前 terraform で workspace 毎に tfstate 管理する方法を執筆しましたが、実運用上いくつかの問題がありました。
結論、現在は workspace 運用をやめています。
まずは実際の運用例です。
もっとうまいことやってるぞ!という話はあろうかと思いますが、まずはありがちなケースを紹介します。
terraform workspace で環境毎に tfsate 管理した話です。
追記時点で workspace は運用時点の問題が多くあった為、利用していません。以下記事ご参考いただければと思います。
Terraform tfstate の管理をかつて
0.8 系では -backend-config
でせっせと環境(stg,prod) 毎に bucket を変えて、
なんてコードを見てきました。
ですが、
workspace で 1 つの bucket に 環境毎に保管できる様になりました。
厳密には環境毎でなくとも
リソースの集合毎、module 毎等で管理するイメージですが
今回はイメージを捉えやすく環境毎で分けました。
= 0.9 では、terraform workspace で同一ディレクトリで複数のリソース群を管理
とより利用しやすくなりました。
以下条件とします。
1 | $ terraform plan |
local に terraform.tfstate を取得します。
中身を確認してリソースの設定がある程度問題ないか確認しておきます。
1 | $ terraform remote config \ |
1 | macOS%$ terraform state pull > terraform.tfstate |
Homebrew ならば upgrade で!
1 | macOS%$ brew upgrade terraform |
既にこの様に設定されている方はスキップです。特に普遍的な書き方です。
1 | terraform { |
stg
作成1 | $ terraform workspace new stg |
1 | $ terraform workspace list |
1 | $ terraform state push -force .terraform/terraform.tfstate |
これで S3 tfstate.bucket
の env:/stg/
ディレクトリ以下に terraform.tfstate が push されました。
実際に S3 を見て確認してみてください。
env
でなく env:
なのが肝です。
1 | $ terraform plan |
想定の実行計画通りか確認して問題なければ移行完了です。
terraform を指定したバージョンで実行するには
one-off Container で実行できる様に Makefile でラップする、
が今の所自分の中のベストプラクティスです。
これによって local 環境に依存せず指定したバージョンの terraform 実行が可能となります。
one-off Container は Docker コンテナを run --rm
で 1 度のコマンド実行の為だけに起動する手法です。
Makefile で Docker コマンドをラップしておくとTERRAFORM_VERSION
を変更するだけで
指定の terraform バージョンを利用できます。
以下は 0.11.1 の例です。
1 | TERRAFORM_VERSION=0.11.1 |
make init ENV=stg
実行で以下まとめてましたstg
作成きっとさらに素敵なベストプラクティスがあれば教えてください!
参考になれば幸いです。
Terraform の Hello World 的なチュートリアルと思っていただけたら幸いです。
RSA フォーマットで鍵を生成します。
1 | $ ssh-keygen -t rsa |
公開鍵を起動した EC2 インスタンスに登録し
秘密鍵でアクセスします。
以下のように利用する予定です。
1 | $ ssh -i ~/.ssh/terraform-test <ec2 user>@<ec2 public ip> |
Point !
resource "aws_key_pair"
で使用する公開鍵設定をしています。resource "aws_security_group"
で SSH(ポート 22)を開いてます。resource "aws_instance"
で使用しているセキュリティグループの指定は vpc_security_group_ids
を利用main.tf
1 | provider "aws" { |
1 | variable "access_key" {} |
1 | access_key = "A******************Q" |
1 | $ terraform plan |
1 | $ terraform apply |
AWS コンソール上で起動確認
1 | $ ssh -i ~/.ssh/terraform-test ubuntu@ec2-54-65-244-25.ap-northeast-1.compute.amazonaws.com |
無事 SSH ログインできました!
terraform を見ながら各パラメータの利用意図を確認しながら
設定してみましたが
パラメータの説明自体はざっくりで利用方法まではわからないです。
Teffaform のチュートリアルに始まり
その他 Stack Overflow で
適宜パターンを蓄積していく学習が程よいと思います。
非常にミニマムなインフラ構築をしてみます。
※個人のアカウントでも無料枠を使えば数十円しか掛からなかったです。
1 | $ brew install terraform |
1 | $ terraform version |
では、早速使ってみます。
1 | provider "aws" { |
1 | $ terraform plan |
1 | $ terraform apply |
Amazon Console からインスタンスが起動されたことが確認できます。
上記 main.tf を github 等で管理するとなると
access_key, secret_key が露見されてしまいます。
その為、以下の様に別ファイルで管理することが望ましいです。
1 | variable "access_key" {} |
1 | access_key = "A******************Q" |
1 | $ terraform plan |
正しく実行できることが確認できました。
terraform.tfvars
ファイルは .gitignore に登録しておくなど
絶対に公開されない様な設定が望ましいと思います。
1 | variable "access_key" {} |
変更される内容が表示されます。
1 | $ terraform plan |
最初に作成したインスタンスは破棄され、新たにインスタンスを作成していることがわかります。
terraform で新規作成・変更ができました。
次は破棄してみましょう。
破棄対象のリソースが表示されます。
1 | $ terraform plan -destroy |
1 | $ terraform destroy |
Amazon コンソールで破棄されたことを確認できます。
1 | variable "access_key" {} |
1 | $ terraform plan |
1 | $ terraform apply |
Elastic IP が設定されたインスタンスが起動していることが確認できます。
※ただ、起動しただけで接続できないことがわかります(>_<) 次回実施します
[f:id:kenzo0107:20170323230208p:plain]
破棄される Elastic IP, インスタンスが確認できます。
1 | $ terraform plan -destroy |
1 | $ terraform destroy |
全インスタンスが破棄されていることが確認できました。
1 | ... |
ex) region us-west-2 を選択
1 | $ terraform apply -var region=us-west-2 |
生成された Elastic IP の値が知りたいときなど便利です。
1 | resource "aws_eip" "ip" { |
出力値が確認できます。
1 | $ terraform apply |
より明示的にパラメータを絞って表示できます。
1 | $ terraform output ip |
1 | $ terraform show |
1 | $ terraform graph | dot -Tpng > graph.png |
1 | $ brew install graphviz |
簡単でしょ?と言われているようなツールでした ♪
引き続きプロビジョニングや AWS の各種設定をしていきたいと思います。