Skip to content

Commit

Permalink
feat: persistent volumes
Browse files Browse the repository at this point in the history
- Create IAM Role for ECS Task Role and ECS Execution Role (same role)
- Encrypt EFS Volume with key that is managed here
- Add EFS File Policy to ensure data transit is encrypted
- Optimize security groups for NFS communication from ECS to EFS
- Enable Cloudwatch Logging from ECS Cluster and ECS Solr Task Definition
  • Loading branch information
nickumia-reisys committed May 17, 2022
1 parent 623ff0f commit d71744e
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 42 deletions.
79 changes: 49 additions & 30 deletions terraform/provision/ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ data "aws_caller_identity" "current" {}

resource "aws_ecs_cluster" "solr-cluster" {
name = "solr-cluster"

setting {
name = "containerInsights"
value = "enabled"
}

configuration {
execute_command_configuration {
kms_key_id = aws_kms_key.ecs-log-key.arn
logging = "OVERRIDE"

log_configuration {
cloud_watch_encryption_enabled = true
cloud_watch_log_group_name = aws_cloudwatch_log_group.ecs-logs.name
}
}
}
}

resource "aws_ecs_cluster_capacity_providers" "fargate" {
Expand All @@ -18,51 +35,58 @@ resource "aws_ecs_cluster_capacity_providers" "fargate" {
}

resource "aws_ecs_task_definition" "solr" {
family = "service"
family = "solr-service"
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = 2048
memory = 14336
task_role_arn = "${aws_iam_role.solr-task-execution.arn}"
execution_role_arn = "${aws_iam_role.solr-task-execution.arn}"
container_definitions = jsonencode([
{
name = "solr"
image = "solr:8.11"
cpu = 2048
memory = 14336
essential = true
# command = ["wget -o start.sh", "https://gist.githubusercontent.com/FuhuXia/91cac09b23ef29e5f219ba83df8b808e/raw/76de04dd7edf0faef2c04d8a8bbd51ee2cef237f/solr-setup-for-catalog.sh", "&&", "./start.sh"]
portMappings = [
{
containerPort = 8983
hostPort = 8983
}
]
# mountPoints = [
# {
# containerPath = "/var/solr/data",
# sourceVolume = "solr-data"
# }
# ]
logConfiguration = {
logDriver = "awslogs",
options = {
awslogs-group = aws_cloudwatch_log_group.ecs-logs.name,
awslogs-region = "us-west-2",
awslogs-stream-prefix = "application"
}
}
mountPoints = [
{
containerPath = "/var/solr/data",
sourceVolume = "solr-data",
readOnly = false
}
]
},
])

# volume {
# name = "solr-data"
# efs_volume_configuration {
# file_system_id = aws_efs_file_system.solr-data.id
# root_directory = "/"
# # transit_encryption = "ENABLED"
# # transit_encryption_port = 2999
# # authorization_config {
# # access_point_id = aws_efs_access_point.solr-data-access.id
# # iam = "ENABLED"
# # }
# }
# }

# placement_constraints {
# type = "memberOf"
# expression = "attribute:ecs.availability-zone in [us-west-2a]"
# }
volume {
name = "solr-data"
efs_volume_configuration {
file_system_id = aws_efs_file_system.solr-data.id
root_directory = "/"
transit_encryption = "ENABLED"
transit_encryption_port = 2049
authorization_config {
access_point_id = aws_efs_access_point.solr-data-ap.id
iam = "ENABLED"
}
}
}
}

resource "aws_ecs_service" "solr" {
Expand All @@ -77,9 +101,4 @@ resource "aws_ecs_service" "solr" {
subnets = module.vpc.public_subnets
assign_public_ip = true
}

# placement_constraints {
# type = "memberOf"
# expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]"
# }
}
52 changes: 50 additions & 2 deletions terraform/provision/efs.tf
Original file line number Diff line number Diff line change
@@ -1,19 +1,67 @@


resource "aws_efs_file_system" "solr-data" {
creation_token = "solr-data"

# encryption-at-rest
encrypted = true
tags = {
Name = "SolrData"
}
}

resource "aws_efs_access_point" "solr-data-access" {
resource "aws_efs_access_point" "solr-data-ap" {
file_system_id = aws_efs_file_system.solr-data.id
# EFS needs to be mounted as root to be able to write-to/create files
posix_user {
gid = "0"
uid = "0"
}
}

resource "aws_efs_mount_target" "all" {
count = length(module.vpc.public_subnets)
file_system_id = aws_efs_file_system.solr-data.id
subnet_id = module.vpc.public_subnets[count.index]
}

resource "aws_efs_file_system_policy" "policy" {
file_system_id = aws_efs_file_system.solr-data.id

# encryption-in-transit
policy = <<-POLICY
{
"Version": "2012-10-17",
"Id": "efs-policy",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"elasticfilesystem:ClientRootAccess",
"elasticfilesystem:ClientWrite",
"elasticfilesystem:ClientMount"
],
"Condition": {
"Bool": {
"elasticfilesystem:AccessedViaMountTarget": "true"
}
}
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "*",
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
POLICY
}
75 changes: 66 additions & 9 deletions terraform/provision/iam.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@

resource "aws_iam_role" "solr" {
name = "solr_role"
resource "aws_iam_role" "solr-task-execution" {
name = "solr_task_role"

# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
Expand All @@ -12,7 +10,7 @@ resource "aws_iam_role" "solr" {
Effect = "Allow"
Sid = ""
Principal = {
Service = "ec2.amazonaws.com"
Service = "ecs-tasks.amazonaws.com"
}
},
]
Expand All @@ -21,17 +19,27 @@ resource "aws_iam_role" "solr" {

resource "aws_iam_policy_attachment" "solr-efs-ecs" {
name = "solr-efs-ecs-attachment"
roles = [aws_iam_role.solr.name]
roles = [aws_iam_role.solr-task-execution.name]
policy_arn = aws_iam_policy.ecs-solr-efs.arn
}

# resource "aws_iam_policy_attachment" "solr-ecs-basic" {
# name = "solr-efs-ecs-attachment"
# roles = [aws_iam_role.solr-task-execution.name]
# policy_arn = aws_iam_policy.ecs-basic.arn
# }

resource "aws_iam_policy_attachment" "solr-ecs-execution-role" {
name = "solr-ecs-execution-role-attachment"
roles = [aws_iam_role.solr-task-execution.name]
policy_arn = aws_iam_policy.ecs-tasks.arn
}

resource "aws_iam_policy" "ecs-solr-efs" {
name = "efs-policy"
path = "/"
description = "Solr EFS ECS Policy"
description = "Allow ECS to talk to EFS"

# Terraform's "jsonencode" function converts a
# Terraform expression result to valid JSON syntax.
policy = jsonencode({
Version = "2012-10-17"
Statement = [
Expand All @@ -47,3 +55,52 @@ resource "aws_iam_policy" "ecs-solr-efs" {
]
})
}

# resource "aws_iam_policy" "ecs-basic" {
# name = "ecs-basic-policy"
# path = "/"
# description = "Allow solr to run on ecs"
#
# policy = jsonencode({
# Version = "2012-10-17"
# Statement = [
# {
# Action = [
# "ec2:AttachNetworkInterface",
# "ec2:CreateNetworkInterface",
# "ec2:CreateNetworkInterfacePermission",
# "ec2:DeleteNetworkInterface",
# "ec2:DeleteNetworkInterfacePermission",
# "ec2:Describe*",
# "ec2:DetachNetworkInterface",
# ]
# Effect = "Allow"
# Resource = "*"
# },
# ]
# })
# }

resource "aws_iam_policy" "ecs-tasks" {
name = "ecs-tasks"
path = "/"
description = "Allow solr task role to run on ecs"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"ecr:*",
# "s3:*",
# "efs:*"
]
Effect = "Allow"
Resource = "*"
},
]
})
}
9 changes: 9 additions & 0 deletions terraform/provision/logging.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

resource "aws_kms_key" "ecs-log-key" {
description = "ecs log key"
deletion_window_in_days = 7
}

resource "aws_cloudwatch_log_group" "ecs-logs" {
name = "ecs-logs-solr"
}
17 changes: 16 additions & 1 deletion terraform/provision/vpc.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ data "aws_availability_zones" "available" {
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "3.11.4"
# insert the 23 required variables here
name = "eks-vpc"
cidr = "10.31.0.0/16"

Expand All @@ -30,3 +29,19 @@ module "vpc" {
# })
}

resource "aws_security_group_rule" "allow-efs" {
type = "ingress"
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = module.vpc.private_subnets_cidr_blocks
security_group_id = module.vpc.default_security_group_id
}
resource "aws_security_group_rule" "allow-efs-b" {
type = "egress"
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = module.vpc.private_subnets_cidr_blocks
security_group_id = module.vpc.default_security_group_id
}

0 comments on commit d71744e

Please sign in to comment.