Skip to content

Commit

Permalink
Merge pull request #27 from belljun3395/infra/aws
Browse files Browse the repository at this point in the history
Infra/aws
  • Loading branch information
belljun3395 authored Aug 1, 2024
2 parents f256ae9 + 9460586 commit b805cfa
Show file tree
Hide file tree
Showing 21 changed files with 1,270 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: NCP IaC
name: Terraform IAC

on:
push:
Expand Down Expand Up @@ -35,9 +35,9 @@ jobs:

- name: Terraform Plan
working-directory: ${{ env.working-directory }}
run: terraform plan -var=ncp_access_key=${{ secrets.NCP_ACCESS_KEY_ID }} -var=ncp_secret_key=${{ secrets.NCP_SECRET_ACCESS_KEY }} -input=false
run: terraform plan -var=aws_root_arn=${{ secrets.AWS_ROOT_ARN }} -var=aws_access_key=${{ secrets.AWS_ACCESS_KEY }} -var=aws_secret_key=${{ secrets.AWS_SECRET_SECRET_KEY }} -var=aws_rds_password=${{ secrets.AWS_RDS_PASSWORD }} -var=fe_origin=${{ secrets.FE_ORIGIN }} -var=email_username=${{ secrets.EMAIL_USERNAME }} -var=email_password=${{ secrets.EMAIL_PASSWORD }} -var=webhook_discord=${{ secrets.WEBHOOK_DISCORD }} -input=false

- name: Terraform Apply
working-directory: ${{ env.working-directory }}
if: github.ref == 'refs/heads/infra/main' && github.event_name == 'push'
run: terraform apply -auto-approve -var=ncp_access_key=${{ secrets.NCP_ACCESS_KEY_ID }} -var=ncp_secret_key=${{ secrets.NCP_SECRET_ACCESS_KEY }} -input=false
run: terraform apply -auto-approve -var=aws_root_arn=${{ secrets.AWS_ROOT_ARN }} -var=aws_access_key=${{ secrets.AWS_ACCESS_KEY }} -var=aws_secret_key=${{ secrets.AWS_SECRET_SECRET_KEY }} -var=aws_rds_password=${{ secrets.AWS_RDS_PASSWORD }} -var=fe_origin=${{ secrets.FE_ORIGIN }} -var=email_username=${{ secrets.EMAIL_USERNAME }} -var=email_password=${{ secrets.EMAIL_PASSWORD }} -var=webhook_discord=${{ secrets.WEBHOOK_DISCORD }} -input=false
12 changes: 12 additions & 0 deletions infra/terraform/aws/acm.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#resource "aws_acm_certificate" "cert" {
# domain_name = "*.${var.domain_name}"
# validation_method = "DNS"
#
# tags = {
# Environment = "${var.prefix}"
# }
#
# lifecycle {
# create_before_destroy = true
# }
#}
42 changes: 42 additions & 0 deletions infra/terraform/aws/asg.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Launch Configuration
resource "aws_launch_configuration" "lc" {
name_prefix = "${var.prefix}-lc-"
image_id = var.lc_image_id
instance_type = var.instance_type
iam_instance_profile = aws_iam_instance_profile.ecs_instance_profile.name
security_groups = [aws_security_group.application_sg.id]
associate_public_ip_address = true
key_name = aws_key_pair.kp.key_name
root_block_device {
volume_size = 30
volume_type = "gp2"
}
lifecycle {
create_before_destroy = true
}
user_data = <<EOF
#!/bin/bash
echo ECS_CLUSTER=${aws_ecs_cluster.ecs_cluster.name} >> /etc/ecs/ecs.config; echo ECS_BACKEND_HOST= >> /etc/ecs/ecs.config;
export PATH=/usr/local/bin:$PATH
yum -y install jq
yum install -y awscli
EOF
}

# Autoscaling Group
resource "aws_autoscaling_group" "asg" {
name = "${var.prefix}-asg"
vpc_zone_identifier = [
aws_subnet.public_a.id,
aws_subnet.public_c.id
]
launch_configuration = aws_launch_configuration.lc.name
min_size = 1
max_size = 1
tag {
key = "Name"
value = "${var.prefix}-asg"
propagate_at_launch = true
}
target_group_arns = [aws_alb_target_group.alb_target_group.arn]
}
44 changes: 44 additions & 0 deletions infra/terraform/aws/cloudfront.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
locals {
s3_domain_name = "${aws_s3_bucket.bucket.bucket}.s3.${var.region}.amazonaws.com"
}

resource "aws_cloudfront_origin_access_control" "s3_origin_access_control" {
name = "s3-origin-access-control"
description = "s3-origin-access-control"
origin_access_control_origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}

resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = local.s3_domain_name
origin_id = local.s3_domain_name
origin_access_control_id = aws_cloudfront_origin_access_control.s3_origin_access_control.id
}

enabled = true
is_ipv6_enabled = true

default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = local.s3_domain_name
cache_policy_id = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"

viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
cloudfront_default_certificate = true
}
}
10 changes: 10 additions & 0 deletions infra/terraform/aws/cloudwatch.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# KMS Key
resource "aws_kms_key" "kms_key" {
description = "${var.prefix}-kms-key"
deletion_window_in_days = 7
}

# Cloudwatch Log Group
resource "aws_cloudwatch_log_group" "cloudwatch_log_group" {
name = "${var.prefix}-cloudwatch-log-group"
}
9 changes: 9 additions & 0 deletions infra/terraform/aws/ecr.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ECR
resource "aws_ecr_repository" "ecr" {
name = "${var.prefix}-ecr"
image_tag_mutability = "MUTABLE"

image_scanning_configuration {
scan_on_push = true
}
}
255 changes: 255 additions & 0 deletions infra/terraform/aws/ecs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# ECS Cluster
resource "aws_ecs_cluster" "ecs_cluster" {
name = "${var.prefix}-ecs-cluster"
configuration {
execute_command_configuration {
kms_key_id = aws_kms_key.kms_key.id
logging = "OVERRIDE"

log_configuration {
cloud_watch_encryption_enabled = true
cloud_watch_log_group_name = aws_cloudwatch_log_group.cloudwatch_log_group.name
}

}
}
}

# Task Definition
resource "aws_ecs_task_definition" "ecs_task" {
family = "${var.prefix}-ecs-task"
network_mode = "bridge"
requires_compatibilities = ["EC2"]
task_role_arn = aws_iam_role.ecs_task_execution_role.arn
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
container_definitions = jsonencode(
[
{
"name" : "${var.prefix}-container",
"image" : "${aws_ecr_repository.ecr.repository_url}:latest",
"cpu" : 0,
"memory" : 512,
"memoryReservation" : 256,
"environment": [
{
"name": "spring.profiles.active",
"value": "prd"
}
],
"essential" : true,
"portMappings" : [
{
"containerPort" : 8080,
"hostPort" : 0,
"protocol" : "tcp"
}
],
"mountPoints" : [],
"volumesFrom" : [],
"secrets" : [
{
"name" : "TOKEN_SECRETKEY",
"valueFrom" : "${aws_ssm_parameter.token_secret_key.name}"
},
{
"name" : "ACCESS_TOKEN_VALIDTIME"
"valueFrom" : "${aws_ssm_parameter.access_token_validtime.name}"
},
{
"name" : "REFRESH_TOKEN_VALIDTIME",
"valueFrom" : "${aws_ssm_parameter.refresh_token_validtime.name}"
},
{
"name" : "CORS_PATH_PATTERNS",
"valueFrom" : "${aws_ssm_parameter.cors_path_patterns.name}"
},
{
"name" : "CORS_ORIGIN_PATTERNS",
"valueFrom" : "${aws_ssm_parameter.cors_origin_patterns.name}"
},
{
"name" : "CORS_ALLOWED_METHODS",
"valueFrom" : "${aws_ssm_parameter.cors_allowed_methods.name}"
},
{
"name" : "CORS_ALLOWED_HEADERS",
"valueFrom" : "${aws_ssm_parameter.cors_allowed_headers.name}"
},
{
"name" : "CORS_EXPOSED_HEADERS",
"valueFrom" : "${aws_ssm_parameter.cors_exposed_headers.name}"
},
{
"name" : "CORS_ALLOW_CREDENTIALS",
"valueFrom" : "${aws_ssm_parameter.cors_allow_credentials.name}"
},
{
"name" : "CORS_MAX_AGE",
"valueFrom" : "${aws_ssm_parameter.cors_max_age.name}"
},
{
"name" : "DB_HOSTNAME",
"valueFrom" : "${aws_ssm_parameter.db_hostname.name}"
},
{
"name" : "DB_USERNAME",
"valueFrom" : "${aws_ssm_parameter.db_username.name}"
},
{
"name" : "DB_PASSWORD",
"valueFrom" : "${aws_ssm_parameter.db_password.name}"
},
{
"name" : "STORAGE_URL",
"valueFrom" : "${aws_ssm_parameter.storage_url.name}"
},
{
"name" : "STORAGE_ACCESS_KEY",
"valueFrom" : "${aws_ssm_parameter.storage_access_key.name}"
},
{
"name" : "STORAGE_SECRET_KEY",
"valueFrom" : "${aws_ssm_parameter.storage_secret_key.name}"
},
{
"name" : "IMAGE_STORE_BUCKET_NAME",
"valueFrom" : "${aws_ssm_parameter.image_store_bucket_name.name}"
},
{
"name": "DOCUMENT_STORE_BUCKET_NAME",
"valueFrom": "${aws_ssm_parameter.document_store_bucket_name.name}"
},
{
"name" : "STORAGE_REGION",
"valueFrom" : "${aws_ssm_parameter.storage_region.name}"
},
{
"name" : "EMAIL_USERNAME",
"valueFrom" : "${aws_ssm_parameter.email_username.name}"
},
{
"name" : "EMAIL_PASSWORD",
"valueFrom" : "${aws_ssm_parameter.email_password.name}"
},
{
"name" : "TIMEOUT_CONNECT",
"valueFrom" : "${aws_ssm_parameter.timeout_connect.name}"
},
{
"name" : "TIMEOUT_READ",
"valueFrom" : "${aws_ssm_parameter.timeout_read.name}"
},
{
"name": "WEBHOOK_DISCORD",
"valueFrom": "${aws_ssm_parameter.webhook_discord.name}"
},
{
"name" : "DISCORD_THREAD_POOL_CORE_POOL_SIZE",
"valueFrom" : "${aws_ssm_parameter.discord_thread_pool_core_pool_size.name}"
},
{
"name": "DISCORD_THREAD_POOL_MAX_POOL_SIZE",
"valueFrom": "${aws_ssm_parameter.discord_thread_pool_max_pool_size.name}"
},
{
"name": "DISCORD_THREAD_POOL_QUEUE_CAPACITY",
"valueFrom": "${aws_ssm_parameter.discord_thread_pool_queue_capacity.name}"
},
{
"name" : "DISCORD_THREAD_POOL_WAIT_FOR_TASKS_TO_COMPLETE_ON_SHUTDOWN",
"valueFrom" : "${aws_ssm_parameter.discord_thread_pool_wait_for_tasks_to_complete_on_shutdown.name}"
},
{
"name" : "DISCORD_THREAD_POOL_AWAIT_TERMINATION_SECONDS",
"valueFrom" : "${aws_ssm_parameter.discord_thread_pool_await_termination_seconds.name}"
},
{
"name": "CDN_URL",
"valueFrom": "${aws_ssm_parameter.cdn_url.name}"
}
],
"logConfiguration" : {
"logDriver" : "awslogs",
"options" : {
"awslogs-group" : "${aws_cloudwatch_log_group.cloudwatch_log_group.name}",
"awslogs-region" : "${var.region}",
"awslogs-stream-prefix" : "ecs"
}
}
}
]
)
}

