Browse Source

start multi availability region ecs fargate

main
gabriel becker 1 year ago
parent
commit
349665a585
  1. 4
      README.md
  2. 13
      aws_fargate/config.tf
  3. 39
      aws_fargate/iam.tf
  4. 39
      aws_fargate/main.tf
  5. 129
      aws_fargate/network.tf
  6. 0
      aws_fargate/outputs.tf
  7. 25
      aws_fargate/variables.tf

4
README.md

@ -3,4 +3,6 @@
Provisioning scripts for personal learning.
References
- [gruntwork](https://blog.gruntwork.io/an-introduction-to-terraform-f17df9c6d180)
- [gruntwork](https://blog.gruntwork.io/an-introduction-to-terraform-f17df9c6d180)
- https://section411.com/2019/07/hello-world/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_task_definition

13
aws_fargate/config.tf

@ -0,0 +1,13 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~>4.0"
}
}
}
provider "aws" {
region = var.region
profile = var.profile
}

39
aws_fargate/iam.tf

@ -0,0 +1,39 @@
resource "aws_iam_role" "api_exec_role" {
name = "${var.project}-exec-role"
assume_role_policy = data.aws_iam_policy_document.api_exec_assume_role.json
}
data "aws_iam_policy_document" "api_exec_assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ecs-task.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "ecs_exec_iam_attach_assume_role" {
role = aws_iam_role.api_exec_role.name
policy_arn = data.aws_iam_policy_document.api_exec_assume_role
}
data "aws_iam_policy_document" "ecs_exec_role" {
statement {
effect = "Allow"
actions = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
resources = ["*${var.project}*"]
}
}
resource "aws_iam_role_policy_attachment" "ecs_exec_iam_attach_rules" {
role = aws_iam_role.api_exec_role.name
policy_arn = data.aws_iam_policy_document.ecs_exec_role.json
}

39
aws_fargate/main.tf

@ -0,0 +1,39 @@
resource "aws_ecs_service" "api_ecs" {
name = "${var.project}-api"
task_definition = aws_ecs_task_definition.api_task.arn
launch_type = "FARGATE"
}
resource "aws_ecs_task_definition" "api_task" {
family = "${var.project}-api"
cpu = 256
memory = 512
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
execution_role_arn = aws_iam_role.api_exec_role.arn
container_definitions = jsonencode([
{
name = "${var.project}-api",
image = var.container_image,
portMappings = [
{
containerPort = 3000
}
],
logConfiguration = {
logDriver = "awslogs",
options = {
awslogs-region = var.region,
awslogs-group = "/ecs/${var.project}-api",
awslogs-stream-prefix = "ecs"
}
}
}
])
}
resource "aws_cloudwatch_log_group" "log_group" {
name = "/ecs/${var.project}-api"
}

129
aws_fargate/network.tf

@ -0,0 +1,129 @@
resource "aws_vpc" "app_vpc" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public_subnet" {
count = length(var.subnets)
vpc_id = aws_vpc.app_vpc.id
availability_zone = element(keys(var.subnets), count.index)
cidr_block = "10.0.${count.index}.0/25"
tags = {
"Name" = "public | ${element(keys(var.subnets), count.index)}"
}
}
resource "aws_subnet" "private_subnet" {
count = length(var.subnets)
vpc_id = aws_vpc.app_vpc.id
availability_zone = element(keys(var.subnets), count.index)
cidr_block = "10.0.${count.index}.128/25"
tags = {
"Name" = "private | ${element(keys(var.subnets), count.index)}"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.app_vpc.id
tags = {
"Name" = "public"
}
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.app_vpc.id
tags = {
"Name" = "private"
}
}
resource "aws_route_table_association" "public_subnet" {
count = length(var.subnets)
subnet_id = element(aws_subnet.public_subnet.*.id, count.index)
route_table_id = aws_route_table.public.id
}
resource "aws_route_table_association" "private_subnet" {
count = length(var.subnets)
subnet_id = element(aws_subnet.private_subnet.*.id, count.index)
route_table_id = aws_route_table.private.id
}
resource "aws_eip" "nat" {
vpc = true
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.app_vpc.id
}
resource "aws_nat_gateway" "ngw" {
count = length(var.subnets)
subnet_id = element(aws_subnet.private_subnet.*.id, count.index)
allocation_id = aws_eip.nat.id
depends_on = [aws_internet_gateway.igw]
}
resource "aws_route" "public_igw" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
resource "aws_route" "private_ngw" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.ngw.id
}
resource "aws_security_group" "http" {
name = "http"
description = "HTTP traffic"
vpc_id = aws_vpc.app_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "TCP"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "https" {
name = "https"
description = "HTTPS traffic"
vpc_id = aws_vpc.app_vpc.id
ingress {
from_port = 443
to_port = 443
protocol = "TCP"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "egress_all" {
name = "egress-all"
description = "Allow all outbound traffic"
vpc_id = aws_vpc.app_vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "ingress_api" {
name = "ingress-api"
description = "Allow ingress to API"
vpc_id = aws_vpc.app_vpc.id
ingress {
from_port = 3000
to_port = 3000
protocol = "TCP"
cidr_blocks = ["0.0.0.0/0"]
}
}

0
aws_fargate/outputs.tf

25
aws_fargate/variables.tf

@ -0,0 +1,25 @@
variable "region" {
default = "us-east-1"
}
variable "profile" {
default = "default"
}
variable "project" {
default = "template"
}
variable "container_image" {
default = "ghcr.io/jimmysawczuk/sun-api:latest"
}
variable "subnets" {
description = "Availability zone for instance associated with ip ranges"
type = map(any)
default = {
"ap-southeast-2a" = "10.0.1.0/25"
"ap-southeast-2b" = "10.0.2.0/25"
"ap-southeast-2c" = "10.0.1.128/25"
}
}
Loading…
Cancel
Save