diff --git a/examples/fargate-cluster/data.tf b/examples/fargate-cluster/data.tf index 86a3d62..a7c91cb 100644 --- a/examples/fargate-cluster/data.tf +++ b/examples/fargate-cluster/data.tf @@ -1,18 +1,18 @@ data "aws_vpc" "ecs_vpc" { filter { name = "tag:Name" - values = [ var.ecs_vpc_filter ] + values = [var.ecs_vpc_filter] } } data "aws_subnets" "container_subnets" { filter { name = "vpc-id" - values = [ data.aws_vpc.ecs_vpc.id ] + values = [data.aws_vpc.ecs_vpc.id] } filter { name = "tag:Name" - values = [ var.ecs_container_subnet_filter ] + values = [var.ecs_container_subnet_filter] } } diff --git a/examples/fargate-cluster/roles.tf b/examples/fargate-cluster/roles.tf new file mode 100644 index 0000000..4e5529f --- /dev/null +++ b/examples/fargate-cluster/roles.tf @@ -0,0 +1,136 @@ +#--- +# roles will be vpc and region specific +# task execution role +#--- +locals { + vpc_id = data.aws_vpc.ecs_vpc.id + vpc_short_name = var.vpc_short_name + vpc_endpoints = ["ecr_api", "ecr_dkr", "ecs", "logs", "secretsmanager", "ssm", ] + + task_base_format = "%v-ecs-task-execution-%v-%v" + task_base_name = format(local.task_base_format, var.app_program, var.vpc_short_name, local.region) + task_policy_name = format("p-%v", local.task_base_name) +} + +data "aws_vpc_endpoint" "vpc_endpoints" { + for_each = toset(local.vpc_endpoints) + service_name = each.key +} + +# note you have to create the policy before creating the role module +# tf-apply -target=aws_iam_policy.ecr_policy +# tf-apply +module "ecs_task_role" { + source = "git@github.e.it.census.gov:terraform-modules/aws-iam-role.git" + + role_name = local.task_base_name + role_description = format("Role for ECS for %v-%v task execution", var.app_program, var.app_environment) + attached_policies = [aws_iam_policy.ecr_task_policy.arn] + assume_policy_document = data.aws_iam_policy_document.ecs_task_assume.json + enable_instance_profile = false + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + { "Name" = local.task_base_name }, + ) +} + +resource "aws_iam_policy" "ecr_task_policy" { + name = local.task_policy_name + description = format("Policy for ECS for %v-%v task execution", var.app_program, var.app_environment) + path = "/" + policy = data.aws_iam_policy_document.ecr_task_policy.json +} + +data "aws_iam_policy_document" "ecs_task_assume" { + statement { + sid = "ECSTaskExecution" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ecs-tasks.amazonaws.com"] + } + } +} + +data "aws_iam_policy_document" "ecr_task_policy" { + statement { + sid = "ECRTokenAndLogs" + effect = "Allow" + actions = [ + "ecr:GetAuthorizationToken", + "logs:CreateLogStream", + "logs:PutLogEvents", + ] + # narrow this maybe? + resources = ["*"] + } + statement { + sid = "ECRImages" + effect = "Allow" + actions = [ + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + ] + resources = ["*"] + condition { + test = "StringEquals" + variable = "aws:sourceVpce" + values = [for k, v in data.aws_vpc_endpoint : v.id] + } + condition { + test = "StringEquals" + variable = "aws:sourceVpc" + values = [data.aws_vpc.ecs_vpc.id] + } + } +} + +## task role +## +## task execution role +## https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html +## AmazonECSTaskExecutionRolePolicy +## other policies as needed +## +## https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html#task-execution-private-auth +## https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_execution_IAM_role.html#task-execution-secrets + +#--- +# roles will be vpc and region specific +# task execution role +#--- +locals { + instance_base_format = "%v-ecs-instance-%v-%v" + instance_base_name = format(local.instance_base_format, var.app_name, var.vpc_short_name, local.region) + instance_managed_policies = [ + "AmazonEC2ContainerServiceforEC2Role", + ] +} + +data "aws_iam_policy" "instance_managed_policies" { + for_each = toset(local.instance_managed_policies) + name = each.key +} + +module "ecs_instance_role" { + source = "git@github.e.it.census.gov:terraform-modules/aws-iam-role.git" + + role_name = local.instance_base_name + role_description = format("Role for ECS for %v-%v instance", var.app_program, var.app_environment) + attached_policies = [for k, p in data.aws_iam_policy.instance_managed_policies : p.arn] + assume_policy_document = data.terraform_remote_state.common.outputs.custom_policy_documents["ec2_assume"].policy + enable_instance_profile = true + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + { "Name" = local.instance_base_name }, + ) +} diff --git a/examples/fargate-cluster/variables.ecs.auto.tfvars b/examples/fargate-cluster/variables.ecs.auto.tfvars index 6491a90..40a05ac 100644 --- a/examples/fargate-cluster/variables.ecs.auto.tfvars +++ b/examples/fargate-cluster/variables.ecs.auto.tfvars @@ -1,3 +1,5 @@ -cluster_name = null -ecs_vpc_filter = "vpcN-*" +cluster_name = null +ecs_vpc_filter = "vpcN-*" ecs_container_subnet_filter = "*-container-*" +app_name = null +app_environment = null diff --git a/examples/fargate-cluster/variables.ecs.tf b/examples/fargate-cluster/variables.ecs.tf index 49005b9..1db2f9a 100644 --- a/examples/fargate-cluster/variables.ecs.tf +++ b/examples/fargate-cluster/variables.ecs.tf @@ -1,6 +1,6 @@ variable "cluster_name" { description = "Cluster name of form {program}-{env}-fargate or {org}-{project}-{env}-fargate" - type = string + type = string } # examples: dice-qa-fargate @@ -8,11 +8,20 @@ variable "cluster_name" { variable "ecs_vpc_filter" { description = "VPC filter (ex.,, vpc4-*) for selecting the correct VPC for this cluster" - type = string + type = string } variable "ecs_container_subnet_filter" { description = "Container subnet filter (ex., *-container-*) to use to select the container subents in this VPC" - type = string + type = string } +variable "app_name" { + description = "Application name for prefix in role and other resources. Either {org}-{project} or {program}" + type = string +} + +variable "app_environment" { + description = "Application environment (dev, test, ite, qa, stage, prod)" + type = string +}