てっくらのーとは、触れた技術のメモと日常の記録が少し合わさった個人のサイトです。
Terraformことはじめ
Terraform を学び始めました。基本的な箇所が中心ですが学習過程のメモとなります。
環境
$ terraform --version
Terraform v0.12.24
$ jq --version
jq-1.5-1-a5b5cbe
インストール
公式ではIntroductionという形で使用する流れを紹介しています。インストールではバイナリをダウンロード(+環境変数の更新)で対応しているようです。
今回はLinuxディストリビューションのパッケージ管理コマンド経由でインストールしました。最近は開発環境としてArchLinuxのdockerを使用することが多くpacman
を使用しています。
$ sudo pacman -Syu terraform
パッケージ (1) terraform-0.12.24-1
合計ダウンロード容量: 13.14 MiB
合計インストール容量: 55.89 MiB
(略)
インフラストラクチャの作成
プロバイダ
インフラストラクチャを定義するIaaSやPaaS、SaaSを記載します。AWS
やGCP
、Azure
だけと思っていたのですが、普通にたくさん存在していました。今回はプロバイダをAWS
としています。
provider "aws" {
profile = "default"
region = "ap-notrheast-1"
}
このように直接tfファイルに設定するのは避けて、通常はawscli
や他のプロジェクトなどでも使用する.aws/profile
に記載・管理して参照するのがスタンダードと思うので、provider
をコメントアウトししたところ.aws/profile
は参照せずにCLIパラメータとして指定するようになりました。
> terraform apply
provider.aws.region
The region where AWS operations will take place. Examples
are us-east-1, us-west-2, etc.
Enter a value: ap-northeast-1
(略)
.aws/config
から直接指定出来るような気もしているので、もう少し見てみたい。また、そのほかには.tfvars
ファイルに変数を分離して、.tf
ファイルではvariable
の宣言を行う方法もあるようです。このような機密情報の絡みは、暗号化(vault)考慮の必要性もあると思うので、その観点でも、もう少し詳しく見ていきたいところ。
リソース
リソースタイプを指定してリソースを作成します。これはVPCにサブネットを作成するリソースタイプを使用して、サブネットを作成しています。
resource "aws_subnet" "subnet" {
vpc_id = "vpc-1234567890"
availability_zone = "ap-northeast-1a"
cidr_block = "172.31.0.0/24"
}
一度実行してみる
- main.tf
provider "aws" {
profile = "default"
region = "ap-northeast-1"
}
resource "aws_subnet" "subnet" {
vpc_id = "vpc-1234567890"
availability_zone = "ap-northeast-1a"
cidr_block = "172.31.0.0/24"
}
- 実行
terraform apply
で実行する。
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_subnet.subnet will be created
+ resource "aws_subnet" "subnet" {
+ arn = (known after apply)
+ assign_ipv6_address_on_creation = false
+ availability_zone = "ap-northeast-1a"
+ availability_zone_id = (known after apply)
+ cidr_block = "172.31.0.0/24"
+ id = (known after apply)
+ ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_association_id = (known after apply)
+ map_public_ip_on_launch = false
+ owner_id = (known after apply)
+ vpc_id = "vpc-1234567890"
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
yes
と入力して続けます。
Enter a value: yes
aws_subnet.subnet: Creating...
aws_subnet.subnet: Creation complete after 1s [id=subnet-1234567890]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
無事にVPCにサブネットが作成された。awscli
コマンドでも確認してみる。
$ aws ec2 describe-subnets | jq -c .Subnets[].SubnetId
"subnet-1234567890"
破棄してみる
terraform destroy
でリソースを破棄する。
$ terraform destroy
aws_subnet.subnet: Refreshing state... [id=subnet-1234567890]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_subnet.subnet will be destroyed
- resource "aws_subnet" "subnet" {
(略)
- vpc_id = "vpc-1234567890" -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
先ほどと同じようにyes
と入力して進める。
Enter a value: yes
aws_subnet.subnet: Destroying... [id=subnet-1234567890]
aws_subnet.subnet: Destruction complete after 0s
Destroy complete! Resources: 1 destroyed.
awscli
コマンドでも確認してみる。
$ aws ec2 describe-subnets | jq -c .Subnets[].SubnetId
引数設定について考える
上ではサブネットを作成しましたが、aws_instance
リソースタイプではインスタンスを作成することが出来ます。aws_instance
はsubnet_id
でサブネットIDを指定する必要があるため、サブネットとインスタンスを一括で作成したい場合は、サブネットリソースからIDを取得してaws_instance
にパラメータとして指定したい。この辺は、AWS CDKを使用する場合も考える機会が多いところです。
以下のようにしました。
- main.tf
variable "cidr" {
default = "172.31.0.0/24"
}
provider "aws" {
profile = "default"
region = "ap-northeast-1"
}
resource "aws_subnet" "subnet" {
vpc_id = "vpc-1234567890"
availability_zone = "ap-northeast-1a"
cidr_block = var.cidr
}
resource "aws_instance" "instance" {
ami = "ami-1234567890"
instance_type = "t2.micro"
subnet_id = aws_subnet.subnet.id
}
subnet_id
はサブネットリソースからid
を取得します。どのような内容が取得できるのかについては、apply
のログにリソースとともに生成されているアトリビュートが記載されているので分かりやすいです。var.cidr
はvariable
で変数を定義しています。
- 実行
> terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.instance will be created
(略)
Only 'yes' will be accepted to approve.
Enter a value:
yes
と入力して続けます。
Enter a value: yes
aws_subnet.subnet: Creating...
aws_subnet.subnet: Creation complete after 1s [id=subnet-1234567890]
aws_instance.instance: Creating...
aws_instance.instance: Still creating... [10s elapsed]
aws_instance.instance: Still creating... [20s elapsed]
aws_instance.instance: Still creating... [30s elapsed]
aws_instance.instance: Creation complete after 34s [id=i-1234567890]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
完了しました。
- 確認
> aws ec2 describe-subnets | jq -c .Subnets[].SubnetId
"subnet-1234567890"
> aws ec2 describe-instances | jq -c .Reservations[].Instances[].InstanceId
"i-1234567890"
問題なさそうです。
次は
初歩的なレベルではあるけれど、基本的な使い方は理解できたと思います。ただtfvars
などの分離の考え方やmodule
の使用方法、より良い構成管理の方法など、まだ詳しく見ることが出来ていない箇所も多いのでその辺を見ていきたいところ。
独自言語(DSL)ということで少々怯えていたこともあり腰が重くなっていたのだけど、想定していたより遥かに簡単に書けて嬉しさあり悲しさありといったところ。悲しさ、というのは技術におけるそういう匂いを感じ取ることが出来ない自分自身に対してです。嗅覚を強くしたい。