Terraformを使って環境構築を行ったときによく使ったコマンドや設定などをまとめておきます。
Terraformをまともに触ったことがない状態でしたが、環境構築をするとなってから事前にある程度どういったものか調べて取り組みました。
その中でもよく使った設定やコマンドを取り上げます。
書いてあること
・Terraform基本的な設定方法
・Terraformの基本コマンド
・詰まったポイント
今回はAWSを前提に書いています。
基本的な設定方法
ざっくりTerraformについて説明すると、
HashiCorp社が提供するマルチクラウド上のコンピュータやネットワークの構築を自動化するツールです。
Infrastructure as Code(IaC)と呼ばれるものですね。
リソースをコード管理できるのがメリットの1つになります。
AWSのCloudFormationも同じくIaCですが、TerraformはAWS以外にもGCPやAzureにも対応しています。
Terraform
では早速設定方法を見ていきます。
provider
どのクラウド環境を使用するかを設定します。
provider "aws" {
region = "ap-northeast-1"
}
variable
変数を定義します。
型やデフォルト値を指定することが可能です。
typeの種類は下記になります。
• string
• number
• bool
• list()
• set()
• map()
• object({ = , … })
• tuple([, …])
variable "hogehoge" {}
variable "env" {
type = string
default = "development"
}
呼び出すときはvar.{変数名}
でその変数の値を取得でき、文字列の中で展開するときは${}
で囲ってあげることで展開もできます。
resource "aws_iam_user" "admin" {
name = var.hogehoge
tags = {
Name = "${var.env}-admin"
}
}
その他値の注入の仕方は後述するterraform plan
などを実行したときに指定したり、コマンドの引数によって指定したり、環境変数による指定などが存在します。
resource
作成するリソースについて記述します。
構文としてはresource "リソースの種類" "リソース名" {}
のような形です。
リソースの種類についてはTerraformの公式ドキュメントに記載されているので作成したいリソースを検索すればすぐに見つけることができます。
ブロックの中にリソース毎に必要な設定項目を記述していきます。
注意点として、Terraformは頻繁にバージョンが変わるためバージョンによっては書き方が非推奨になっていたりするので自分の設定したバージョンでドキュメントを見ることが必要です。
リソース名は任意の値で問題ないです。
resource "aws_vpc" "main" {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "false"
tags {
Name = "${var.env}-main"
}
}
data
Terraform内で参照したいリソースの情報を参照します。
構文としては、data "要求するリソース名" "terraform内の名前" {}
のような形です。
resourceと同じくドキュメントにリソース名は記載されています。
data.要求するリソース名.terraform内の名前.取得したキー名
でリソースの値を取得することができます。
data "aws_vpc" "main" {
id = "vpc-01b2caf4c15eaab98"
}
data "aws_subnet_ids" "hoge_subnet" {
vpc_id = data.aws_vpc.main.id
name = "${var.env}-main
}
基本コマンド
terraform fmt
ソースコードのフォーマットを整えてくれるコマンドです。
例えば下記のようにイコール(=)の位置が項目ごとにずれているときにすべてを同じ位置に整えてくれます。
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
assign_generated_ipv6_cidr_block = false
}
↓こんな感じ
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
instance_tenancy = "default"
assign_generated_ipv6_cidr_block = false
}
例えば、/developmentというディレクトリ配下にvpc.tfが存在する場合は/developmentでterraform fmt
を実行する必要があります。
/developmentにあるファイルはすべてフォーマットの対象になります。
しかし、/development/moduleのように更に階層が深くなる場合は/module配下のファイルには適応されません。
オプションのterraform fmt -recursive
を使用することで解決することができます。
このオプションをつけることでコマンドを実行した階層の配下すべてのファイルに適応されます。
terrform plan
実装した内容が実際にどのようなリソースを作成するのかを確認することができます。
何か間違いがあればエラーが出るので実行前にテストできるイメージですね。
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_vpc.hogehoge will be created
+ resource "aws_vpc" "main" {
+ arn = (known after apply)
+ assign_generated_ipv6_cidr_block = false
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_classiclink = (known after apply)
+ enable_classiclink_dns_support = (known after apply)
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_network_border_group = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags_all = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
known after apply
はAWSリソースが作成された後に決定する値です。
下記はリソースが1つ追加され、変更や削除はないという意味になります。
Plan: 1 to add, 0 to change, 0 to destroy.
terraform apply
実際にリソース作成を実行します。
コマンドを実行するとterraform planのときと同じように作成されるリソースが確認できます。
その後本当に実行するか聞かれるので「yes」と入力すると作成が開始されます。
リソースによっては少し時間がかかることもあります。
terraform import ADDRESS ID
既存のリソースをインポートします。
ADDRESS
はリソースの種類+リソース名です。
本章で取り上げていたVPCの場合だとaws_vpc.main
の部分になります。
ID
はAWSのリソースの種類によって異なります。
ARNだったり、インスタンスの場合はインスタンスIDだったりします。
ID形式の詳細はドキュメントに記載されています。
terraform import aws_vpc.main [VPCのID]
moduleの場合
terraform import module.foo.aws_instance.bar i-abcd1234
ここで指定したtfファイルのリソースに対して既存リソースの情報がインポートされることになります。
そのため、予め対応するリソースをtfファイルに記述しておく必要があります。
Terraformは実行したときに自動で判断してリソースを作成してくれますが、これは実行時に読み込んだtfファイルとtfstateに書かれている内容の差分を元に行われます。
つまり、指定した既存リソースをTerraform上で管理するためにはtfstateの内容を変更する必要があり、指定した既存リソースの情報を読み込みtfstateに追加してくれるコマンドになります。
terraform state show ADDRESS
指定したリソースがtfstate上でどのような属性や値を持っているかを見ることができます。
ADDRESS
はリソースの種類+リソース名です。
resource "aws_vpc" "main" {
arn = "arn:aws:vpc:ap-northeast-1:AWSアカウントID:vpc/main"
assign_generated_ipv6_cidr_block = false
cidr_block = "10.0.0.0/16"
default_network_acl_id = "acl-0294d93390a5fb366"
default_route_table_id = "rtb-0070871d11d9ef714"
default_security_group_id = "sg-00fb88354cb9fa47e"
dhcp_options_id = "dopt-0b1a7ce9ce8741ab2"
enable_classiclink = false
enable_classiclink_dns_support = false
enable_dns_hostnames = true
enable_dns_support = true
id = "vpc-0ab175d8404e47af3"
instance_tenancy = "default"
ipv6_netmask_length = 0
main_route_table_id = "rtb-0070871d11d9ef714"
owner_id = "123456789098"
}
まとめ
初めてTerraformを触って環境構築を行いましたが、何度もエラーにぶつかりかなり手こずりました。
ただ1コマンドで環境が出来上がり、コード管理できるという点は魅力的でした!
AWSの話になってしまいますが、個人的にはARNが取得できないサービスがあったときは優しくないなあと思ってしまいました笑
terraform state showコマンドを使って取得する方法を先輩エンジニアの方に教えてもらったことでなんとか解決できました。
今回はあまりmoduleとかを使わなかったのでそういったところも使えるようになりたいですね。
コメント