terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
data "aws_region" "current" {}
data "aws_vpc" "default" {
default = true
}
# 🛡️ 1. セキュリティグループ(しっかり改行しました)
resource "aws_security_group" "web_sg" {
name = "ecr-web-sg"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "dns_sg" {
name = "custom-dns-sg"
vpc_id = data.aws_vpc.default.id
ingress {
from_port = 53
to_port = 53
protocol = "udp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 53
to_port = 53
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# 📦 2. ECRリポジトリの作成
resource "aws_ecr_repository" "apache_repo" {
name = "ctf-apache"
force_delete = true
}
resource "aws_ecr_repository" "nginx_repo" {
name = "ctf-nginx"
force_delete = true
}
# 🚀 3. ローカルのKali上でスクリプトを実行し、ECRへPushさせる魔法
resource "null_resource" "push_images" {
depends_on = [aws_ecr_repository.apache_repo, aws_ecr_repository.nginx_repo]
provisioner "local-exec" {
command = "bash push_images.sh ${data.aws_region.current.name} ${aws_ecr_repository.apache_repo.repository_url} ${aws_ecr_repository.nginx_repo.repository_url}"
}
}
# 🔑 4. EC2がECRからPullするためのIAMロール
resource "aws_iam_role" "ec2_ecr_role" {
name = "EC2-ECR-PullRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Principal = { Service = "ec2.amazonaws.com" }
Effect = "Allow"
}
]
})
}
resource "aws_iam_role_policy_attachment" "ecr_readonly" {
role = aws_iam_role.ec2_ecr_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
}
resource "aws_iam_instance_profile" "ec2_ecr_profile" {
name = "ec2-ecr-profile"
role = aws_iam_role.ec2_ecr_role.name
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
}
}
# 💻 5. Webサーバー構築(Apache / Nginx)
resource "aws_instance" "apache_server" {
depends_on = [null_resource.push_images]
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.ec2_ecr_profile.name
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
apt-get update && apt-get install -y docker.io
snap install aws-cli --classic
aws ecr get-login-password --region ${data.aws_region.current.name} | docker login --username AWS --password-stdin ${aws_ecr_repository.apache_repo.repository_url}
docker run -d -p 80:80 ${aws_ecr_repository.apache_repo.repository_url}:latest
EOF
tags = { Name = "ctf-apache" }
}
resource "aws_instance" "nginx_server" {
depends_on = [null_resource.push_images]
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
iam_instance_profile = aws_iam_instance_profile.ec2_ecr_profile.name
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
apt-get update && apt-get install -y docker.io
snap install aws-cli --classic
aws ecr get-login-password --region ${data.aws_region.current.name} | docker login --username AWS --password-stdin ${aws_ecr_repository.nginx_repo.repository_url}
docker run -d -p 80:80 ${aws_ecr_repository.nginx_repo.repository_url}:latest
EOF
tags = { Name = "ctf-nginx" }
}
# 🌐 WebサーバーのEIP
resource "aws_eip" "apache_eip" {
instance = aws_instance.apache_server.id
domain = "vpc"
}
resource "aws_eip" "nginx_eip" {
instance = aws_instance.nginx_server.id
domain = "vpc"
}
resource "time_sleep" "wait_300_seconds" {
# 【重要】第2ドミノ(Webサーバー2台)が作られるのを待ってからタイマーを起動!
depends_on = [
aws_instance.apache_server,
aws_instance.nginx_server
]
# 待機時間を300秒(5分)に設定
create_duration = "300s"
}
# 🧠 6. DNSサーバー構築(インデント罠排除 & あなたのhosts仮説版)
resource "aws_instance" "dns_server" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.dns_sg.id]
depends_on = [time_sleep.wait_300_seconds]
# 【重要】インデントを一切付けず、完全に左端から書き始めます
user_data = < /etc/resolv.conf
# 2. Dnsmasqのインストール
apt-get update && apt-get install -y dnsmasq
# 3. 【あなたの仮逃】eth0を指定した、無駄のないクリーンな設定
cat << 'EOD' > /etc/dnsmasq.conf
port=53
listen-address=0.0.0.0
bogus-priv
addn-hosts=/etc/hosts-dnsmasq
resolv-file=/etc/resolv.conf
bind-interfaces
local-ttl=60
EOD
# 4. 【あなたの仮説】名前解決の組み合わせを専用のhostsファイルに書き込む
echo "${aws_instance.apache_server.public_ip} apache-test.com" > /etc/hosts-dnsmasq
echo "${aws_instance.nginx_server.public_ip} nginx-test.com" >> /etc/hosts-dnsmasq
# 5. Dnsmasqを確実に再起動
systemctl restart dnsmasq
ufw allow 53
EOF
tags = { Name = "ctf-dns" }
}
resource "aws_eip" "dns_eip" {
instance = aws_instance.dns_server.id
domain = "vpc"
}
output "DNS_SERVER_IP" {
value = aws_eip.dns_eip.public_ip
}