2章 Terraformを使ったインフラストラクチャの構築
インフラ構築サイクル
https://gyazo.com/e9d42d670774eb83ef02594220c5cbb9
コーディング
1. 以下のようなファイルを作成し、provider ブロックを記述する
code:provider.tf
provider "aws" {}
Terraform では、書いたソースコードを各サービスの API やコマンドとして実行するために、プロバイダ利用する
2. terraform init を実行し、プロバイダを取得する
3. 設定ファイル(.tf)への記述
code:hello.tf
resource "terraform_data" "sample" {
provisioner "local-exec" {
command = "echo \"Hello, Terraform\""
}
}
設定ファイルの構成や記述の粒度には特に指定がないが、以下のような粒度で記述する
Terraform におけるリソース単位
e.g. EC2: aws_instance をまとめたファイル
特定の機能単位
e.g. API: ロードバランサ、ターゲットグループ、API サーバに関するリソースをまとめたファイル
terraform fmt でコードを整形できる
terraform validate で構文チェックが可能
tflint などのサードパーティ製のツールを用いると静的解析も可能
動作確認
terraform plan でインフラの変更内容を確認する
このとき、特に以下に注意する
1. 意図したリソースが作成・削除されていること
2. パラメータ変更のあったリソースの変更が意図したものであること
環境への適用
terraform apply を使って環境に適用する
terraform plan 実行時と同様に変更内容が出力されるので問題がないことを確認し、yes を入力する
https://gyazo.com/3d325a8ae0f6fa55d33893dbeb71ac8b
完了すると、以下のような出力が確認できる
https://gyazo.com/b27afb10fa40cc9f16d9314d4615f050
必要に応じて Terratest のようなサードパーティ製のツールを用いて、意図した構成となっているか確認すると良い
環境の破棄
terraform destroy で環境全体を破棄することができる
terraform plan 実行時と同様に変更内容が出力されるので問題がないことを確認し、yes を入力する
https://gyazo.com/495e6b885614ace5aa9da24d3e6f3532
Terraform の構成要素
モジュール
まとめて利用するリソースの集合
これにより、コードの 再利用性 を高められる
作成したモジュールは Terraform Registry に登録したり、GitHub などの VCS に配置するなどして配布可能
ローカルディスク上にあるモジュールの参照方法
code:tf
module "sample" {
source = "./モジュールの配置ディレクトリ"
変数名 = 値
...
}
モジュール内で作成した値などは output を介して他のリソースに渡せる
code:tf
module "sample" {
output "output_value" {
value = 値
}
}
出力した値は module.<モジュール名>.<output名> でアクセス可能
code:tf
locals {
output_value = module.output_value.value
}
プロバイダ
各種のリソースやデータ
主要なクラウドプロバイダやそのサービスに関連する機能は、プロバイダとして実装されている
多くは Terraform Registry に登録されている
明示的にプロバイダを指定しない場合、リソースなどで指定した設定のデフォルト値に基づいて必要なプロバイダを読み込む
e.g. aws_vpc を指定した場合は、自動的に AWS プロバイダを利用する
code:tf
resource "aws_vpc" "vpc" {
...
}
この時、AWS プロバイダは AWS CLI の default プロファイルの設定を利用する
ステート
terraform apply が実行された時に構築するインフラを管理するファイル
terraform apply が実行されると、ステートファイルに記録されているリソースの状態と、tf ファイルの記述内容の差分を埋めるために、リソースを操作する
https://gyazo.com/288defcc19b9ab1dd4675df47d14da73
デフォルトではローカルに保存される
terraform state を使って直接操作することもできるが、基本的に terraform plan と terraform apply で操作する
他で管理しているリソースやコードを取り込む必要があるなど、コードを大幅に変更する必要がある場合のみ、terraform state rm + terraform import や terraform state mv を利用する
モジュールとワークスペース
モジュール
複数リソースを特定のアーキテクチャパターンやクラウドのサービスの集合として利用
これにより、同様の構成を複製したり、サービスごとに分割することが可能
モジュールの最適な構成には、マイクロサービス の考え方が参考になる
モジュールを用いる際の 2 つの考え方
リソースの結合密度
リソースへの依存(パラメータへの受け渡し)は暗黙的に示す
depends_on で明示することも可能
リソース間のパラメータの受け渡し
モジュール内部でのパラメータの受け渡し
モジュール間でのパラメータの受け渡し
Terraform ではこれを極力減らすのが大事
= モジュール間を 疎結合 にすることで、モジュールの 独立性 を高めるという考え
output というモジュール間やステートをまたいで利用する機能がある
これの数が増えた場合は、モジュールの単位の再検討や統合をした方が良い
モジュールの分割粒度
受け渡すパラメータ数が少なくなるように分割するのが良い
e.g.
https://gyazo.com/61b14ee8eb4ed78854e0465628938017
1. それぞれのサービスをモジュールとして分割: LB, Fargate, DB(RDS)
2. 共通部分をモジュール化して切り出す: LB+Fargate, DB(RDS)
LB と Fargate 間で多くのパラメータが受け渡されているので、2 を選択した方が良い
ワークスペース
ステートを分割し、独立してリソースを管理できる方法
何も指定していない場合、暗黙的に default ワークスペースとなる
関連コマンド
terraform workspace new <ワークスペース名>: ワークスペースの新規作成
terraform workspace show: 現在のワークスペースの表示
terraform workspace list: ワークスペースの一覧表示
terraform workspace select: ワークスペースの切り替え
terraform workspace delete <ワークスペース名>: ワークスペースの削除
メリット
同一コードを使って、複数の環境(開発、ステージング、本番)を立ち上げられる
環境で値を変えることが可能
code:.tf
resource "aws_instance" "sample_instance" {
ami = local.instance_settingterraform_workspace.ami
instance_type = local.instance_settingterraform_workspace.type
tags = {
Name = "${terraform.workspace}-instance"
Env = terraform.workspace
}
}
locals {
instance_setting = {
stg = {
type = "t3.midium"
ami = "ami-xxxxxxxxxxxxxxxxx"
}
prod = {
type = "r5.large"
ami = "ami-yyyyyyyyyyyyyyyyy"
}
}
}
リソースへの権限を分離できる
e.g. ステージングのリソースは開発者も変更できるが、本番環境は管理者のみ
S3 のオブジェクトポリシーを使えば実現可能
デメリット
どの環境も同じ構成にする必要がある
無理にロジックで吸収しようとすると、コードが複雑になってしまいがち
回避策
ワークスペースを利用しない(ディレクトリ分割でコードを分ける)
https://gyazo.com/5eb6047e47e7dfbaa524fbb7d082b68b
ワークスペース名に応じてリソース作成有無を切り替える
code:.tf
resource "何かしらのリソース" "リソース名" {
count = terraform.workspace == "dev" ? 0 : 1
...
}
#Terraform #読書メモ