AWSの無料枠で出来る範囲のチュートリアルがあったので試してみた経過を簡単にまとめてみました。
AWS等の実際の画面や操作はどんな感じか知りたい方を読者対象としているつもりです。
著者はAWS クラウドプラクティショナー、ソリューションアーキテクト アソシエイト という資格を取得済みで「AWSってなんぞや?」という概要を知識としてある程度理解しているが、実際にAWSの画面を触ったことが無いという状態でAWSのチュートリアルをこなしていくという状況です。
今回の内容としては、Terraform を用いて ALB + HTTPS を構築するというものです。
注意点
おすすめ(王道)
👉 Route53でドメイン取得(数百円〜)
練習用(簡易)
👉 HTTPのままALBだけ作る
今回は練習用の方で行きます。
前回のおさらいコード
main.tf
############################################
# プロバイダー設定(AWS東京リージョン)
############################################
provider "aws" {
region = "ap-northeast-1"
}
############################################
# VPC(ネットワークの土台)
############################################
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "terraform-vpc"
}
}
############################################
# インターネットゲートウェイ(外部通信)
############################################
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.main.id
tags = {
Name = "terraform-igw"
}
}
############################################
# パブリックサブネット(インターネット接続用)
############################################
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
# EC2起動時にパブリックIP自動付与
map_public_ip_on_launch = true
tags = {
Name = "terraform-public-subnet"
}
}
############################################
# ルートテーブル(通信経路の定義)
############################################
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.main.id
# インターネットへのルート
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "terraform-public-rt"
}
}
############################################
# サブネットとルートテーブルの関連付け
############################################
resource "aws_route_table_association" "public_assoc" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public_rt.id
}
############################################
# セキュリティグループ(通信制御)
############################################
resource "aws_security_group" "web_sg" {
name = "web-sg"
vpc_id = aws_vpc.main.id
# HTTP(Webアクセス)
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# SSH(接続用)※本番では制限推奨
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"]
}
tags = {
Name = "terraform-web-sg"
}
}
############################################
# EC2インスタンス(Webサーバー)
############################################
resource "aws_instance" "web" {
ami = "ami-0c3fd0f5d33134a76" # Amazon Linux 2
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
associate_public_ip_address = true
##########################################
# user_data(起動時に自動実行されるスクリプト)
##########################################
user_data = <<-EOF
#!/bin/bash
exec > /var/log/user-data.log 2>&1
# 少し待つ(初期化安定のため)
sleep 30
# nginxインストール(Amazon Linux 2)
amazon-linux-extras install -y nginx1
# nginx起動
systemctl start nginx
# 自動起動設定
systemctl enable nginx
EOF
tags = {
Name = "terraform-nginx"
}
}
############################################
# 出力(IPを表示)
############################################
output "public_ip" {
value = aws_instance.web.public_ip
}
output "public_dns" {
value = aws_instance.web.public_dns
}
今回main.tfに「追記」するコード
ALBには、サブネットが2つ以上必要な点に注意です。
main.tf
output "public_dns" {
value = aws_instance.web.public_dns
}
# ターゲットグループ
resource "aws_lb_target_group" "tg" {
name = "terraform-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
path = "/"
port = "traffic-port"
}
}
# ALB(ロードバランサー)
resource "aws_lb" "alb" {
name = "terraform-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
# 👇 サブネット2つにするために、ここを2つにする
subnets = [
aws_subnet.public.id,
aws_subnet.public2.id
]
tags = {
Name = "terraform-alb"
}
}
# ALB用セキュリティグループ
resource "aws_security_group" "alb_sg" {
name = "alb-sg"
vpc_id = aws_vpc.main.id
# インターネット → ALB
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# インターネット → ALB (https)
ingress {
from_port = 443
to_port = 443
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_lb_listener" "listener" {
load_balancer_arn = aws_lb.alb.arn
port = 80
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.tg.arn
}
}
# EC2をターゲットに登録
resource "aws_lb_target_group_attachment" "tg_attach" {
target_group_arn = aws_lb_target_group.tg.arn
target_id = aws_instance.web.id
port = 80
}
# 出力(ALB URL)
output "alb_dns" {
value = aws_lb.alb.dns_name
}
# サブネット追加(ALBには2つ以上のサブネットが必要)
resource "aws_subnet" "public2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-northeast-1c"
map_public_ip_on_launch = true
tags = {
Name = "terraform-public-subnet-2"
}
}
# ルートテーブル関連付け(サブネット2を関連付ける)
resource "aws_route_table_association" "public_assoc2" {
subnet_id = aws_subnet.public2.id
route_table_id = aws_route_table.public_rt.id
}
main.tf に上記コードを続けて記載し、bash で
terraform apply
を実行し、成功すると
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
Outputs:
alb_dns = "terraform-alb-123456789.ap-northeast-1.elb.amazonaws.com"
public_dns = ""
public_ip = "12.345.678.901"
のような表示がなされます。
ここで、
# nginx が表示される
http://terraform-alb-123456789.ap-northeast-1.elb.amazonaws.com
# nginx が表示されない
http://12.345.678.901
となればOKです。
今の構成は
インターネット
↓
ALB(許可)
↓
EC2(ALBからのみ許可)
という状態です。
これが意味すること
✔ 外部から直接EC2に侵入できない
✔ 必ずALBを通る
→ 入口を1つに絞った