Reputation: 677
I know this question has been asked before, and I've seen several of the SO responses and read the AWS docs on the subject... I have a terraform module that, in part, builds out an ECS service, cluster, task, and Fargate container:
###############################################################################
#### EFS for added stoage
#### TODO: remove in favor of larger ephmemeral storage when terraform supports it
###############################################################################
resource "aws_efs_file_system" "test" {
creation_token = var.fargate_container_name
tags = {
Name = "test"
}
}
resource "aws_efs_access_point" "test" {
file_system_id = aws_efs_file_system.test.id
root_directory {
path = "/"
}
}
resource "aws_efs_mount_target" "test" {
count = 3
file_system_id = aws_efs_file_system.test.id
subnet_id = local.directory_subnet_ids[count.index]
security_groups = [aws_security_group.test_ecs.id]
}
###############################################################################
#### ECS Task and Service
###############################################################################
resource "aws_ecs_task_definition" "test" {
family = "test"
requires_compatibilities = ["FARGATE"]
cpu = var.test_cpu_limit
memory = var.test_memory_limit
container_definitions = <<JSON
[
{
"name": "test",
"image": "${var.test_image_registry_repo_and_image_name}",
"memory": ${var.test_memory_limit},
"cpu": ${var.test_cpu_limit},
"essential": true,
"portMappings": [
{
"containerPort": 7001,
"hostPort": 7001,
"protocol": "tcp"
},
{
"containerPort": 7002,
"hostPort": 7002,
"protocol": "tcp"
},
{
"containerPort": 9001,
"hostPort": 9001,
"protocol": "tcp"
},
{
"containerPort": 9002,
"hostPort": 9002,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${aws_cloudwatch_log_group.test_ecs.name}",
"awslogs-region": "${data.aws_region.main.name}",
"awslogs-stream-prefix": "ecs"
}
},
"linuxParameters": {
"initProcessEnabled": true
},
"mountPoints": [
{
"containerPath": "/",
"sourceVolume": "${var.fargate_container_name}"
}
]
}
]
JSON
volume {
name = var.fargate_container_name
efs_volume_configuration {
file_system_id = aws_efs_file_system.test.id
transit_encryption = "ENABLED"
transit_encryption_port = 2049
authorization_config {
access_point_id = aws_efs_access_point.test.id
iam = "ENABLED"
}
}
}
network_mode = "awsvpc"
# The role used by ECS to pull images and the like.
execution_role_arn = aws_iam_role.test_ecs_execution.arn
task_role_arn = aws_iam_role.test_task_ecs.arn
tags = merge(
local.tags, {
"Name" = "test"
}
)
}
resource "aws_ecs_service" "test" {
name = "test"
cluster = aws_ecs_cluster.test.id
task_definition = aws_ecs_task_definition.test.arn
desired_count = var.test_desired_count
enable_execute_command = true
platform_version = "1.4.0"
# service_registries {
# registry_arn = aws_service_discovery_service.test.arn
# container_name = "test"
# }
capacity_provider_strategy {
base = var.fargate_capacity_provider_base_value
capacity_provider = "FARGATE"
weight = var.fargate_capacity_provider_weight_value
}
capacity_provider_strategy {
base = var.fargate_spot_capacity_provider_base_value
capacity_provider = "FARGATE_SPOT"
weight = var.fargate_spot_capacity_provider_weight_value
}
network_configuration {
security_groups = [aws_security_group.test_ecs.id]
subnets = local.directory_subnet_ids
}
tags = merge(
local.tags, {
"Name" = "test"
}
)
}
resource "aws_security_group" "test_ecs" {
name_prefix = "test-ecs"
description = "Allow strict inbound access to ECS Tasks"
vpc_id = data.aws_vpc.primary.id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = [data.aws_vpc.primary.cidr_block]
}
ingress {
from_port = 7001
to_port = 7002
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 9001
to_port = 9002
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(
local.tags, {
"Name" = "test-ecs"
}
)
}
resource "aws_iam_role" "test_task_ecs" {
name = "EST"
description = "Test."
permissions_boundary = data.aws_iam_policy.role_permissions_boundary.arn
assume_role_policy = <<POLICY
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
I've explicitly set the Fargate version in the service, I saw some other SO user answered stating that the VPC needed to have DNS hostnames and resolution set to true -- they are. I'm still getting the error:
container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:71: creating device nodes caused: errno 524
It seems to be connected to "mountPoints" block in the container definition, as removing it will at least start the container, but it will not mount the EFS volume.
EDIT: Added ECS Task role
EDIT 2: Adding role permissions boundary:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "UseServices",
"Effect": "Allow",
"Action": [
"organizations:DescribeOrganization",
"cloudshell:*",
"compute-optimizer:*",
"amplify:*",
"appmesh:*",
"appmesh-preview:*",
"appconfig:*",
"appflow:*",
"clouddirectory:*",
"datapipeline:*",
"dms:*",
"dbqms:*",
"devicefarm:*",
"devops-guru:*",
"ds:*",
"autoscaling:*",
"imagebuilder:*",
"ec2-instance-connect:*",
"ecr-public:*",
"forecast:*",
"honeycode:*",
"proton:*",
"rds-db:*",
"rds-data:*",
"access-analyzer:*",
"ce:*",
"cur:*",
"health:*",
"pricing:*",
"ram:Get*",
"ram:List*",
"servicequotas:*",
"ssm:*",
"ssmmessages:*",
"support:*",
"tag:*",
"cloudfront:*",
"elasticloadbalancing:*",
"ecs:*",
"ecr:*",
"cloudwatch:*",
"synthetics:*",
"servicequotas:*",
"apigateway:*",
"rds:*",
"secretsmanager:*",
"route53:*",
"acm:*",
"resource-groups:*",
"servicediscovery:*",
"application-autoscaling:*",
"ec2messages:*",
"trustedadvisor:*",
"cloud9:*",
"codeartifact:*",
"codebuild:*",
"codecommit:*",
"codedeploy:*",
"codepipeline:*",
"codestar:*",
"codestar-connections:*",
"codestar-notifications:*",
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"dynamodb:*",
"eks:*",
"emr-containers:*",
"elasticache:*",
"elasticbeanstalk:*",
"elasticfilesystem:*",
"firehose:*",
"kafka:*",
"kinesis:*",
"kinesisanalytics:*",
"serverlessrepo:*",
"sqs:*",
"xray:*",
"workspaces:*",
"wam:*",
"appsync:*",
"athena:*",
"batch:*",
"states:*",
"backup:*",
"backup-storage:*",
"es:*",
"glue:*",
"databrew:*",
"lightsail:*",
"timestream:*",
"schemas:*",
"ec2:*",
"sts:AssumeRole",
"sts:TagSession",
"cloudformation:*",
"lambda:*",
"s3:*",
"sns:*",
"events:*",
"kms:*",
"logs:*",
"cloudtrail:*",
"iam:ListAccountAliases"
],
"Resource": "*"
},
{
"Sid": "AllowServiceLinkedRole",
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:GetServiceLinkedRoleDeletionStatus",
"iam:UpdateRole"
],
"Resource": [
"arn:aws:iam::*:role/aws-service-role/*"
]
},
{
"Sid": "AllowPolicy",
"Effect": "Allow",
"Action": [
"iam:GetPolicy",
"iam:DeletePolicy",
"iam:CreatePolicy",
"iam:GetPolicyVersion",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion",
"iam:ListPolicyVersions"
],
"Resource": [
"arn:aws:iam::*:policy/*"
]
},
{
"Sid": "AllowReadRole",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:DeleteRole",
"iam:TagRole",
"iam:UpdateRoleDescription",
"iam:ListInstanceProfilesForRole",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:UpdateAssumeRolePolicy",
"iam:PassRole",
"iam:GetRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/*"
]
},
{
"Sid": "AllowWriteRole",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:DeleteRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:PutRolePolicy",
"iam:UpdateRole",
"iam:PassRole"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::835718480179:policy/CuriPipelineAdministratorAccessPermBoundaries"
}
}
},
{
"Sid": "AllowWriteInstanceProfile",
"Effect": "Allow",
"Action": [
"iam:AddRoleToInstanceProfile",
"iam:CreateInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:GetInstanceProfile",
"iam:ListInstanceProfiles",
"iam:RemoveRoleFromInstanceProfile"
],
"Resource": [
"arn:aws:iam::*:instance-profile/*"
]
},
{
"Sid": "DenyIamActions",
"Effect": "Deny",
"Action": [
"iam:*OpenIDConnect*",
"iam:*SAMLProvider*",
"iam:*User*",
"iam:*Group*",
"iam:*AccessKey*",
"iam:*Password*",
"iam:CreateAccountAliases",
"iam:DeleteAccountAliases",
"iam:*LoginProfile*",
"iam:*ServiceSpecificCredential*",
"iam:*MFADevice*",
"iam:*CredentialReport*",
"iam:*OrganizationsAccessReport*",
"iam:*SecurityTokenServicePreferences*",
"iam:GetAccountAuthorizationDetails",
"iam:GetAccountSummary"
],
"Resource": "*"
},
{
"Sid": "NoBoundaryPolicyEdit",
"Effect": "Deny",
"Action": [
"iam:CreatePolicyVersion",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": [
"arn:aws:iam::835718480179:policy/CuriPipelineAdministratorAccessPermBoundaries"
]
},
{
"Sid": "NoSelfRoleEdit",
"Effect": "Deny",
"Action": [
"iam:Add*",
"iam:Attach*",
"iam:Change*",
"iam:Create*",
"iam:Delete*",
"iam:Deactivate*",
"iam:Detach*",
"iam:Enable*",
"iam:Update*",
"iam:Put*",
"iam:Remove*",
"iam:Reset*",
"iam:Tag*",
"iam:Untag*"
],
"Resource": [
"arn:aws:iam::835718480179:role/CuriPipelineAdministratorAccess"
]
}
]
}
Upvotes: 3
Views: 2308
Reputation: 677
The whole problem had nothing to do with AWS, but the server I am running (weblogic) failed to start because I was trying to mount EFS in /, which cannot be done as it would overlay many critical startup and credential files. If I had the whole filesystem already on EFS (which I did not, I used a blank filesystem), then this likely would have been fine. I mounted it successfully to a lower subdirectory and the container spun up and is running.
Upvotes: 7