はじめに
AWS のエンジニアとして terraform を使ったことないのはいかがなものかと思い少しだけ勉強した。その備忘録。
関係ないけど terraform と terraterm 似てるよね。
そもそも terraform とは
AWS に限らず GCP, Azure などのインフラをコードを書くように構築できる (IaC)。
以下のようなメリットがある。
- コードのように書くのでバージョン管理ができる
- 手作業で発生しやすい人的ミスを防げる
- チーム内で容易に共有でき、属人化を防げる
- デプロイの前に変更内容が確認できる
インストール
ここにあるので省略
https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli
コードの書き方
コードのように書くといったが厳密には hashicorp configuration language (HCL) という専用の言語で書く。
実例を先に見た方がわかりやすいので例を以下に載せる。
terraform ではディレクトリ内のファイル全てを参照するので、他のプログラミング言語にあるような import 文を書かなくて良い (ディレクトリが違う場合を除く)
なので役割ごとにファイルを分けることができる。
terraform {
required_version = "~> 1.14.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
data "aws_ami" "amazonlinux_2023" {
most_recent = true
owners = [ "amazon" ]
filter {
name = "name"
values = [ "al2023-ami-*-kernel-6.1-x86_64" ]
}
}
resource "aws_instance" "example" {
ami = data.aws_ami.amazonlinux_2023.id
instance_type = "t3.micro"
tags = {
Name = var.instance_name
}
}
variable "instance_name" {
description = "Value of the Name tag for the EC2 instance"
type = string
default = "ExampleInstance"
}
output "instance_id" {
description = "instance id"
value = aws_instance.example.id
}
output "instance_public_ip" {
description = "public ip"
value = aws_instance.example.public_ip
}
terraform ブロック
terraform 自体の設定を書く。必要なバージョンやプロバイダーとして何を使うかなどを記載する
ドキュメントはこちら: https://developer.hashicorp.com/terraform/language/providers/requirements
provider ブロック
プロバイダーの設定。
上の例ではプロバイダーとして aws を指定しており、provider ブロックでリージョンの設定をしている。
aws の provider ブロックについては以下のドキュメント参照
output ブロック
外部リソースからデータを取得する。Describe* API を実行して情報を取得するイメージ。
上の例では最新の AL2023 AMI を取得して、AMI ID を後から参照している。
他にも後述の output からデータを取得するときにも使える。
ドキュメント: https://developer.hashicorp.com/terraform/language/data-sources
aws_ami: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami
resource ブロック
作成するリソースを記述するブロック。ブロック内はリソースのパラメーター。
上の例では EC2 インスタンスを作成している。
“resource” の後の文字列は、1 つめがリソースの種類。リソースの種類に従って決まった値を入れる必要がある。
EC2 インスタンス (“aws_instance”) のドキュメントは以下にある。
2 番目の文字列はラベルのようなもの。aws_instance.example.id のような形で ID などを参照することができる。
variables ブロック
変数を記述するブロック。
上の例だと、var.instance_name で格納した値を参照できる。
default 以外の値にしたいときはデプロイ時に指定できる。(-var-file で値をファイルに書くこともできる)
terraform apply -var="instance_name=TestName"
ドキュメント: https://developer.hashicorp.com/terraform/language/values/variables
output ブロック
外部モジュールに公開する値を指定する。
ドキュメント: https://developer.hashicorp.com/terraform/language/values/outputs
デプロイ方法
terraform コマンドを使ってデプロイを行う。
terraform init
まず最初に以下のコマンドで初期化を行う。git init みたいなもんだと思ってる。
terraform init
実行すると .terraform ディレクトリができる
terraform plan
デプロイする前にどんなリソースが作成されて、何が変更されるか確認できる。
実行しなくてもデプロイできるが、実行して確認することが推奨される。
$ terraform plan
data.aws_ami.amazonlinux_2023: Reading...
data.aws_ami.amazonlinux_2023: Read complete after 1s [id=ami-01d3379df335f13cd]
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_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-01d3379df335f13cd"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
(略)
terraform apply
実際にデプロイを行う。
実行後 “yes” と入力する必要があるが、-auto-approve オプションで回避できる (非推奨)
先述のように、-var オプションで変数に値を設定できる。
デプロイすると terraform.tfstate ファイルが作成される。このファイルに設定や、作成したリソースなどの情報が全て入ってる。
コードを編集した際、現在の環境との差分を terraform.tfstate ファイルを見て判断される。
チームで開発する場合はこのファイルを S3 とかに配置して共有する必要がある。
terraform show
現在の環境を表示できる。
terraform destroy
環境を削除する。
“terraform apply -destroy” コマンドのエイリアス。
終わりに
今回は基礎も基礎の部分だけ書いた。
terraform には他にも for 文だったり、三項演算子が使えたり、関数呼び出しができたり、色々できる。
この辺については以下のドキュメントにもあるし、もしやる気があれば続きのブログも書くかも。
https://developer.hashicorp.com/terraform/language/expressions