# ALB
resource "aws_alb" "alb" {
name = "${var.prefix}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb_sg.id]
subnets = [aws_subnet.public_a.id, aws_subnet.public_c.id]
enable_deletion_protection = false
}

# ALB Target Group
resource "aws_alb_target_group" "alb_target_group" {
name = "${var.prefix}-alb-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.vpc.id
target_type = "instance"
health_check {
path = "/actuator/health"
protocol = "HTTP"
port = "traffic-port"
interval = 300
timeout = 120
healthy_threshold = 2
unhealthy_threshold = 2
}
}

# ALB Listener
resource "aws_alb_listener" "http_alb_listener" {
load_balancer_arn = aws_alb.alb.arn
port = 80
protocol = "HTTP"

default_action {
type = "forward"
target_group_arn = aws_alb_target_group.alb_target_group.arn
}
}

// todo: add https listener
#resource "aws_alb_listener" "https_alb_listenser" {
# load_balancer_arn = aws_alb.alb.arn
# port = 443
# protocol = "HTTPS"
# ssl_policy = "ELBSecurityPolicy-2016-08"
# certificate_arn = aws_acm_certificate.cert.arn
#
# default_action {
# type = "forward"
# target_group_arn = aws_alb_target_group.alb_target_group.arn
# }
#}

#resource "aws_lb_listener_certificate" "https_listener_cert" {
# listener_arn = aws_alb_listener.https_alb_listenser.arn
# certificate_arn = aws_acm_certificate.cert.arn
#}

# ECS Service
resource "aws_ecs_service" "ecs_service" {
name = "${var.prefix}-ecs-service"
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.ecs_task.arn
desired_count = 1
launch_type = "EC2"
load_balancer {
target_group_arn = aws_alb_target_group.alb_target_group.arn
container_name = "${var.prefix}-container"
container_port = 8080
}
}
Loading

0 comments on commit b805cfa

Please sign in to comment.