Skip to content

Commit

Permalink
JASPER-127/174: Setup ECS Services and Integrate Public Load Balancer (
Browse files Browse the repository at this point in the history
…#58)

* - Reference public load
- Added rules to redirect traffic to target group
- Provision rds db

* Added subnet group name

* Added kms_key_id and db ca cert

* Use kms key ARN instead of ID

* Removed hypens in db names

* Added db identifier to make it easier to reference the db

* Comment interceptor

* - Use provisioned security groups
- Update ECS to use existing SGs
- Removed rolesanywhere code
- Update Target Groups to have Web and API
- Update Load Balancer Listeners

* - Add checking if image in ECR already exists
- Resolved tfsec errors
- Prevent overwriting ECS TD when deploying infra code

* Added shell: bash

* Fixed ECR repo url

* Use repo name instead of repo uri

* Fixed if condition syntax

* Changed image_tag format

* Changed backup retention to 7 days

---------

Co-authored-by: Ronaldo Macapobre <[email protected]>
  • Loading branch information
ronaldo-macapobre and Ronaldo Macapobre authored Oct 28, 2024
1 parent 648b69e commit b314dd0
Show file tree
Hide file tree
Showing 20 changed files with 536 additions and 325 deletions.
20 changes: 19 additions & 1 deletion .github/workflows/actions/deploy-to-aws/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,25 @@ runs:
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v2

- name: Pull Docker image from GHCR
- name: Check ECR Image exists
id: ecr-check
shell: bash
run: |
IMAGE_TAG=${{ inputs.image_name }}-${{ inputs.short_sha}}
REPOSITORY_NAME=${{ inputs.app_name }}-ecr-repo-${{ inputs.environment }}
IMAGE_EXISTS=$(aws ecr describe-images --repository-name $REPOSITORY_NAME --query "imageDetails[?contains(imageTags, '$IMAGE_TAG')]" --output text)
if [ -z "$IMAGE_EXISTS" ]; then
echo "Image with tag $IMAGE_TAG does not exist."
echo "exists=false" >> $GITHUB_OUTPUT
else
echo "Image with tag $IMAGE_TAG already exists."
echo "exists=true" >> $GITHUB_OUTPUT
fi
- name: Push if Docker image does not exist
if: steps.ecr-check.outputs.exists == 'false'
shell: bash
run: |
docker pull ${{ inputs.github_image_repo }}/${{ inputs.image_name }}:${{ inputs.short_sha}}
Expand Down
3 changes: 3 additions & 0 deletions infrastructure/cloud/environments/dev/dev.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ app_subnet_names = ["App_Dev_aza_net", "App_Dev_azb_net"]
data_subnet_names = ["Data_Dev_aza_net", "Data_Dev_azb_net"]
openshift_iam_user = "openshiftuserdev"
iam_user_table_name = "BCGOV_IAM_USER_TABLE"
lb_name = "default"
rds_db_ca_cert = "rds-ca-rsa2048-g1"
cert_domain_name = "*.example.ca"
16 changes: 16 additions & 0 deletions infrastructure/cloud/environments/dev/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,19 @@ variable "iam_user_table_name" {
description = "The BCGOV DynamoDb IAM user table"
type = string
}

variable "lb_name" {
description = "The BCGOV provisioned Load Balancer name"
type = string
}

variable "rds_db_ca_cert" {
description = "The Certifiate Authority identifier used in RDS"
type = string
}

variable "cert_domain_name" {
description = "The BCGov provisioned certificate domain name"
type = string
}

37 changes: 24 additions & 13 deletions infrastructure/cloud/environments/dev/webapp.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module "security" {
ecr_repository_arn = module.container.ecr_repository_arn
openshift_iam_user = var.openshift_iam_user
iam_user_table_name = var.iam_user_table_name
cert_domain_name = var.cert_domain_name
}

module "storage" {
Expand All @@ -16,18 +17,26 @@ module "storage" {
app_name = var.app_name
kms_key_name = module.security.kms_key_alias
test_s3_bucket_name = var.test_s3_bucket_name
data_sg_id = module.networking.data_sg_id
db_username = module.security.db_username
db_password = module.security.db_password
vpc_id = var.vpc_id
kms_key_arn = module.security.kms_key_arn
rds_db_ca_cert = var.rds_db_ca_cert
depends_on = [module.security]
}

module "networking" {
source = "../../modules/networking"
environment = var.environment
app_name = var.app_name
region = var.region
vpc_id = var.vpc_id
web_subnet_names = var.web_subnet_names
app_subnet_names = var.app_subnet_names
data_subnet_names = var.data_subnet_names
source = "../../modules/networking"
environment = var.environment
app_name = var.app_name
region = var.region
vpc_id = var.vpc_id
web_subnet_names = var.web_subnet_names
app_subnet_names = var.app_subnet_names
data_subnet_names = var.data_subnet_names
lb_name = var.lb_name
default_lb_cert_arn = module.security.default_lb_cert_arn
}

module "container" {
Expand All @@ -36,16 +45,18 @@ module "container" {
app_name = var.app_name
region = var.region
ecs_execution_role_arn = module.security.ecs_execution_role_arn
subnet_ids = module.networking.web_subnets_ids
ecs_sg_id = module.networking.ecs_sg_id
lb_tg_arn = module.networking.lb_tg_arn
web_subnet_ids = module.networking.web_subnets_ids
app_subnet_ids = module.networking.app_subnets_ids
web_sg_id = module.networking.web_sg_id
app_sg_id = module.networking.app_sg_id
web_tg_arn = module.networking.web_tg_arn
api_tg_arn = module.networking.api_tg_arn
ecs_web_td_log_group_name = module.monitoring.ecs_web_td_log_group_name
ecs_api_td_log_group_name = module.monitoring.ecs_api_td_log_group_name
kms_key_id = module.security.kms_key_id
lb_dns_name = module.networking.lb_dns_name
default_lb_dns_name = module.networking.default_lb_dns_name
api_secrets = module.security.api_secrets
web_secrets = module.security.web_secrets
db_secrets = module.security.db_secrets
depends_on = [module.monitoring]
}

Expand Down
51 changes: 37 additions & 14 deletions infrastructure/cloud/modules/container/ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,22 @@ resource "aws_ecs_task_definition" "ecs_web_task_definition" {
cpu = 256
memory = 512
execution_role_arn = var.ecs_execution_role_arn
task_role_arn = var.ecs_execution_role_arn

lifecycle {
ignore_changes = [container_definitions]
}

container_definitions = jsonencode([
{
name = "${var.app_name}-web-container-${var.environment}"
image = "${aws_ecr_repository.ecr_repository.repository_url}:web"
image = "${aws_ecr_repository.ecr_repository.repository_url}:jasper-web"
essential = true
portMappings = [
{
containerPort = 8080
hostPort = 8080
protocol = "tcp"
}
]
logConfiguration = {
Expand All @@ -49,23 +56,28 @@ resource "aws_ecs_task_definition" "ecs_web_task_definition" {
}

resource "aws_ecs_service" "ecs_web_service" {
name = "${var.app_name}-ecs-web-service-${var.environment}"
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.ecs_web_task_definition.arn
launch_type = "FARGATE"
desired_count = 1
name = "${var.app_name}-ecs-web-service-${var.environment}"
cluster = aws_ecs_cluster.ecs_cluster.id
task_definition = aws_ecs_task_definition.ecs_web_task_definition.arn
launch_type = "FARGATE"
desired_count = 1
enable_execute_command = true

network_configuration {
subnets = var.subnet_ids
security_groups = [var.ecs_sg_id]
subnets = var.web_subnet_ids
security_groups = [var.app_sg_id]
assign_public_ip = true
}

load_balancer {
target_group_arn = var.lb_tg_arn
target_group_arn = var.web_tg_arn
container_name = "${var.app_name}-web-container-${var.environment}"
container_port = 8080
}

lifecycle {
prevent_destroy = true
}
}

# API
Expand All @@ -76,21 +88,28 @@ resource "aws_ecs_task_definition" "ecs_api_task_definition" {
cpu = 256
memory = 512
execution_role_arn = var.ecs_execution_role_arn
task_role_arn = var.ecs_execution_role_arn

lifecycle {
ignore_changes = [container_definitions]
}

container_definitions = jsonencode([
{
name = "${var.app_name}-api-container-${var.environment}"
image = "${aws_ecr_repository.ecr_repository.repository_url}:api"
image = "${aws_ecr_repository.ecr_repository.repository_url}:jasper-api"
essential = true
portMappings = [
{
containerPort = 5000
hostPort = 5000
protocol = "tcp"
}
]
environment = [
{
name = "CORS_DOMAIN"
value = var.lb_dns_name
value = var.default_lb_dns_name
}
]
secrets = [
Expand Down Expand Up @@ -119,14 +138,18 @@ resource "aws_ecs_service" "ecs_api_service" {
desired_count = 1

network_configuration {
subnets = var.subnet_ids
security_groups = [var.ecs_sg_id]
subnets = var.app_subnet_ids
security_groups = [var.app_sg_id]
assign_public_ip = true
}

load_balancer {
target_group_arn = var.lb_tg_arn
target_group_arn = var.api_tg_arn
container_name = "${var.app_name}-api-container-${var.environment}"
container_port = 5000
}

lifecycle {
prevent_destroy = true
}
}
36 changes: 23 additions & 13 deletions infrastructure/cloud/modules/container/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,33 @@ variable "ecs_execution_role_arn" {
type = string
}

variable "subnet_ids" {
description = "Subnet IDs in which ECS will deploy the tasks"
variable "web_subnet_ids" {
description = "The Web Subnet IDs"
type = list(string)
}

variable "ecs_sg_id" {
description = "Load Balancer Security Group ID"
variable "app_subnet_ids" {
description = "The App Subnet IDs"
type = list(string)
}

variable "web_sg_id" {
description = "The BCGOV provisioned Web Security Group"
type = string
}

variable "app_sg_id" {
description = "The BCGOV provisioned App Security Group"
type = string
}

variable "lb_tg_arn" {
description = "Load Balancer Target Group ARN"
variable "web_tg_arn" {
description = "The Web Target Group ARN"
type = string
}

variable "api_tg_arn" {
description = "The API Target Group ARN"
type = string
}

Expand All @@ -48,8 +63,8 @@ variable "kms_key_id" {
type = string
}

variable "lb_dns_name" {
description = "Load Balancer DNS Name"
variable "default_lb_dns_name" {
description = "The BCGov Load Balancer DNS Name"
type = string
}

Expand All @@ -62,8 +77,3 @@ variable "web_secrets" {
description = "List if env variable secrets used in Web"
type = list(list(string))
}

variable "db_secrets" {
description = "List if env variable secrets used in Database"
type = list(list(string))
}
Loading

0 comments on commit b314dd0

Please sign in to comment.