Skip to content

Commit

Permalink
Merge pull request #25 from dxw/conditionally-add-ecs-cluster-ssm-pol…
Browse files Browse the repository at this point in the history
…icies

Conditionally add ECS cluster SSM policies
  • Loading branch information
Stretch96 authored Jan 2, 2024
2 parents 7133e68 + a0fd78f commit a3495ce
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 1 deletion.
21 changes: 20 additions & 1 deletion .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project creates and manages resources within an AWS account for infrastruct
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6.5 |
| <a name="requirement_archive"></a> [archive](#requirement\_archive) | >= 2.4.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.30.0 |
| <a name="requirement_external"></a> [external](#requirement\_external) | >= 2.3.2 |

## Providers

Expand All @@ -21,6 +22,7 @@ This project creates and manages resources within an AWS account for infrastruct
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.4.1 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.31.0 |
| <a name="provider_aws.awsroute53root"></a> [aws.awsroute53root](#provider\_aws.awsroute53root) | 5.31.0 |
| <a name="provider_external"></a> [external](#provider\_external) | 2.3.2 |

## Resources

Expand Down Expand Up @@ -51,6 +53,8 @@ This project creates and manages resources within an AWS account for infrastruct
| [aws_iam_policy.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_kms_encrypt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_sns_publish](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.infrastructure_ecs_cluster_ec2_ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.infrastructure_ecs_cluster_pass_role_ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_policy.infrastructure_ecs_cluster_ssm_service_setting_rw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.ecs_cluster_infrastructure_draining_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.infrastructure_ecs_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role.infrastructure_ecs_cluster_autoscaling_lifecycle_termination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
Expand All @@ -63,6 +67,8 @@ This project creates and manages resources within an AWS account for infrastruct
| [aws_iam_role_policy_attachment.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_kms_encrypt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_sns_publish](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.infrastructure_ecs_cluster_ec2_ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.infrastructure_ecs_cluster_pass_role_ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.infrastructure_ecs_cluster_ssm_service_setting_rw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_internet_gateway.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
| [aws_kms_alias.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
Expand Down Expand Up @@ -116,6 +122,7 @@ This project creates and manages resources within an AWS account for infrastruct
| [aws_ami.ecs_cluster_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_route53_zone.root](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
| [external_external.ssm_dhmc_setting](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |

## Inputs

Expand Down
13 changes: 13 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,16 @@ data "aws_ami" "ecs_cluster_ami" {
]
}
}

# aws_ssm_service_setting doesn't yet have a data source, so we need to use
# a script to retrieve SSM service settings
# https://github.com/hashicorp/terraform-provider-aws/issues/25170
data "external" "ssm_dhmc_setting" {
count = local.enable_infrastructure_ecs_cluster ? 1 : 0

program = ["/bin/bash", "external-data-scripts/get-ssm-service-setting.sh"]

query = {
setting_id = "arn:aws:ssm:${local.aws_region}:${local.aws_account_id}:servicesetting/ssm/managed-instance/default-ec2-instance-management-role"
}
}
43 changes: 43 additions & 0 deletions ecs-cluster-infrastructure.tf
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,43 @@ resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_ec2_ecs" {
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_ec2_ecs[0].arn
}

resource "aws_iam_policy" "infrastructure_ecs_cluster_ssm_service_setting_rw" {
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0

name = "${local.resource_prefix}-ssm-service-setting-rw"
policy = templatefile(
"${path.root}/policies/ssm-service-setting-rw.json.tpl",
{ ssm_service_setting_arn = data.external.ssm_dhmc_setting[0].result.arn }
)
}

resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_ssm_service_setting_rw" {
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0

role = aws_iam_role.infrastructure_ecs_cluster[0].name
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_ssm_service_setting_rw[0].arn
}

resource "aws_iam_policy" "infrastructure_ecs_cluster_pass_role_ssm_dhmc" {
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0

name = "${local.resource_prefix}-pass-role-ssm-dhmc"
policy = templatefile(
"${path.root}/policies/pass-role.json.tpl",
{
role_arn = "arn:aws:iam::${local.aws_account_id}:role/${data.external.ssm_dhmc_setting[0].result.setting_value}",
service = "ssm.amazonaws.com"
}
)
}

resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_pass_role_ssm_dhmc" {
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0

role = aws_iam_role.infrastructure_ecs_cluster[0].name
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_pass_role_ssm_dhmc[0].arn
}

resource "aws_iam_instance_profile" "infrastructure_ecs_cluster" {
count = local.enable_infrastructure_ecs_cluster ? 1 : 0

Expand Down Expand Up @@ -294,6 +331,12 @@ resource "aws_autoscaling_group" "infrastructure_ecs_cluster" {
"WarmPoolTotalCapacity",
"WarmPoolWarmedCapacity",
]

depends_on = [
aws_iam_role_policy_attachment.infrastructure_ecs_cluster_ec2_ecs,
aws_iam_role_policy_attachment.infrastructure_ecs_cluster_ssm_service_setting_rw,
aws_iam_role_policy_attachment.infrastructure_ecs_cluster_pass_role_ssm_dhmc,
]
}

resource "aws_sns_topic" "infrastructure_ecs_cluster_autoscaling_lifecycle_termination" {
Expand Down
18 changes: 18 additions & 0 deletions external-data-scripts/get-ssm-service-setting.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash

set -e
set -o pipefail

eval "$(jq -r '@sh "SSM_SERVICE_SETTING_ID=\(.setting_id)"')"

SERVICE_SETTING="$(aws ssm get-service-setting --setting-id "$SSM_SERVICE_SETTING_ID" | jq -cr '.ServiceSetting')"

jq -ncr --argjson service_setting "$SERVICE_SETTING" \
'$service_setting | {
setting_id: .SettingId,
setting_value: .SettingValue,
last_modified_date: .LastModifiedDate,
last_modified_user: .LastModifiedUser,
arn: .ARN,
status: .Status
}'
1 change: 1 addition & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ locals {
infrastructure_ecs_cluster_autoscaling_time_based_custom = {
for custom in toset(var.infrastructure_ecs_cluster_autoscaling_time_based_custom) : "${custom["min"]}-${custom["max"]} ${custom["cron"]}" => custom
}
infrastructure_ecs_cluster_enable_ssm_dhmc = local.enable_infrastructure_ecs_cluster ? data.external.ssm_dhmc_setting[0].result.setting_value != "$None" : ""
infrastructure_ecs_cluster_user_data = base64encode(
templatefile("ec2-userdata/ecs-instance.tpl", {
docker_storage_volume_device_name = local.infrastructure_ecs_cluster_ebs_docker_storage_volume_device_name,
Expand Down
19 changes: 19 additions & 0 deletions policies/pass-role.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "${role_arn}",
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"${service}"
]
}
}
}
]
}
14 changes: 14 additions & 0 deletions policies/ssm-service-setting-rw.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetServiceSetting",
"ssm:ResetServiceSetting",
"ssm:UpdateServiceSetting"
],
"Resource": "${ssm_service_setting_arn}"
}
]
}
4 changes: 4 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ terraform {
source = "hashicorp/archive"
version = ">= 2.4.1"
}
external = {
source = "hashicorp/external"
version = ">= 2.3.2"
}
}
}

0 comments on commit a3495ce

Please sign in to comment.