手作成したAWSリソースをTerraform管理する

7 min read読了の目安(約6700字

前提

  • 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個じゃないでしょうから、体力と気持ちの続く限り、繰り返します。

参考