#httpリクエストを受け付けるLBと、そのLBへのhttpリクエストを許可するセキュリティグループを作成
下記コードをmain.tfに追記
# SecurityGroup
# https://www.terraform.io/docs/providers/aws/r/security_group.html
resource "aws_security_group" "alb" {
name = "handson-alb"
description = "handson alb"
vpc_id = "${aws_vpc.main.id}"
# セキュリティグループ内のリソースからインターネットへのアクセスを許可する
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "handson-alb"
}
}
# SecurityGroup Rule
# https://www.terraform.io/docs/providers/aws/r/security_group.html
resource "aws_security_group_rule" "alb_http" {
security_group_id = "${aws_security_group.alb.id}"
# セキュリティグループ内のリソースへインターネットからのアクセスを許可する
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# ALB
# https://www.terraform.io/docs/providers/aws/d/lb.html
resource "aws_lb" "main" {
load_balancer_type = "application"
name = "handson"
security_groups = ["${aws_security_group.alb.id}"]
subnets = ["${aws_subnet.public_1a.id}", "${aws_subnet.public_1c.id}", "${aws_subnet.public_1d.id}"]
}
planで確認後apply
コンソール上でALBが起動していることを確認
DNS名を確認
この時点ではロードバランサの設定(リスナーの追加)を行っていないためALBにアクセスできないため “リスナー” を確認すると設定が1つもないことを確認することができる
#リスナーの設定
ALBに登録されているDNSへhttpでアクセスすると “ok” の固定レスポンスを返すように設定
“ok” を返すためにはALBのリスナーの設定を追加する
# Listener
# https://www.terraform.io/docs/providers/aws/r/lb_listener.html
resource "aws_lb_listener" "main" {
# HTTPでのアクセスを受け付ける
port = "80"
protocol = "HTTP"
# ALBのarnを指定します。
#XXX: arnはAmazon Resource Names の略で、その名の通りリソースを特定するための一意な名前(id)です。
load_balancer_arn = "${aws_lb.main.arn}"
# "ok" という固定レスポンスを設定する
default_action {
type = "fixed-response"
fixed_response {
content_type = "text/plain"
status_code = "200"
message_body = "ok"
}
}
}
planで確認後apply
ALBがhttpを受け付けるようになったことを確認
ALBのDNSへアクセスし、 “ok” が返ってくることを確認
#ECSは “コントロールプレーン” と “データプレーン” の2つに別れる
データプレーンは1台以上のEC2をリソースプールとして扱うもので、データプレーン上にコンテナは配置される
コントロールプレーンはデータプレーン上へコンテナの配置とその管理を行う
EC2を立てて、ECSのコンソール上で「どんなコンテナが必要か」定義する
ECSを使用する際に重要なのは “タスク定義” “サービス” “タスク”
「タスク定義を作成し、そのタスク定義をもとにサービスを起動」
- タスク定義
- どんなコンテナをどんな設定で動かすかを定義する
- サービス
- どのタスク定義でコンテナを立ち上げ、そのコンテナとどのロードバランサ(ターゲットグループ, リスナー)と紐付けるか
- タスク
- タスク定義をもとに起動したコンテナをタスクと呼ぶ
#Fargate
コンテナを動かすリソースプールとして、開発者が管理するEC2郡ではなくAWSがマネージするリソースプールを使用
nginxを立ち上げるための設定
# Task Definition
# https://www.terraform.io/docs/providers/aws/r/ecs_task_definition.html
resource "aws_ecs_task_definition" "main" {
family = "handson"
# データプレーンの選択
requires_compatibilities = ["FARGATE"]
# ECSタスクが使用可能なリソースの上限
# タスク内のコンテナはこの上限内に使用するリソースを収める必要があり、メモリが上限に達した場合OOM Killer にタスクがキルされる
cpu = "256"
memory = "512"
# ECSタスクのネットワークドライバ
# Fargateを使用する場合は"awsvpc"決め打ち
network_mode = "awsvpc"
# 起動するコンテナの定義
# 「nginxを起動し、80ポートを開放する」設定を記述。
container_definitions = <<EOL
[
{
"name": "nginx",
"image": "nginx:1.14",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
]
}
]
EOL
}
planで確認後apply
#ECSクラスターの作成
# ECS Cluster
# https://www.terraform.io/docs/providers/aws/r/ecs_cluster.html
resource "aws_ecs_cluster" "main" {
name = "handson"
}
planで確認後apply
#サービス
サービスはタスク定義をもとにタスク(コンテナ)を立ち上げ、そのタスクとロードバランサを紐付ける
#ロードバランサの設定を追加
サービスとロードバランサを紐付けるための設定を追加
ロードバランサとコンテナの紐付けは”ターゲットグループ”と”リスナー”
- ターゲットグループ
- ヘルスチェックを行う
- リスナー
- ロードバランサがリクエスト受けた際、どのターゲットグループへリクエストを受け渡すのかの設定
# ELB Target Group
# https://www.terraform.io/docs/providers/aws/r/lb_target_group.html
resource "aws_lb_target_group" "main" {
name = "handson"
# ターゲットグループを作成するVPC
vpc_id = "${aws_vpc.main.id}"
# ALBからECSタスクのコンテナへトラフィックを振り分ける設定
port = 80
protocol = "HTTP"
target_type = "ip"
# コンテナへの死活監視設定
health_check = {
port = 80
path = "/"
}
}
# ALB Listener Rule
# https://www.terraform.io/docs/providers/aws/r/lb_listener_rule.html
resource "aws_lb_listener_rule" "main" {
# ルールを追加するリスナー
listener_arn = "${aws_lb_listener.main.arn}"
# 受け取ったトラフィックをターゲットグループへ受け渡す
action {
type = "forward"
target_group_arn = "${aws_lb_target_group.main.id}"
}
# ターゲットグループへ受け渡すトラフィックの条件
condition {
field = "path-pattern"
values = ["*"]
}
}
planで確認後apply
#サービスの作成
# SecurityGroup
# https://www.terraform.io/docs/providers/aws/r/security_group.html
resource "aws_security_group" "ecs" {
name = "handson-ecs"
description = "handson ecs"
# セキュリティグループを配置するVPC
vpc_id = "${aws_vpc.main.id}"
# セキュリティグループ内のリソースからインターネットへのアクセス許可設定
# 今回の場合DockerHubへのPullに使用する。
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "handson-ecs"
}
}
# SecurityGroup Rule
# https://www.terraform.io/docs/providers/aws/r/security_group.html
resource "aws_security_group_rule" "ecs" {
security_group_id = "${aws_security_group.ecs.id}"
# インターネットからセキュリティグループ内のリソースへのアクセス許可設定
type = "ingress"
# TCPでの80ポートへのアクセスを許可する
from_port = 80
to_port = 80
protocol = "tcp"
# 同一VPC内からのアクセスのみ許可
cidr_blocks = ["10.0.0.0/16"]
}
# ECS Service
# https://www.terraform.io/docs/providers/aws/r/ecs_service.html
resource "aws_ecs_service" "main" {
name = "handson"
# 依存関係の記述。
# "aws_lb_listener_rule.main" リソースの作成が完了するのを待ってから当該リソースの作成を開始する。
# "depends_on" は "aws_ecs_service" リソース専用のプロパティではなく、Terraformのシンタックスのため他の"resource"でも使用可能
depends_on = ["aws_lb_listener_rule.main"]
# 当該ECSサービスを配置するECSクラスターの指定
cluster = "${aws_ecs_cluster.main.name}"
# データプレーンとしてFargateを使用する
launch_type = "FARGATE"
# ECSタスクの起動数を定義
desired_count = "1"
# 起動するECSタスクのタスク定義
task_definition = "${aws_ecs_task_definition.main.arn}"
# ECSタスクへ設定するネットワークの設定
network_configuration = {
# タスクの起動を許可するサブネット
subnets = ["${aws_subnet.private_1a.id}", "${aws_subnet.private_1c.id}", "${aws_subnet.private_1d.id}"]
# タスクに紐付けるセキュリティグループ
security_groups = ["${aws_security_group.ecs.id}"]
}
# ECSタスクの起動後に紐付けるELBターゲットグループ
load_balancer = [
{
target_group_arn = "${aws_lb_target_group.main.arn}"
container_name = "nginx"
container_port = "80"
},
]
}
planで確認後apply
コンソールでロードバランサのDNS名にアクセスしnginxが起動していることを確認