Terraform - 基本
概要
インフラ構築や設定をコード(テンプレートファイル)を使って自動化するためのツール、いわゆるIaCです
多くのプロバイダ(クラウド / ツール)に対応しており、インフラ構成を宣言的に定義 1 できることが特徴です
ファイル構成
Terraformでは、基本的にxxx.tf
という拡張子:tf
で定義された情報に従って各種リソースを構築します
単一ファイルにすべてを定義することも可能ですが、分離することが一般的です
以下、ファイル構成の基本を記述します。
- テンプレートファイル(.tf)に構成情報、プロバイダ情報2、変数等を記載していく
- tfファイルは、HCLというHashiCorp製の独自言語
- 実体は設定ファイル記述用DSLでJSONとも互換性あり
- 以下はサンプルのシンプルなディレクトリ構成
-
実運用時は、環境(Prod / Dev 等)後にディレクトリを分ける等の考慮が必要3
directory |- providers.tf :プロバイダ設定 |- main.tf :リソース定義(ファイル名は任意) |- variables.tf :変数設定 |- terraform.tfstate :リソースの現状を示すファイル(自動作成)
-
providers.tf
実行するTerraformのバージョンを指定4したり、プロバイダを指定する
-
複数のプロバイダに対応しているため、どのプロバイダで構築するかを定義する
以下は、AWSをプロバイダとしてproviders.tf
を記述したものとなるterraform { backend "s3" { bucket = "aws-terraform" key = "path/terraform.tfstate" region = "ap-northeast-1" shared_credentials_file = "$HOME/.aws/credentials" profile = "xxxxx" } required_version = ">=0.12" } provider aws { shared_credentials_file = "$HOME/.aws/credentials" profile = "xxxxx" region = "ap-northeast-1" }
認証情報もproviders.tf
に直接記述可能が、セキュリティリスクを考慮し環境変数で定義するが多い
-
単一アカウントでの管理手法
TF_VAR_<変数名>
というかたちで環境変数で定義する-
terraform
コマンド実行時にこの環境変数が読み込まれ、変数に値が代入される$ export TF_VAR_access_key="AKIAXXXXXXXXXXXXXXXXXX" $ export TF_VAR_secret_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-
複数アカウント環境の管理手法
shared_credentials_file
を利用可能profile
を利用してアカウントをスイッチ可能
後述のterraform.tfstate
の出力先をbackend
で指定できる
- このファイルはリソースの状態管理に使われる重要なファイルのため、ローカルは非推奨
- コンフリクト時の影響を考慮し、git等は非推奨
- ProviderがAWSであれば、S3/DynamoDBに配置するのが一般的
main.tf
Terraformにて、構築するリソース情報を定義する
resource "<リースの種類>" "<リソース名>" {}
といった構文で指定- <リソース名>は任意の名前を設定可能であり、用途を識別できるようにする
- ブロック中には
設定項目名 = 設定値
の形式で記述する
定義済みの他リソースの情報を参照することも可能
<リソースの種類>.<リソース名>.<属性名>
で指定する- 依存関係はTerraform側で制御されているので、原則、考慮不要
-
明示的に指定したい場合は、
depends_on
で指定する→作成したセキュリティグループ自身のIDをInboundルールに追加する例ですresource "aws_security_group" "allow_tls" { name = "allow_tls" description = "Allow TLS inbound traffic" vpc_id = aws_vpc.main.id ingress { description = "TLS from VPC" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = [aws_vpc.main.cidr_block] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_security_group_rule" "add-rule" { type = "ingress" from_port = 0 to_port = 0 protocol = "-1" source_security_group_id = aws_security_group.allow_tls.id security_group_id = aws_security_group.allow_tls.id depends_on = aws_security_group.allow_tls }
variables.tf
変数情報をmain.tf
等から分離するためのテンプレートファイル
- main.tf内で記述可能だが、可読性を考慮し別ファイルで管理することが多い
変数はvariable <変数名> {}
といった構文で定義
variable "env" {
type = string
description = "環境種別"
default = "dev"
}
type
変数の型を定義する(String/List/Map など)default
変数のデフォルト値
コマンド実行時や別ファイルを利用して上書き可能description
対象変数の説明を示す(コメントのように利用する)
terraform.tfstate
Terraformが管理しているリソースの状態を表すファイルとなる
- デフォルトではローカルにtfstateファイルが生成される
- ProviderがAWSであれば、s3などのリモートバックエンドで管理することが多い5
作成タイミングはterraform apply
を実行すると生成される
- 次回以降、
terraform plan
を実行時に前回実行時のリソース情報と差分が表示される - 実機との差分確認は行わないという設計方針6となっている
リソースを分割≒コマンド実行単位を分割することで、更新頻度の高低でtfstateを分割できる
-
tfstateの実体は以下のようなjsonファイル(リソース:ECSのtfstate)
{ "version": 4, "terraform_version": "0.12.14", "serial": 1, "lineage": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "outputs": {}, "resources": [ { "module": "module.ecs", "mode": "managed", "type": "aws_ecs_service", "name": "xxx-api", "provider": "provider.aws", "instances": [ { "schema_version": 0, "attributes": { "cluster": "arn:aws:ecs:ap-northeast-1:xxxxxxx:cluster/dev", "desired_count": 1, "id": "arn:aws:ecs:ap-northeast-1:xxxxxxx:service/dev-xxx-api", "launch_type": "FARGATE", "name": "dev-xxx-api", "task_definition": "dev-xxx-api:1", ... }, "dependencies": [ "module.ecs_service.xxx-api.aws_ecs_task_definition.task" ] } ] }, ... ] }
コマンド
Terraformで構築を行う際の基本的なコマンドについて、説明します
$ terraform init # BackendとプロバイダのInitialize
$ terraform plan # 実行内容の確認、チェック
$ terraform apply # 実行
terraform init
- ワークスペースを初期化するコマンド
- Terraform を実行するためには、まず
terraform init
でワークスペースの初期化が必須 - .tf(テンプレート)ファイル内の plugin(aws provider など)のダウンロード処理などが走る
terraform plan
- Terraform による実行計画を参照するコマンド
- .tf(テンプレート)ファイルに情報を元に、どのようなリソースが 作成/修正/削除 されるかを参照可能
terraform apply
- .tf(テンプレート)ファイルに記載された情報を元にリソースを作成するコマンド
- リソースが作成後、
terraform.tfstate
に、作成されたリソースに関連する情報が保存される - 2度目以降の実行後には、1世代前のものが
terraform.tfstate.backup
に保存される - Terraform において、この状態を管理する
terraform.state
ファイルが非常に重要となるため、手動更新等は行わないこと