From f9683f919655c96a85b6b1481924513e64befd77 Mon Sep 17 00:00:00 2001 From: badra001 Date: Fri, 28 Oct 2022 14:04:03 -0400 Subject: [PATCH] add tf-upgrade --- examples/fargate-cluster-tf-upgrade/README.md | 38 +++++ .../cicd-deployer.tf | 154 +++++++++++++++++ .../fargate-cluster-tf-upgrade/cluster.tf | 34 ++++ examples/fargate-cluster-tf-upgrade/data.tf | 22 +++ examples/fargate-cluster-tf-upgrade/locals.tf | 9 + .../fargate-cluster-tf-upgrade/outputs.tf | 4 + .../fargate-cluster-tf-upgrade/prefixes.tf | 40 +++++ examples/fargate-cluster-tf-upgrade/region.tf | 3 + examples/fargate-cluster-tf-upgrade/roles.tf | 155 ++++++++++++++++++ .../fargate-cluster-tf-upgrade/tf-run.data | 15 ++ .../variables.cicd-deployer.tf | 12 ++ .../variables.ecs.tf | 27 +++ .../fargate-cluster-tf-upgrade/versions.tf | 13 ++ 13 files changed, 526 insertions(+) create mode 100644 examples/fargate-cluster-tf-upgrade/README.md create mode 100644 examples/fargate-cluster-tf-upgrade/cicd-deployer.tf create mode 100644 examples/fargate-cluster-tf-upgrade/cluster.tf create mode 100644 examples/fargate-cluster-tf-upgrade/data.tf create mode 100644 examples/fargate-cluster-tf-upgrade/locals.tf create mode 100644 examples/fargate-cluster-tf-upgrade/outputs.tf create mode 100644 examples/fargate-cluster-tf-upgrade/prefixes.tf create mode 100644 examples/fargate-cluster-tf-upgrade/region.tf create mode 100644 examples/fargate-cluster-tf-upgrade/roles.tf create mode 100644 examples/fargate-cluster-tf-upgrade/tf-run.data create mode 100644 examples/fargate-cluster-tf-upgrade/variables.cicd-deployer.tf create mode 100644 examples/fargate-cluster-tf-upgrade/variables.ecs.tf create mode 100644 examples/fargate-cluster-tf-upgrade/versions.tf diff --git a/examples/fargate-cluster-tf-upgrade/README.md b/examples/fargate-cluster-tf-upgrade/README.md new file mode 100644 index 0000000..596e1ac --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/README.md @@ -0,0 +1,38 @@ +# About + +This directory constructs the appropriate resources for the ECS used for DICE. + +# Application Information + +* Application: DICE +* Organization: ADSD +* Project: DICE Mojo and Centurion +* Point of Contact(s): +* Creation Date: YYYY-MM-DD +* References: + * Requirements: + * Remedy Ticket: + * Other: {url} +* Related Configurations: + * {directory-path} + +# Application Requirements + +# Terraform Directions + +* Rsync the `examples/fargate-cluster-tf-upgrade` to your new directory +* Update the file `variables.ecs.auto.tfvars` +* Replace placeholders + * {ENV} with environment name in lowercase (ite, uat, etc) + * {NUMBER} with the VPC number (4, 5, etc) associated with the specific VPC +* execute + +```script +tf-run apply +``` + +# Details + + +{{ .Content }} + diff --git a/examples/fargate-cluster-tf-upgrade/cicd-deployer.tf b/examples/fargate-cluster-tf-upgrade/cicd-deployer.tf new file mode 100644 index 0000000..bf532a7 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/cicd-deployer.tf @@ -0,0 +1,154 @@ +locals { + cicd_iam_username = format("%v%v-%v", local._prefixes["ecs-user"], var.cluster_name, var.cicd_group_name) + policy_cicd_group_name = replace(local.cicd_iam_username, local._prefixes["ecs-user"], local._prefixes["ecs-policy"]) + role_cicd_group_name = replace(local.cicd_iam_username, local._prefixes["ecs-user"], "") + cicd_group_name = local.role_cicd_group_name + iam_policies_cicd = ["p-inf-manage-access-keys"] +} + +data "aws_iam_policy" "cicd_deployer_policies" { + for_each = toset(local.iam_policies_cicd) + name = each.key +} + +module "service_cicd_deployer" { + source = "git@github.e.it.census.gov:terraform-modules/aws-iam-user.git" + + iam_username = local.cicd_iam_username + username = "" + email_address = "" + groups = ["g-inf-ip-restriction"] + generate_password = false + service_account = true + enable_sending_mail = false + create_access_keys = false + attached_policies = flatten(concat([for k, v in data.aws_iam_policy.cicd_deployer_policies : v.arn], [aws_iam_policy.cicd_deployer.arn])) + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + ) +} + +module "role_cicd_deployer" { + source = "git@github.e.it.census.gov:terraform-modules/aws-iam-role.git?ref=tf-upgrade" + + role_name = local.role_cicd_group_name + role_description = "Role for ECS cluster ${var.cluster_name} for access by ${var.cicd_group_name}" + enable_ldap_creation = false + assume_policy_document = data.aws_iam_policy_document.cicd_deployer_allow_sts.json + attached_policies = [aws_iam_policy.cicd_deployer.arn] + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + ) +} + +resource "aws_iam_policy" "cicd_deployer" { + name = local.policy_cicd_group_name + path = "/" + description = "Policy for ECS ${var.cluster_name} IAM access ${var.cicd_group_name}" + policy = data.aws_iam_policy_document.cicd_deployer.json +} + +locals { + cicd_deployer_policy_statements = { + ECRRead = { + actions = [ + "ecr:Describe*", + "ecr:Get*", + "ecr:ListImages", + "ecr:BatchGetImage", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + ] + resources = ["*"] + } + ECRWrite = { + # effect = "Deny" + actions = [ + "ecr:BatchDeleteImage", + "ecr:CompleteLayerUpload", + "ecr:CreateRepository", + "ecr:DeleteRepository", + "ecr:InitiateLayerUpload", + "ecr:PutImage", + "ecr:UploadLayerPart" + ] + not_resources = [ + format(local.common_arn, "ecr", "repository/eks/*"), + ] + } + ECSRead = { + actions = [ + "ecs:ListClusters", + ] + resources = ["*"] + } + } +} + +data "aws_iam_policy_document" "cicd_deployer" { + dynamic "statement" { + for_each = local.cicd_deployer_policy_statements + iterator = s + content { + sid = format("%v%vAccess", lookup(s.value, "effect", "Allow"), s.key) + effect = lookup(s.value, "effect", "Allow") + actions = lookup(s.value, "actions", []) + resources = lookup(s.value, "resources", []) + not_resources = lookup(s.value, "not_resources", []) + } + } +} + +# allow anyone in this account to assume the role, if they have the permission to do so +data "aws_iam_policy_document" "cicd_deployer_allow_sts" { + statement { + sid = "AllowSTSAssume" + effect = "Allow" + actions = ["sts:AssumeRole"] + principals { + type = "AWS" + identifiers = [ + format(local.iam_arn, "root"), + ] + } + } +} + +# output "service_cicd_deployer_arn" { +# description = "CICD Deployer user ARN" +# value = module.service_cicd_deployer.user_arn +# } +# +# output "service_cicd_deployer_username" { +# description = "CICD Deployer username" +# value = module.service_cicd_deployer.user_name +# } + +module "group_cicd_deployer" { + source = "git@github.e.it.census.gov:terraform-modules/aws-iam-group.git" + + group_name = local.cicd_group_name + attached_policies = flatten(concat([for k, v in data.aws_iam_policy.cicd_deployer_policies : v.arn], [aws_iam_policy.cicd_deployer.arn])) + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + ) +} + +output "info_cicd_deployer" { + description = "CID Deployer IAM details" + value = { + user_name = module.service_cicd_deployer.user_name + user_arn = module.service_cicd_deployer.user_arn + group_name = module.group_cicd_deployer.group_name + group_arn = module.group_cicd_deployer.group_arn + } +} diff --git a/examples/fargate-cluster-tf-upgrade/cluster.tf b/examples/fargate-cluster-tf-upgrade/cluster.tf new file mode 100644 index 0000000..4097d43 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/cluster.tf @@ -0,0 +1,34 @@ +resource "aws_ecs_cluster" "ecs" { + name = var.cluster_name + setting { + name = "containerInsights" + value = "enabled" + } + #capacity_providers = ["FARGATE"] + + # default_capacity_provider_strategy = { + # capacity_provider + # weight + # base + # } + + tags = merge( + local.base_tags, + local.common_tags, + var.application_tags, + { "Name" = format("ecs-%v", var.cluster_name) }, + ) +} + +resource "aws_ecs_cluster_capacity_providers" "ecs" { + cluster_name = aws_ecs_cluster.ecs.name + + capacity_providers = ["FARGATE"] + +# default_capacity_provider_strategy { +# base = 1 +# weight = 100 +# capacity_provider = "FARGATE" +# } +} + diff --git a/examples/fargate-cluster-tf-upgrade/data.tf b/examples/fargate-cluster-tf-upgrade/data.tf new file mode 100644 index 0000000..a7c91cb --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/data.tf @@ -0,0 +1,22 @@ +data "aws_vpc" "ecs_vpc" { + filter { + name = "tag:Name" + values = [var.ecs_vpc_filter] + } +} + +data "aws_subnets" "container_subnets" { + filter { + name = "vpc-id" + values = [data.aws_vpc.ecs_vpc.id] + } + filter { + name = "tag:Name" + values = [var.ecs_container_subnet_filter] + } +} + +data "aws_subnet" "container_subnets" { + for_each = toset(data.aws_subnets.container_subnets.ids) + id = each.key +} diff --git a/examples/fargate-cluster-tf-upgrade/locals.tf b/examples/fargate-cluster-tf-upgrade/locals.tf new file mode 100644 index 0000000..786f6c2 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/locals.tf @@ -0,0 +1,9 @@ +locals { + base_tags = { + "boc:created_by" = "terraform" + } + + base_arn = format("arn:%v:%%v:%v:%v:%%v:%%v", data.aws_arn.current.partition, data.aws_region.current.name, data.aws_caller_identity.current.account_id) + iam_arn = format("arn:%v:iam::%v:%%v", data.aws_arn.current.partition, data.aws_caller_identity.current.account_id) + common_arn = format("arn:%v:%%v:%v:%v:%%v", data.aws_arn.current.partition, data.aws_region.current.name, data.aws_caller_identity.current.account_id) +} diff --git a/examples/fargate-cluster-tf-upgrade/outputs.tf b/examples/fargate-cluster-tf-upgrade/outputs.tf new file mode 100644 index 0000000..33abb2c --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/outputs.tf @@ -0,0 +1,4 @@ +output "ecs_cluster_id" { + description = "ECS Cluster ID" + value = aws_ecs_cluster.ecs.id +} diff --git a/examples/fargate-cluster-tf-upgrade/prefixes.tf b/examples/fargate-cluster-tf-upgrade/prefixes.tf new file mode 100644 index 0000000..6517845 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/prefixes.tf @@ -0,0 +1,40 @@ +locals { + _prefixes = { + "efs" = "v-efs-" + "s3" = "v-s3-" + "ebs" = "v-ebs-" + "kms" = "k-kms-" + "role" = "r-" + "policy" = "p-" + "group" = "g-" + "security-group" = "" # "sg-" + # VPC + "vpc" = "" + "dhcp-options" = "" + "vpc-peer" = "vpcp-" + "route-table" = "route-" + "subnet" = "" + "vpc-endpoint" = "vpce-" + "elastic-ip" = "eip-" + "nat-gateway" = "nat-" + "internet-gateway" = "igw-" + "network-acl" = "nacl-" + "customer-gateway" = "cgw-" + "vpn-gateway" = "vpcg-" + "vpn-connection" = "vpn_" + "log-group" = "lg-" + "log-stream" = "lgs-" + # EKS + "eks" = "eks-" + "eks-user" = "s-eks-" + "eks-role" = "r-eks-" + "eks-policy" = "p-eks-" + "eks-security-group" = "eks-" # "sg-eks-" + # ECS + "ecs" = "ecs-" + "ecs-user" = "s-ecs-" + "ecs-role" = "r-ecs-" + "ecs-policy" = "p-ecs-" + "ecs-security-group" = "ecs-" + } +} diff --git a/examples/fargate-cluster-tf-upgrade/region.tf b/examples/fargate-cluster-tf-upgrade/region.tf new file mode 100644 index 0000000..f617506 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/region.tf @@ -0,0 +1,3 @@ +locals { + region = var.region +} diff --git a/examples/fargate-cluster-tf-upgrade/roles.tf b/examples/fargate-cluster-tf-upgrade/roles.tf new file mode 100644 index 0000000..0edcc40 --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/roles.tf @@ -0,0 +1,155 @@ +#--- +# roles will be vpc and region specific +# task execution role +#--- +locals { + 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_name, var.vpc_short_name, local.region) + task_policy_name = format("p-%v", local.task_base_name) +} + +data "aws_vpc_endpoint_service" "vpc_endpoints" { + for_each = toset(local.vpc_endpoints) + service = each.key + filter { + name = "service-type" + values = ["Interface"] + } +} + +data "aws_vpc_endpoint" "vpc_endpoints" { + for_each = data.aws_vpc_endpoint_service.vpc_endpoints + service_name = each.value.service_name + vpc_id = data.aws_vpc.ecs_vpc.id +} + +# 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?ref=tf-upgrade" + + role_name = local.task_base_name + role_description = format("Role for ECS for %v-%v task execution", var.app_name, 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_name, 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.vpc_endpoints : 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?ref=tf-upgrade" + + role_name = local.instance_base_name + role_description = format("Role for ECS for %v-%v instance", var.app_name, 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 }, + ) +} + +output "ecs_task_role_arn" { + description = "ECS Task Role ARN" + value = module.ecs_task_role.role_arn +} + +output "ecs_instance_role_arn" { + description = "ECS Instance Role ARN" + value = module.ecs_instance_role.role_arn +} diff --git a/examples/fargate-cluster-tf-upgrade/tf-run.data b/examples/fargate-cluster-tf-upgrade/tf-run.data new file mode 100644 index 0000000..8e732ac --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/tf-run.data @@ -0,0 +1,15 @@ +VERSION 1.0.4 +REMOTE-STATE +COMMAND tf-directory-setup.py -l none -f +COMMAND setup-new-directory.sh +COMMAND tf-init -upgrade +COMMAND ln -sf ../init . +COMMAND ln -sf ../variables.vpc.tf +COMMAND ln -sf ../variables.vpc.auto.tfvars +LINKTOP provider_configs.d/provider.ldap_new.auto.tfvars +LINKTOP provider_configs.d/provider.ldap_new.tf +LINKTOP provider_configs.d/provider.ldap_new.variables.tf + +POLICY +ALL +COMMAND tf-directory-setup.py -l s3 diff --git a/examples/fargate-cluster-tf-upgrade/variables.cicd-deployer.tf b/examples/fargate-cluster-tf-upgrade/variables.cicd-deployer.tf new file mode 100644 index 0000000..9f1a42d --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/variables.cicd-deployer.tf @@ -0,0 +1,12 @@ +variable "cicd_user_name" { + description = "The user name of CICD Deployer" + type = string + default = "cicd-deployer" +} + +variable "cicd_group_name" { + description = "The Group name of CICD Deployer belongs to (excluding prefix for service account and cluster)" + type = string + default = "cicd-deployer" +} + diff --git a/examples/fargate-cluster-tf-upgrade/variables.ecs.tf b/examples/fargate-cluster-tf-upgrade/variables.ecs.tf new file mode 100644 index 0000000..1db2f9a --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/variables.ecs.tf @@ -0,0 +1,27 @@ +variable "cluster_name" { + description = "Cluster name of form {program}-{env}-fargate or {org}-{project}-{env}-fargate" + type = string +} + +# examples: dice-qa-fargate +# examples: ditd-gups-test-fargate + +variable "ecs_vpc_filter" { + description = "VPC filter (ex.,, vpc4-*) for selecting the correct VPC for this cluster" + 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 +} + +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 +} diff --git a/examples/fargate-cluster-tf-upgrade/versions.tf b/examples/fargate-cluster-tf-upgrade/versions.tf new file mode 100644 index 0000000..1fe34ba --- /dev/null +++ b/examples/fargate-cluster-tf-upgrade/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.0" + } + ldap = { + source = "trevex/ldap" + version = ">= 0.5.4" + } + } + required_version = ">= 0.13" +}