前回の記事で記載している、副産物の記事になります。
構成図
まずは構成図でおさらいです。
今回の副産物はWeb Serverの構成関連です。
1.EC2のローカルIPアドレスをDHCPにする。
今までTerraformでEC2を構築する際、ローカルIPアドレスを固定IPアドレスで構築していましたが、今回ALBがDHCPなのでTerraform実行時に何度かIPアドレスが重複して失敗しました。
EC2のIPアドレスをDHCPで構成する場合どうしたら良いか知らなかったので調べてみたのですが、一発で出てこなかったので個人メモに近いですが記載します。
具体的なtfファイル上の記載は以下の通りです。
# Front End(Web Server) 1台目
resource "aws_instance" "ec2_app01" {
ami = data.aws_ssm_parameter.al2023-ami-kernel-default-x86_64.value
instance_type = var.ec2_instance_type
availability_zone = var.availability_zone.a
vpc_security_group_ids = [aws_security_group.sg_ec2_app01.id]
subnet_id = aws_subnet.sn_private_1a.id
# private_ip = "${var.vpc_address_pre}1.21"
associate_public_ip_address = "false"
iam_instance_profile = aws_iam_instance_profile.instance_prof.name
user_data = <<-EOF
#!/bin/bash
sudo hostnamectl set-hostname ${var.env_type}-${var.sys_name}-ec2-app01
sudo dnf update -y
sudo dnf install -y httpd php
sudo systemctl start httpd
sudo systemctl enable httpd
sudo usermod -a -G apache ec2-user
sudo usermod -a -G apache ssm-user
sudo chown -R ec2-user:apache /var/www
sudo chown -R ssm-user:apache /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;
echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
echo "It Works! ec2-app01" >/var/www/html/index.html
EOF
root_block_device {
volume_size = 30 # GB
volume_type = "gp3" # 汎用SSD
encrypted = false
tags = {
Snapshot = "false"
}
}
tags = {
Name = "${var.env_type}-${var.sys_name}-ec2-app01"
}
depends_on = [
aws_route_table_association.associate_rt_sn_private_1a
]
}
固定IPアドレスにする場合は
private_ip = "${var.vpc_address_pre}1.21"
なのですが、これをコメントアウトする、つまり固定IPアドレスにしないという設定がDHCPの設定になる、ということでした。
2.EC2のヒアドキュメントを正常に実行するため、各リソース構築の順序を制御する
これもec2.tfファイル内で記載している通りなのですが、sudo dnf update -y
とsudo dnf install -y httpd php
を実行していますが、NAT Gateway経由でインターネットに接続するようにしているので、NAT Gateway構築前にEC2の構築が完了してしまい、これらのコマンドがコケます。
再現性は100%です。
NAT Gatewayは構築に時間のかかるリソースなので、まぁ仕方ないのかな、という感じですが、これをちゃんと制御できるようにする方法を個人の予想を含めて記載します。
depends_on = [
aws_route_table_association.associate_rt_sn_private_1a
]
これで順序を制御可能です。
このdepends_on
の処理の後にEC2の構築が行われます。
ちょっと調べたところNAT Gatewayの構築後にEC2を構築する、というだけでいいのであれば、
depends_on = [
aws_nat_gateway.nat_1a
]
のような記述で良いのですが、これだと3台あるEC2のうち最初の1台だけがdnfコマンドが実行され、残りの2台はdnfコマンドがコケました。
こちらも再現率100%でした。
色々考えたのですが恐らく、EC2の構築順序はNAT Gatewayの後に行われているはずなのですが、NAT Gateway経由でEC2がインターネット接続する、というルートテーブルの定義が間に合ってないのではないか、と考えました。
つまり、
ルートテーブルでNAT Gateway宛ての通信が定義されている場合、ルートテーブル構築にはNAT Gatewayが必須なので、NAT Gatewayの構築が行われてからルートテーブルの構築が行われる
ということが予想されることから、各EC2のdepends_on
でaws_route_table_association.associate_rt_sn_private_1a
と定義しました。
この定義にすると、ルートテーブルの構築後にEC2の構築が行われることとなり、ルートテーブルが構築されているということは暗黙的にNAT Gatewayは構築済みである、ということになるため、EC2がNAT Gateway経由でインターネット接続を行うという前提条件がすべて揃います。
予想が正しかったのか、これでEC2内のヒアドキュメントがコケることはなくなりました。
(本来的にはログを見たり公式の情報を調べたりして裏を取るべきですが、今回は案件ではない検証なのでいったんこのままで良いかなと考えています。)
どちらも小ネタですが、何気に便利な部分なので記事にしました。
本日はここまで。