Skip to content

Commit 4fdf84f

Browse files
committed
Conditionally add ECS cluster SSM policies
* This conditionally adds the policies with permissions required to use SSM default host management configuration. * It checks for the value of the service setting to ensure dhcm has been enabled to decide wether to add the policies. `aws_ssm_service_setting` doesn't yet have a data source (hashicorp/terraform-provider-aws#25170), so it uses a script along with the `external` provider instead to get the service setting parameters.
1 parent 8bceca6 commit 4fdf84f

7 files changed

+126
-0
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ This project creates and manages resources within an AWS account for infrastruct
2121
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.4.1 |
2222
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.31.0 |
2323
| <a name="provider_aws.awsroute53root"></a> [aws.awsroute53root](#provider\_aws.awsroute53root) | 5.31.0 |
24+
| <a name="provider_external"></a> [external](#provider\_external) | n/a |
2425

2526
## Resources
2627

@@ -46,6 +47,8 @@ This project creates and manages resources within an AWS account for infrastruct
4647
| [aws_iam_policy.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_kms_encrypt](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4748
| [aws_iam_policy.infrastructure_ecs_cluster_autoscaling_lifecycle_termination_sns_publish](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4849
| [aws_iam_policy.infrastructure_ecs_cluster_ec2_ecs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
50+
| [aws_iam_policy.infrastructure_ecs_cluster_pass_role_ssm_dhmc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
51+
| [aws_iam_policy.infrastructure_ecs_cluster_ssm_service_setting_rw](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
4952
| [aws_iam_role.ecs_cluster_infrastructure_draining_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5053
| [aws_iam_role.infrastructure_ecs_cluster](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
5154
| [aws_iam_role.infrastructure_ecs_cluster_autoscaling_lifecycle_termination](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
@@ -58,6 +61,8 @@ This project creates and manages resources within an AWS account for infrastruct
5861
| [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 |
5962
| [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 |
6063
| [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 |
64+
| [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 |
65+
| [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 |
6166
| [aws_internet_gateway.infrastructure_public](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/internet_gateway) | resource |
6267
| [aws_kms_alias.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
6368
| [aws_kms_key.infrastructure](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
@@ -108,6 +113,7 @@ This project creates and manages resources within an AWS account for infrastruct
108113
| [aws_ami.ecs_cluster_ami](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
109114
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
110115
| [aws_route53_zone.root](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
116+
| [external_external.ssm_dhmc_setting](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |
111117

112118
## Inputs
113119

data.tf

+13
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,16 @@ data "aws_ami" "ecs_cluster_ami" {
2626
]
2727
}
2828
}
29+
30+
# aws_ssm_service_setting doesn't yet have a data source, so we need to use
31+
# a script to retrieve SSM service settings
32+
# https://github.com/hashicorp/terraform-provider-aws/issues/25170
33+
data "external" "ssm_dhmc_setting" {
34+
count = local.enable_infrastructure_ecs_cluster ? 1 : 0
35+
36+
program = ["/bin/bash", "external-data-scripts/get-ssm-service-setting.sh"]
37+
38+
query = {
39+
setting_id = "arn:aws:ssm:${local.aws_region}:${local.aws_account_id}:servicesetting/ssm/managed-instance/default-ec2-instance-management-role"
40+
}
41+
}

ecs-cluster-infrastructure.tf

+37
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,43 @@ resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_ec2_ecs" {
126126
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_ec2_ecs[0].arn
127127
}
128128

129+
resource "aws_iam_policy" "infrastructure_ecs_cluster_ssm_service_setting_rw" {
130+
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0
131+
132+
name = "${local.resource_prefix}-ssm-service-setting-rw"
133+
policy = templatefile(
134+
"${path.root}/policies/ssm-service-setting-rw.json.tpl",
135+
{ ssm_service_setting_arn = data.external.ssm_dhmc_setting.result.arn }
136+
)
137+
}
138+
139+
resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_ssm_service_setting_rw" {
140+
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0
141+
142+
role = aws_iam_role.infrastructure_ecs_cluster[0].name
143+
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_ssm_service_setting_rw[0].arn
144+
}
145+
146+
resource "aws_iam_policy" "infrastructure_ecs_cluster_pass_role_ssm_dhmc" {
147+
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0
148+
149+
name = "${local.resource_prefix}-pass-role-ssm-dhmc"
150+
policy = templatefile(
151+
"${path.root}/policies/pass-role.json.tpl",
152+
{
153+
role_arn = "arn:aws:iam::${local.aws_account_id}:role/${data.external.ssm_dhmc_setting.result.setting_value}",
154+
service = "ssm.amazonaws.com"
155+
}
156+
)
157+
}
158+
159+
resource "aws_iam_role_policy_attachment" "infrastructure_ecs_cluster_pass_role_ssm_dhmc" {
160+
count = local.infrastructure_ecs_cluster_enable_ssm_dhmc ? 1 : 0
161+
162+
role = aws_iam_role.infrastructure_ecs_cluster[0].name
163+
policy_arn = aws_iam_policy.infrastructure_ecs_cluster_pass_role_ssm_dhmc[0].arn
164+
}
165+
129166
resource "aws_iam_instance_profile" "infrastructure_ecs_cluster" {
130167
count = local.enable_infrastructure_ecs_cluster ? 1 : 0
131168

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
set -e
4+
set -o pipefail
5+
6+
eval "$(jq -r '@sh "SSM_SERVICE_SETTING_ID=\(.setting_id)"')"
7+
8+
SERVICE_SETTING="$(aws ssm get-service-setting --setting-id "$SSM_SERVICE_SETTING_ID" | jq -cr '.ServiceSetting')"
9+
10+
#SETTING_ID="$(echo "$SERVICE_SETTING" | jq -cr '.SettingId')"
11+
#SETTING_VALUE="$(echo "$SERVICE_SETTING" | jq -cr 'SettingValue')"
12+
#LAST_MODIFIED_DATE="$(echo "$SERVICE_SETTING" | jq -cr '.LastModifiedDate')"
13+
#LAST_MODIFIED_USER="$(echo "$SERVICE_SETTING" | jq -cr '.LastModifiedUser')"
14+
#ARN="$(echo "$SERVICE_SETTING" | jq -cr '.ARN')"
15+
#STATUS="$(echo "$SERVICE_SETTING" | jq -cr '.Status')"
16+
#
17+
#jq -n \
18+
# --arg setting_id "$SETTING_ID" \
19+
# --arg setting_value "$SETTING_VALUE" \
20+
# --arg last_modified_date "$LAST_MODIFIED_DATE" \
21+
# --arg last_modified_user "$LAST_MODIFIED_USER" \
22+
# --arg arn "$ARN" \
23+
# --arg status "$STATUS" \
24+
# '{
25+
# setting_id =
26+
# }'
27+
28+
jq -ncr --argjson service_setting "$SERVICE_SETTING" \
29+
'$service_setting | {
30+
setting_id: .SettingId,
31+
setting_value: .SettingValue,
32+
last_modified_date: .LastModifiedDate,
33+
last_modified_user: .LastModifiedUser,
34+
arn: .ARN,
35+
status: .Status
36+
}'

locals.tf

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ locals {
107107
infrastructure_ecs_cluster_min_size = var.infrastructure_ecs_cluster_min_size
108108
infrastructure_ecs_cluster_max_size = var.infrastructure_ecs_cluster_max_size
109109
infrastructure_ecs_cluster_max_instance_lifetime = var.infrastructure_ecs_cluster_max_instance_lifetime
110+
infrastructure_ecs_cluster_enable_ssm_dhmc = data.external.ssm_dhmc_setting.result.setting_value != "$None"
110111
infrastructure_ecs_cluster_user_data = base64encode(
111112
templatefile("ec2-userdata/ecs-instance.tpl", {
112113
docker_storage_volume_device_name = local.infrastructure_ecs_cluster_ebs_docker_storage_volume_device_name,

policies/pass-role.json.tpl

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Effect": "Allow",
6+
"Action": [
7+
"iam:PassRole"
8+
],
9+
"Resource": "${role_arn}",
10+
"Condition": {
11+
"StringEquals": {
12+
"iam:PassedToService": [
13+
"${service}"
14+
]
15+
}
16+
}
17+
}
18+
]
19+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"Version": "2012-10-17",
3+
"Statement": [
4+
{
5+
"Effect": "Allow",
6+
"Action": [
7+
"ssm:GetServiceSetting",
8+
"ssm:ResetServiceSetting",
9+
"ssm:UpdateServiceSetting"
10+
],
11+
"Resource": "${ssm_service_setting_arn}"
12+
}
13+
]
14+
}

0 commit comments

Comments
 (0)