Terraform の aws_route_table が何もしてないのに壊れた
月イチ連載になるのか?「何もしてないのに壊れた」シリーズ
2019-12にterraformしたAWS上の開発環境を、サブセットにしてもう一丁建立というタスクが発生したのです。
- tf コード一式をコピー
- 不要なところを削除
-
tags.Name
とかsubnet.cidr_block
とかの環境固有部分を置換 terraform init
terraform plan
terraform apply
-
serverspec
で疎通テスト
毎日とか毎週の頻度じゃないけど、いつもの段取りでやれる作業のはずだったのです。
未知のエラーとの遭遇
typoがないか、環境固有値の設定漏れがないか code差分チェックして、いよいよ terraform plan
するとこれまで見たことのないエラーが出ました。
$ terraform plan
...
Error: expected "route.0.ipv6_cidr_block" to be a valid IPv4 Value, got : invalid CIDR address:
on route.tf line 17, in resource "aws_route_table" "private-rt":
17: resource "aws_route_table" "private-rt" {
なぜ? ipv6 のところに IPv4 Value なの? まあ、言われたとおりにしてみます。
ipv6_cidr_block = "0.0.0.0/0"
たしかに terraform plan は通るようになるのですが、 terraform apply
すると
Enter a value: yes
aws_route_table.private-rt: Modifying... [id=rtb-xxxxxxxxxxxxxxxx]
Error: Error creating route: InvalidParameterCombination: The parameter destinationCidrBlock cannot be used with the parameter destinationIpv6CidrBlock
status code: 400, request id: xxxx
on route.tf line 17, in resource "aws_route_table" "private-rt":
17: resource "aws_route_table" "private-rt" {
そりゃそうだろうと。空文字列が気にいらなかったのかな、
ipv6_cidr_block = "::/0"
Enter a value: yes
aws_route_table.private-rt: Modifying... [id=rtb-xxxxxxxxxxxxxxxx]
Error: Error creating route: InvalidParameterCombination: The parameter destinationCidrBlock cannot be used with the parameter destinationIpv6CidrBlock
terraform plan
は通っても terraform apply
はできない。
terraform import
コピペ元の aws_route_table
の resource文
resource "aws_route_table" "private-rt" {
route = [
{
cidr_block = "0.0.0.0/0"
egress_only_gateway_id = ""
gateway_id = ""
instance_id = ""
ipv6_cidr_block = ""
nat_gateway_id = aws_nat_gateway.ngw.id
network_interface_id = ""
transit_gateway_id = ""
vpc_peering_connection_id = ""
},
]
tags = {
"Name" = "private-rt"
}
vpc_id = data.aws_vpc.vpc.id
}
このresource文の出所は、既存 route_table を terraform import
して terraform state show
した結果だったはず。
既存環境の route table の 現時点で state show した結果もこの形式になっています。
$ terraform state show aws_route_table."private-rt"
# aws_route_table.private-rt:
resource "aws_route_table" "private-rt" {
id = "rtb-xxxxxxxxxxxxxxxx"
owner_id = "xxxxxxxx"
propagating_vgws = []
route = [
{
cidr_block = "0.0.0.0/0"
egress_only_gateway_id = ""
gateway_id = ""
instance_id = ""
ipv6_cidr_block = ""
nat_gateway_id = "nat-xxxxxxxxxxxxxxxxf"
network_interface_id = ""
transit_gateway_id = ""
vpc_peering_connection_id = ""
},
]
tags = {
"Name" = "private-rt"
}
vpc_id = "vpc-xxxxxxxx"
}
「何もしてないのに壊れた」
コード修正
https://www.terraform.io/docs/providers/aws/r/route_table.html
aws_route_table の公式構文は state show結果と随分と違うみたい。
こちらに合わせて下記で通った。
resource "aws_route_table" "private-rt" {
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.ngw.id
}
tags = {
"Name" = "private-rt"
}
vpc_id = data.aws_vpc.vpc.id
}
実行環境
- Amazon Linux 2
- Terraform v0.12.26
- aws-cli/1.16.102 Python/2.7.16 Linux/4.14.138-114.102.amzn2.x86_64 botocore/1.12.92