🔥
手作成したAWSリソースをTerraform管理する
前提
- AWS CLIやAWSマネコンで、いろいろと構築した山がある
- いいかげんTerraformで管理したいと思い幾年
install terraform with asdf
asdf で terraform を入れます。
❯ asdf list all terraform | tail -n3
0.15.0-rc1
0.15.0-rc2
0.15.0
❯ asdf install terraform 0.15.0
Downloading terraform version 0.15.0 from https://releases.hashicorp.com/terraform/0.15.0/terraform_0.15.0_linux_amd64.zip
Cleaning terraform previous binaries
Creating terraform bin directory
Extracting terraform archive
❯ asdf global terraform 0.15.0
❯ terraform version
Terraform v0.15.0
on linux_amd64
tfstate の保管 & ロックのため、S3 と DynamoDB を構築する
本番運用やチーム開発を視野に入れると必須ですね。最初に作っておきます。
セキュリティグループをTerraform管理してみる
こういう端っこからやっていきます。
tf に枠を作っておく
security-group.tf を以下の内容で作ります。
resource "aws_security_group" "alb-web-sg" {
}
terraform import "tf内のリソース名" "AWSでのID"
件のセキュリティグループIDを調べ terraform import します。
❯ terraform import aws_security_group.alb-web-sg sg-0b21077fb303c2e2a
Acquiring state lock. This may take a few moments...
aws_security_group.alb-web-sg: Importing from ID "sg-0b21077fb303c2e2a"...
aws_security_group.alb-web-sg: Import prepared!
Prepared aws_security_group for import
aws_security_group.alb-web-sg: Refreshing state... [id=sg-0b21077fb303c2e2a]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Releasing state lock. This may take a few moments...
terraform state show "tf内のリソース名"
S3に保管されてる tfstate の全文を見れます。こいつを security-group.tf にコピペします。まるごとコピペです。なんか要らんもん削ったほうが、とか、そういうことは考えない。
❯ terraform state show aws_security_group.alb-web-sg
# aws_security_group.alb-web-sg:
resource "aws_security_group" "alb-web-sg" {
arn = "arn:aws:ec2:us-east-1:841403573067:security-group/sg-0b21077fb303c2e2a"
description = "alb-web-sg"
egress = [
{
cidr_blocks = [
"0.0.0.0/0",
]
description = ""
from_port = 0
ipv6_cidr_blocks = []
prefix_list_ids = []
protocol = "-1"
security_groups = []
self = false
to_port = 0
},
]
id = "sg-0b21077fb303c2e2a"
ingress = [
{
cidr_blocks = [
"xxx.xxx.xxx.xxx/32",
]
description = ""
from_port = 443
ipv6_cidr_blocks = []
prefix_list_ids = []
protocol = "tcp"
security_groups = []
self = false
to_port = 443
},
{
cidr_blocks = [
"xxx.xxx.xxx.xxx/32",
]
description = ""
from_port = 80
ipv6_cidr_blocks = []
prefix_list_ids = []
protocol = "tcp"
security_groups = []
self = false
to_port = 80
},
]
name = "alb-web-sg"
owner_id = "841403573067"
tags = {}
vpc_id = "vpc-0c0d01192ea2e6027"
timeouts {}
}
terraform plan
tfstate からコピペったのを、そのまま terraform plan すると、いくらなんでもダメでしょうと怒られます。arn, id, owner_id は .tf には書いておけないので、こういうのだけし仕方なく .tf から削除します。
❯ terraform plan
Acquiring state lock. This may take a few moments...
Releasing state lock. This may take a few moments...
╷
│ Error: Computed attributes cannot be set
│
│ on security-group.tf line 3, in resource "aws_security_group" "alb-web-sg":
│ 3: arn = "arn:aws:ec2:us-east-1:841403573067:security-group/sg-0b21077fb303c2e2a"
│
│ Computed attributes cannot be set, but a value was set for "arn".
╵
╷
│ Error: Invalid or unknown key
│
│ on security-group.tf line 20, in resource "aws_security_group" "alb-web-sg":
│ 20: id = "sg-0b21077fb303c2e2a"
│
╵
╷
│ Error: Computed attributes cannot be set
│
│ on security-group.tf line 50, in resource "aws_security_group" "alb-web-sg":
│ 50: owner_id = "841403573067"
│
│ Computed attributes cannot be set, but a value was set for "owner_id".
╵
指摘に従い security-group.tf を調整しリトライ。今度は大丈夫です。tfstate と全く差のない tf なので、planしても No Changes になります。
❯ terraform plan
Acquiring state lock. This may take a few moments...
aws_dynamodb_table.tfstate_lock: Refreshing state... [id=sasasin-terraform-hello]
aws_security_group.alb-web-sg: Refreshing state... [id=sg-0b21077fb303c2e2a]
aws_s3_bucket.tfstate: Refreshing state... [id=sasasin-terraform-hello]
aws_s3_bucket_public_access_block.tfstate: Refreshing state... [id=sasasin-terraform-hello]
No changes. Infrastructure is up-to-date.
This means that Terraform did not detect any differences between your configuration and the remote system(s). As a result, there are no actions to take.
Releasing state lock. This may take a few moments...
terraform apply
tfstate と全く差のない tf なので、 apply しても No Changes になります。
❯ terraform apply
Acquiring state lock. This may take a few moments...
aws_dynamodb_table.tfstate_lock: Refreshing state... [id=sasasin-terraform-hello]
aws_security_group.alb-web-sg: Refreshing state... [id=sg-0b21077fb303c2e2a]
aws_s3_bucket.tfstate: Refreshing state... [id=sasasin-terraform-hello]
aws_s3_bucket_public_access_block.tfstate: Refreshing state... [id=sasasin-terraform-hello]
Releasing state lock. This may take a few moments...
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
git commit
ここまでで、セキュリティグループの1個をTerraform管理できたので、git commit します。
繰り返す
どうせ1個じゃないでしょうから、体力と気持ちの続く限り、繰り返します。
参考
- バージョン管理ツール「asdf」を使ってみる | 働くひとと組織の健康を創る iCARE
- asdf All Plugins
- Backend の S3 や DynamoDB 自体を terraform で管理するセットアップ方法 - Qiita
-
実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing)) | 野村 友規 | 工学 | Kindleストア | Amazon
- 「25章 既存リソースのインポート」で、細部は異なりますが terraform import する手順が詳細に記述されています。
- terraform import でしくじったら「24章 リファクタリング」を漁ると救いを見出せます。
- hashicorp/aws | Terraform Registry
Discussion