git checkout master
git pull origin master
git checkout -b feature/s3-backend
deploy
디렉토리 내에 s3.tf 파일을 생성한다.
버킷이름과 AWS 리전을 담은 변수를 컨테이너에 전달해야 한다.
{"name": "S3_STORAGE_BUCKET_NAME", "value": "${s3_storage_bucket_name}"},
{"name": "S3_STORAGE_BUCKET_REGION", "value": "${s3_storage_bucket_region}"},
위 두 코드를 추가한다.
s3.tf 코드는 아래와 같다.
[
{
"name": "api",
"image": "${app_image}",
"essential": true,
"memoryReservation": 256,
"environment": [
{"name": "DJANGO_SECRET_KEY", "value": "${django_secret_key}"},
{"name": "DB_HOST", "value": "${db_host}"},
{"name": "DB_NAME", "value": "${db_name}"},
{"name": "DB_USER", "value": "${db_user}"},
{"name": "DB_PASS", "value": "${db_pass}"},
{"name": "ALLOWED_HOSTS", "value": "${allowed_hosts}"},
{"name": "S3_STORAGE_BUCKET_NAME", "value": "${s3_storage_bucket_name}"},
{"name": "S3_STORAGE_BUCKET_REGION", "value": "${s3_storage_bucket_region}"},
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${log_group_name}",
"awslogs-region": "${log_group_region}",
"awslogs-stream-prefix": "api"
}
},
"portMappings": [
{
"containerPort": 9000,
"hostPort": 9000
}
],
"mountPoints": [
{
"readOnly": false,
"containerPath": "/vol/web",
"sourceVolume": "static"
}
]
},
{
"name": "proxy",
"image": "${proxy_image}",
"essential": true,
"portMappings": [
{
"containerPort": 8000,
"hostPort": 8000
}
],
"memoryReservation": 256,
"environment": [
{"name": "APP_HOST", "value": "127.0.0.1"},
{"name": "APP_PORT", "value": "9000"},
{"name": "LISTEN_PORT", "value": "8000"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${log_group_name}",
"awslogs-region": "${log_group_region}",
"awslogs-stream-prefix": "proxy"
}
},
"mountPoints": [
{
"readOnly": true,
"containerPath": "/vol/static",
"sourceVolume": "static"
}
]
}
]
아래 두 코드를 추가한다.
s3_storage_bucket_name = aws_s3_bucket.app_public_files.bucket
s3_storage_bucket_region = data.aws_region.current.name
resource "aws_ecs_cluster" "main" {
name = "${local.prefix}-cluster"
tags = local.common_tags
}
resource "aws_iam_policy" "task_execution_role_policy" {
name = "${local.prefix}-task-exec-role-policy"
path = "/"
description = "Allow retrieving of images and adding logs"
policy = file("./templates/ecs/task-exec-role.json")
}
resource "aws_iam_role" "task_execution_role" {
name = "${local.prefix}-task-exec-role"
assume_role_policy = file("./templates/ecs/assume-role-policy.json")
tags = local.common_tags
}
resource "aws_iam_role_policy_attachment" "task_execution_role" {
role = aws_iam_role.task_execution_role.name
policy_arn = aws_iam_policy.task_execution_role_policy.arn
}
resource "aws_iam_role" "app_iam_role" {
name = "${local.prefix}-api-task"
assume_role_policy = file("./templates/ecs/assume-role-policy.json")
tags = local.common_tags
}
resource "aws_cloudwatch_log_group" "ecs_task_logs" {
name = "${local.prefix}-api"
tags = local.common_tags
}
data "template_file" "api_container_definitions" {
template = file("./templates/ecs/container-definitions.json.tpl")
vars = {
app_image = var.ecr_image_api
proxy_image = var.ecr_image_proxy
django_secret_key = var.django_secret_key
db_host = aws_db_instance.main.address
db_name = aws_db_instance.main.name
db_user = aws_db_instance.main.username
db_pass = aws_db_instance.main.password
log_group_name = aws_cloudwatch_log_group.ecs_task_logs.name
log_group_region = data.aws_region.current.name
allowed_hosts = aws_lb.api.dns_name
s3_storage_bucket_name = aws_s3_bucket.app_public_files.bucket
s3_storage_bucket_region = data.aws_region.current.name
}
}
resource "aws_ecs_task_definition" "api" {
family = "${local.prefix}-api"
container_definitions = data.template_file.api_container_definitions.rendered
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 256
memory = 512
execution_role_arn = aws_iam_role.task_execution_role.arn
task_role_arn = aws_iam_role.app_iam_role.arn
volume {
name = "static"
}
tags = local.common_tags
}
resource "aws_security_group" "ecs_service" {
description = "Access for the ECS Service"
name = "${local.prefix}-ecs-service"
vpc_id = aws_vpc.main.id
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = [
aws_subnet.private_a.cidr_block,
aws_subnet.private_b.cidr_block
]
}
ingress {
from_port = 8000
to_port = 8000
protocol = "tcp"
security_groups = [
aws_security_group.lb.id
]
}
tags = local.common_tags
}
resource "aws_ecs_service" "api" {
name = "${local.prefix}-api"
cluster = aws_ecs_cluster.main.name
task_definition = aws_ecs_task_definition.api.family
desired_count = 1
launch_type = "FARGATE"
network_configuration {
subnets = [
aws_subnet.private_a.id,
aws_subnet.private_b.id,
]
security_groups = [aws_security_group.ecs_service.id]
}
load_balancer {
target_group_arn = aws_lb_target_group.api.arn
container_name = "proxy"
container_port = 8000
}
}