Terraformの基本構文
TerraformではHCL2というTerraformの独自構文が用いられる。
その基本構文についてまとめていく
jsonに似ているが、
- 簡単にプログラム(繰り返し、変数、定数などが使用できる)を作成できる
- コメントが書ける
- keyとvalueがコロンではなくイコールで指定
- ヒアドキュメントが利用できる
基本的な構成は下記の通りである
<block_type> "<label_1>" "<label_2>" {
key = value
nested_block {
...
}
}
早速、構成要素を見ていく
HCLの構成
HCL言語はブロックという単位から構成される
下記の定義ある場合はproviderやresourceという単位がブロックである(ブロックの入れ子も存在する)
provider "aws" {
region = "ap-northeast-1"
profile = "admin" # SSOでログインしたプロファイル名
}
resource "aws_instance" "hello-world" {
ami = "ami-0c1638aa346a43fe8"
instance_type = "t2.micro"
subnet_id = "subnet-0d6271c9f83a42751"
}
ブロックタイプとラベル
先ほどのproviderやresourceなどのブロックの先頭に記載してあるものをブロックタイプという
またブロックタイプごとに決まったラベルを与えることができる
下記は代表的なブロックタイプをまとめたものである
ブロック形式 | 構文例 | ラベルの意味 | 用途 |
---|---|---|---|
provider |
provider "aws" { ... } |
"aws" : プロバイダ名(ラベル1) |
クラウドプロバイダの設定(AWS、GCPなど) |
resource |
resource "aws_instance" "web" { ... } |
"aws_instance" : リソースタイプ(ラベル1)"web" : インスタンス名(ラベル2) |
実際のリソース(EC2、S3など)の作成 |
module |
module "vpc" { ... } |
"vpc" : モジュールインスタンス名(ラベル1) |
再利用可能な構成の呼び出し |
data |
data "aws_ami" "latest" { ... } |
"aws_ami" : データソース名(ラベル1)"latest" : インスタンス名(ラベル2) |
既存の読み取り専用データの参照 |
variable |
variable "region" { ... } |
"region" : 変数名(ラベル1) |
変数の定義(外部から値を受け取る) |
output |
output "instance_id" { ... } |
"instance_id" : 出力名(ラベル1) |
実行後に表示する出力値の定義 |
locals |
locals { name = "web" } |
(ラベルなし) | ローカルスコープでの再利用変数の定義 |
terraform |
terraform { required_providers { ... } } |
(ラベルなし) | Terraformの全体設定(バージョン、プロバイダ) |
backend |
backend "s3" { ... } (terraform内) |
"s3" : バックエンド種別(ラベル1) |
ステートファイルの保存先設定(S3、localなど) |
provisioner |
provisioner "remote-exec" { ... } |
"remote-exec" : プロビジョナータイプ(ラベル1) |
EC2などでのコマンド実行 |
lifecycle |
lifecycle { prevent_destroy = true } |
(ラベルなし) | リソースの挙動制御(削除防止など) |
dynamic |
dynamic "ingress" { ... } |
"ingress" : 動的に生成するブロック名(ラベル1) |
動的に繰り返しブロックを生成 |
ブロックにおける引数
ブロックタイプに対して引数を渡すことができる
下記の形式で引数を渡していく
key = value
# 例
resource "aws_instance" "hello-world" {
ami = "ami-0c1638aa346a43fe8" # 引数
instance_type = "t2.micro" # 引数
subnet_id = "subnet-0d6271c9f83a42751" 引数
tag = { # マップ型の引数
name = "test"
}
}
基本的には引数のキーは
- スネークケース
- 英小文字、数字、アンダースコアを使用
- 引用符で囲まない
これらが推奨されている
記述があったかあやふやだが下記にスタイルガイドのリンクを置いておく
値の型
下記が値の方となる
型(Type) | 書き方例 | 説明 | 使用例 |
---|---|---|---|
string |
"example" |
文字列型。ダブルクオート(シングルでもOK)で囲む | ami = "ami-12345678" |
number |
123 , 3.14 |
数値型(整数・小数) | instance_count = 2 |
bool |
true , false |
真偽値型 | enable_dns = true |
list |
["a", "b", "c"] |
同じ型の値の順序付きリスト | cidr_blocks = ["0.0.0.0/0"] |
tuple |
["a", 1, true] |
型が異なる値の順序付きリスト(型順序を固定) | output = ["abc", 123, false] |
map |
{ key1 = "val1", key2 = "val2" } |
キーと値のペアのコレクション(値の型は同じでなくても可) | tags = { Name = "web", Env = "dev" } |
object |
{ name = string, port = number } |
特定の構造をもつマップ型、フィールド名・型を定義 | 変数や出力の型指定に使用 |
set |
toSet(["a", "b", "c"]) |
重複のない値の集合。順序は保証されない | allowed_ips = toSet(["1.1.1.1"]) |
null |
null |
明示的に値なしとする | description = null |
localsとvariablesブロック
HCLで利用可能な変数である
種類 | 説明 |
---|---|
locals | ローカル変数であり、プライベートな変数で外部から変更できない |
variables | 外部から変更可能な変数であり、コマンドラインのオプションやファイル指定で上書き可能 |
locals定義方法
localsブロックで宣言を行い、${local.<NAME>}
で参照できる(外部から変更は不可)
locals {
env = "dev"
}
<block_type> "<label_1>" "<label_2>" {
tags {
env = "${local.env}"
}
}
variables定義方法
variableブロックで宣言を行い、${var.<NAME>}
で参照できる(外部からの変更は可能)
宣言にはラベルを必要とし、ラベルには変数名を用いる
内部では型(値の型を参照してください)とデフォルト値を設定可能
variables "env" {
type = string
default = "dev"
}
<block_type> "<label_1>" "<label_2>" {
tags {
env = "${var.env}"
}
}
変数の上書き方法
- 環境変数を使って上書きする
- 変数ファイルを使って上書きする
- コマンド引数を使って上書きする
この3種類の変更方法がある
上書き順は環境変数<変数ファイル<コマンド引数(同種の値であれば後勝ち)という形で右に行くほど、優先される
使い分けは?
環境変数
・実行ログに残らないため、鍵情報や環境依存情報などを設定する際に使用する。(tfstateに残ってしまう可能性はあるため注意)
変数ファイル
・git管理できるため、記録に残せる。プロビジョンとデータを切り離して管理することで変更しやすいソース管理ができる
コマンド引数
・実行ログに残るため、テストやデバッグで一時的に変更したい場合に利用
環境変数を使用した場合
variables "hoge" {
type = string
default = "None"
}
環境変数を設定し実行=>この際に変数が環境変数によって上書きされる。TF_VAR_変数名=値
で上書き可能
export TF_VAR_hoge="hoge_hoge"
terraform apply
変数ファイルを使用した場合
variables "hoge" {
type = string
default = "None"
}
変数ファイルを用意する
terraform.tfvars
tfvars拡張子のファイルを用紙する
hoge = "hoge_hoge"
コマンド実行
terrafrom apply
コマンド引数を使用した場合
コマンドにvar
オプションを指定して実行する
terraform apply -var hoge="hoge_hoge"
Terraformブロック
Terraformの設定に関わるブロックである
Terraformの構成は大きく分けて、
- Terraform本体機能
- プロバイダー(AWSやAzure,GCPなどに対応した機能)
に分かれる。
これらは個別にバージョンを持っており、それぞれのバージョン管理や制限が必要になる
主にTerraformブロックではバージョン管理を主として記載することとなる
Terraformのバージョン固定 => required_version
プロバイダのバージョン固定 => required_providers
を用いる
terraform {
required_version = "x.x.x" # terraform のバージョンを設定
required_providers {
aws = {
source ="hashicorp/aws" # プロバイダー設定
version = "x.x.x" # バージョン設定
}
}
}
プロバイダーブロック
プロバイダを使用する際に、リージョンや認証情報の設定などを行う
provider "aws" {
region ="ap-northeast-1"
profile = "admin" # AWSならCLIに設定したプロファイル名を指定できる
}
データブロック
Terraformで管理対象外となっているリソースの参照が可能
リソースによって記載方法が異なるので注意
outputブロックで設定してあるリソースの参照も可能
data {}
Outputブロック
作成したリソースの情報を外部から参照できるようにするためのブロック
resource "aws_instance" "hello-world" {
ami = "ami-0c1638aa346a43fe8"
instance_type = "t2.micro"
}
outpur "ec2_instance_id" { # 呼び出し名=>ec2_instance_id
value = aws_instance.hello_world.id # 出力する値
}
リソース間の参照
HCLでリソースを参照するための記述
<BLOCK_TYPE>.<LABEL_1>.<LABEL_2>
# ブロックタイプは省略可能なので、通常は下記で呼び出しすることが多そう
<LABEL_1>.<LABEL_2>
# 例えば、vpcのリソースを呼び出したいときは
resource "aws_vpc" "vpc" {
...
}
# 必要なブロック内で取得可能
aws_vpc.vpc.id
終わりに
すごくざっくりと記載しました。
今後はより実践向けの記事を書きたいなと思います。