今回はTerraformでECS(Fargate)作成に挑戦してみた。
やること
TerraformでECS(Fargate)を作成、Serviceにはnginxを稼働させ、インターネット越しから接続できるよう環境を整え、インターネットからnginxのWelcomeページが表示できることを確認する。
前提
・Windows11で実施してます。
※Linuxで参考にする場合は"(ダブルクォーテーション)などを適宜変更要。
・jqがインストールされていること。
※なくてもいいですがCLIで調べるのが面倒になります
・aws vaultが設定されていること。
※設定していない場合は適宜profile周りを変更する
※設定方法は下記参照
amegaeru.hatenablog.jp
作成リソース
・VPC×1
・Subnet×2
・InternetGateway×1
・RouteTable×2
・IAMRole×1
・SecurityGroup×1
・SecurityGroup Rule×1
・ECS Cluster×1
・ECS TaskDefinition×1
・ECS Service×1
実践!
1.イメージ選定
今回はサンプルでDocker-Hubからnginx:latestを使用する。
2.作成
2-1.tfファイル作成
provider "aws" { region = "ap-northeast-1" profile = "testvault" } variable "env" { default = { env_name = "test" vpc_cidr = "10.0.0.0/16" sb_az1a = "ap-northeast-1a" sb_az1a_cidr = "10.0.1.0/24" sb_az1c = "ap-northeast-1c" sb_az1c_cidr = "10.0.2.0/24" } } ### VPC resource "aws_vpc" "vpc" { cidr_block = "${var.env.vpc_cidr}" tags = { Name = "${var.env.env_name}_vpc" } } ### Subnet resource "aws_subnet" "public_1a" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1a}" cidr_block = "${var.env.sb_az1a_cidr}" tags = { Name = "${var.env.env_name}_public_1a" } } resource "aws_subnet" "public_1c" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1c}" cidr_block = "${var.env.sb_az1c_cidr}" tags = { Name = "${var.env.env_name}_public_1c" } } ### InternetGateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "${var.env.env_name}_igw" } } ### RouteTable resource "aws_route_table" "public" { vpc_id = aws_vpc.vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.igw.id } tags = { Name = "${var.env.env_name}_public_route_table" } } resource "aws_route_table_association" "public_1a" { subnet_id = aws_subnet.public_1a.id route_table_id = aws_route_table.public.id } resource "aws_route_table_association" "public_1c" { subnet_id = aws_subnet.public_1c.id route_table_id = aws_route_table.public.id } ### SecurityGroup resource "aws_security_group" "my_sg" { name = "${var.env.env_name}_my-sg" description = "My security group for ECS tasks" vpc_id = aws_vpc.vpc.id } resource "aws_security_group_rule" "ingress_http" { type = "ingress" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.my_sg.id } resource "aws_security_group_rule" "egress_all" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.my_sg.id } ### IAM Role resource "aws_iam_role" "ecs_execution_role" { name = "${var.env.env_name}_ecs_execution_role" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Action = "sts:AssumeRole", Principal = { Service = "ecs-tasks.amazonaws.com" }, Effect = "Allow", Sid = "" } ] }) } ### ECS Cluster resource "aws_ecs_cluster" "my_cluster" { name = "${var.env.env_name}_my_cluster" } ### ECS TaskDefinition resource "aws_ecs_task_definition" "my_task" { family = "${var.env.env_name}_my_task" network_mode = "awsvpc" requires_compatibilities = ["FARGATE"] cpu = "256" memory = "512" execution_role_arn = aws_iam_role.ecs_execution_role.arn container_definitions = jsonencode([ { name = "${var.env.env_name}_my_container" ## 1.で決めたイメージを記載する。※サーバを指定しない場合、Docker-Hubから取得される。 image = "nginx:latest" portMappings = [ { containerPort = 80 hostPort = 80 } ] } ]) } ### ECS Service resource "aws_ecs_service" "my_service" { name = "${var.env.env_name}_my_service" cluster = aws_ecs_cluster.my_cluster.id task_definition = aws_ecs_task_definition.my_task.arn launch_type = "FARGATE" desired_count = 2 network_configuration { subnets = [aws_subnet.public_1a.id, aws_subnet.public_1c.id] security_groups = [aws_security_group.my_sg.id] assign_public_ip = true } }
2-2.適用
# terraform plan # terraform apply
2-3.確認
### VPC # aws ec2 describe-vpcs --profile testvault | jq ".Vpcs[] | .CidrBlock" "100.0.0/16" ### Subnet # aws ec2 describe-subnets --profile testvault | jq ".Subnets[] | .Tags[]?.Value " "test_public_1a" "test_public_1c" ### InternetGateway # aws ec2 describe-internet-gateways --profile testvault | jq ".InternetGateways[] | .Tags[].Value" "my-internetgw" ### RouteTable # aws ec2 describe-route-tables --profile testvault | jq ".RouteTables[] | .Associations[].RouteTableId" "rtb-00646f022be6c7ce8" ### SecurityGroup # aws ec2 describe-security-groups --profile testvault | jq ".SecurityGroups[] | .GroupName" | findstr "test" "test_my-sg" ### IAM Role # aws iam list-roles --profile testvault | jq ".Roles[] | .RoleName" | findstr "test" "test_ecs_execution_role" ### ECS Cluster # aws ecs list-clusters --profile testvault | jq ".clusterArns[]" "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:cluster/test_my_cluster" ### ECS TaskDefinition # aws ecs list-task-definitions --profile testvault | jq ".taskDefinitionArns" | findstr "test" "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:task-definition/test_my_task:1" ### ECS Service # aws ecs list-services --cluster test_my_cluster --profile testvault | jq ".serviceArns " "arn:aws:ecs:ap-northeast-1:xxxxxxxxxxxx:service/test_my_cluster/test_my_service"
2-4.動作確認
2-4-1.[ECS]-[クラスター]-[test-my-cluster]-[test_my-service]-[タスク]タブ-タスクを1つ選択し、パブリックIPをメモする。
2-4-2.ブラウザで下記にアクセスし、Welcomのページが表示されることを確認する。
http://[パブリックIP]
3.後始末
# terraform destroy
感想
結構作るものが多くて大変だった。(´Д`)