From 7669b0006a2e537c9e8ce75fb971368c47a01b00 Mon Sep 17 00:00:00 2001 From: Simon Hildrew Date: Thu, 19 Jan 2023 09:32:11 +0000 Subject: [PATCH] fix: Switch from our home baked SSM policy to the current managed policy Once upon a time the recommended managed policy allowed full access to all S3 buckets but this craziness is no longer the case and the managed policy is treated with care. We should switch to this, at least in part, because it has some extra permissions needed for AWS Inspector (v2) and new required SSM permissions will be added for us in the future. --- src/constructs/iam/policies/index.ts | 1 - src/constructs/iam/policies/ssm.test.ts | 42 ---- src/constructs/iam/policies/ssm.ts | 38 --- .../__snapshots__/instance-role.test.ts.snap | 221 ++++++------------ .../iam/roles/instance-role.test.ts | 8 +- src/constructs/iam/roles/instance-role.ts | 7 +- .../error-budget-alarm.test.ts.snap | 102 +++----- .../ec2-app/__snapshots__/base.test.ts.snap | 102 +++----- 8 files changed, 134 insertions(+), 387 deletions(-) delete mode 100644 src/constructs/iam/policies/ssm.test.ts delete mode 100644 src/constructs/iam/policies/ssm.ts diff --git a/src/constructs/iam/policies/index.ts b/src/constructs/iam/policies/index.ts index f03544913f..2d8cf88879 100644 --- a/src/constructs/iam/policies/index.ts +++ b/src/constructs/iam/policies/index.ts @@ -9,4 +9,3 @@ export * from "./parameter-store-read"; export * from "./s3-get-object"; export * from "./s3-put-object"; export * from "./ses"; -export * from "./ssm"; diff --git a/src/constructs/iam/policies/ssm.test.ts b/src/constructs/iam/policies/ssm.test.ts deleted file mode 100644 index c48d605a20..0000000000 --- a/src/constructs/iam/policies/ssm.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Template } from "aws-cdk-lib/assertions"; -import { attachPolicyToTestRole, simpleGuStackForTesting } from "../../../utils/test"; -import { GuSSMRunCommandPolicy } from "./ssm"; - -describe("The GuSSMRunCommandPolicy class", () => { - it("sets default props", () => { - const stack = simpleGuStackForTesting(); - - const ssmPolicy = GuSSMRunCommandPolicy.getInstance(stack); - - attachPolicyToTestRole(stack, ssmPolicy); - - Template.fromStack(stack).hasResourceProperties("AWS::IAM::Policy", { - PolicyName: "ssm-run-command-policy", - PolicyDocument: { - Version: "2012-10-17", - Statement: [ - { - Effect: "Allow", - Resource: "*", - Action: [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - }, - ], - }, - }); - }); -}); diff --git a/src/constructs/iam/policies/ssm.ts b/src/constructs/iam/policies/ssm.ts deleted file mode 100644 index e16846b417..0000000000 --- a/src/constructs/iam/policies/ssm.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { isSingletonPresentInStack } from "../../../utils/singleton"; -import type { GuStack } from "../../core"; -import { GuAllowPolicy } from "./base-policy"; - -export class GuSSMRunCommandPolicy extends GuAllowPolicy { - private static instance: GuSSMRunCommandPolicy | undefined; - - private constructor(scope: GuStack) { - super(scope, "SSMRunCommandPolicy", { - policyName: "ssm-run-command-policy", - resources: ["*"], - actions: [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - }); - } - - public static getInstance(stack: GuStack): GuSSMRunCommandPolicy { - if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) { - this.instance = new GuSSMRunCommandPolicy(stack); - } - - return this.instance; - } -} diff --git a/src/constructs/iam/roles/__snapshots__/instance-role.test.ts.snap b/src/constructs/iam/roles/__snapshots__/instance-role.test.ts.snap index 075b580bd1..595b4e1448 100644 --- a/src/constructs/iam/roles/__snapshots__/instance-role.test.ts.snap +++ b/src/constructs/iam/roles/__snapshots__/instance-role.test.ts.snap @@ -7,7 +7,6 @@ exports[`The GuInstanceRole construct should allow additional policies to be spe "GuStack", "GuGetS3ObjectsPolicy", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuDistributionBucketParameter", "GuGetDistributablePolicy", @@ -116,6 +115,20 @@ exports[`The GuInstanceRole construct should allow additional policies to be spe ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -201,42 +214,6 @@ exports[`The GuInstanceRole construct should allow additional policies to be spe }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestingCB7BD146", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, }, } `; @@ -247,7 +224,6 @@ exports[`The GuInstanceRole construct should be possible to create multiple inst "gu:cdk:constructs": [ "GuStack", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -425,6 +401,20 @@ exports[`The GuInstanceRole construct should be possible to create multiple inst ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -465,6 +455,20 @@ exports[`The GuInstanceRole construct should be possible to create multiple inst ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -609,45 +613,6 @@ exports[`The GuInstanceRole construct should be possible to create multiple inst }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleMyfirstapp5C11A22B", - }, - { - "Ref": "InstanceRoleMysecondapp48DD15D7", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, }, } `; @@ -658,7 +623,6 @@ exports[`The GuInstanceRole construct should create an additional logging policy "gu:cdk:constructs": [ "GuStack", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -795,6 +759,20 @@ exports[`The GuInstanceRole construct should create an additional logging policy ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -880,42 +858,6 @@ exports[`The GuInstanceRole construct should create an additional logging policy }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestingCB7BD146", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, }, } `; @@ -926,7 +868,6 @@ exports[`The GuInstanceRole construct should create the correct resources with m "gu:cdk:constructs": [ "GuStack", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuDistributionBucketParameter", "GuGetDistributablePolicy", @@ -1014,6 +955,20 @@ exports[`The GuInstanceRole construct should create the correct resources with m ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -1099,42 +1054,6 @@ exports[`The GuInstanceRole construct should create the correct resources with m }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestingCB7BD146", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, }, } `; diff --git a/src/constructs/iam/roles/instance-role.test.ts b/src/constructs/iam/roles/instance-role.test.ts index 78578f3af0..907f4334e7 100644 --- a/src/constructs/iam/roles/instance-role.test.ts +++ b/src/constructs/iam/roles/instance-role.test.ts @@ -12,7 +12,7 @@ describe("The GuInstanceRole construct", () => { expect(template.toJSON()).toMatchSnapshot(); template.resourceCountIs("AWS::IAM::Role", 1); - template.resourceCountIs("AWS::IAM::Policy", 4); + template.resourceCountIs("AWS::IAM::Policy", 3); }); it("should create an additional logging policy if logging stream is specified", () => { @@ -23,7 +23,7 @@ describe("The GuInstanceRole construct", () => { expect(template.toJSON()).toMatchSnapshot(); template.resourceCountIs("AWS::IAM::Role", 1); - template.resourceCountIs("AWS::IAM::Policy", 5); + template.resourceCountIs("AWS::IAM::Policy", 4); }); it("should allow additional policies to be specified", () => { @@ -39,7 +39,7 @@ describe("The GuInstanceRole construct", () => { expect(template.toJSON()).toMatchSnapshot(); template.resourceCountIs("AWS::IAM::Role", 1); - template.resourceCountIs("AWS::IAM::Policy", 5); + template.resourceCountIs("AWS::IAM::Policy", 4); }); it("should be possible to create multiple instance roles in a single stack", () => { @@ -57,6 +57,6 @@ describe("The GuInstanceRole construct", () => { expect(template.toJSON()).toMatchSnapshot(); template.resourceCountIs("AWS::IAM::Role", 2); - template.resourceCountIs("AWS::IAM::Policy", 7); // 3 shared policies + 2 policies per role (3 + (2*2)) + template.resourceCountIs("AWS::IAM::Policy", 6); // 2 shared policies + 2 policies per role (2 + (2*2)) }); }); diff --git a/src/constructs/iam/roles/instance-role.ts b/src/constructs/iam/roles/instance-role.ts index 262113ad1b..547966d320 100644 --- a/src/constructs/iam/roles/instance-role.ts +++ b/src/constructs/iam/roles/instance-role.ts @@ -1,4 +1,4 @@ -import { ServicePrincipal } from "aws-cdk-lib/aws-iam"; +import { ManagedPolicy, ServicePrincipal } from "aws-cdk-lib/aws-iam"; import { GuAppAwareConstruct } from "../../../utils/mixin/app-aware-construct"; import type { AppIdentity, GuStack } from "../../core"; import { @@ -6,7 +6,6 @@ import { GuGetDistributablePolicy, GuLogShippingPolicy, GuParameterStoreReadPolicy, - GuSSMRunCommandPolicy, } from "../policies"; import type { GuPolicy } from "../policies"; import { GuRole } from "./roles"; @@ -49,7 +48,6 @@ export class GuInstanceRole extends GuAppAwareConstruct(GuRole) { }); const sharedPolicies = [ - GuSSMRunCommandPolicy.getInstance(scope), GuDescribeEC2Policy.getInstance(scope), ...(props.withoutLogShipping ? [] : [GuLogShippingPolicy.getInstance(scope)]), ]; @@ -61,6 +59,9 @@ export class GuInstanceRole extends GuAppAwareConstruct(GuRole) { ...(props.additionalPolicies ? props.additionalPolicies : []), ]; + const managedPolicies = [ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")]; + policies.forEach((p) => p.attachToRole(this)); + managedPolicies.forEach((p) => this.addManagedPolicy(p)); } } diff --git a/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap b/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap index 50751afef6..e945603a85 100644 --- a/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap +++ b/src/experimental/constructs/__snapshots__/error-budget-alarm.test.ts.snap @@ -629,7 +629,6 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "GuEc2App", "GuCertificate", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -1550,6 +1549,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -1921,42 +1934,6 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestguec2appC325BE42", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, "TargetGroupTestguec2app9F67D503": { "Properties": { "HealthCheckIntervalSeconds": 10, @@ -2064,7 +2041,6 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re "GuEc2App", "GuCertificate", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -2817,6 +2793,20 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -3188,42 +3178,6 @@ exports[`The ErrorBudgetAlarmExperimental construct should create the correct re }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestguec2appC325BE42", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, "TargetGroupTestguec2app9F67D503": { "Properties": { "HealthCheckIntervalSeconds": 10, diff --git a/src/patterns/ec2-app/__snapshots__/base.test.ts.snap b/src/patterns/ec2-app/__snapshots__/base.test.ts.snap index 16c2aae180..e832dbdbbf 100644 --- a/src/patterns/ec2-app/__snapshots__/base.test.ts.snap +++ b/src/patterns/ec2-app/__snapshots__/base.test.ts.snap @@ -11,7 +11,6 @@ exports[`the GuEC2App pattern can produce a restricted EC2 app locked to specifi "GuEc2App", "GuCertificate", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -407,6 +406,20 @@ exports[`the GuEC2App pattern can produce a restricted EC2 app locked to specifi ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -682,42 +695,6 @@ exports[`the GuEC2App pattern can produce a restricted EC2 app locked to specifi }, "Type": "AWS::EC2::SecurityGroupEgress", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestguec2appC325BE42", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, "TargetGroupTestguec2app9F67D503": { "Properties": { "HealthCheckIntervalSeconds": 10, @@ -825,7 +802,6 @@ exports[`the GuEC2App pattern should produce a functional EC2 app with minimal a "GuEc2App", "GuCertificate", "GuInstanceRole", - "GuSSMRunCommandPolicy", "GuDescribeEC2Policy", "GuLoggingStreamNameParameter", "GuLogShippingPolicy", @@ -1199,6 +1175,20 @@ exports[`the GuEC2App pattern should produce a functional EC2 app with minimal a ], "Version": "2012-10-17", }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/AmazonSSMManagedInstanceCore", + ], + ], + }, + ], "Path": "/", "Tags": [ { @@ -1416,42 +1406,6 @@ exports[`the GuEC2App pattern should produce a functional EC2 app with minimal a }, "Type": "AWS::IAM::Policy", }, - "SSMRunCommandPolicy244E1613": { - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "ec2messages:AcknowledgeMessage", - "ec2messages:DeleteMessage", - "ec2messages:FailMessage", - "ec2messages:GetEndpoint", - "ec2messages:GetMessages", - "ec2messages:SendReply", - "ssm:UpdateInstanceInformation", - "ssm:ListInstanceAssociations", - "ssm:DescribeInstanceProperties", - "ssm:DescribeDocumentParameters", - "ssmmessages:CreateControlChannel", - "ssmmessages:CreateDataChannel", - "ssmmessages:OpenControlChannel", - "ssmmessages:OpenDataChannel", - ], - "Effect": "Allow", - "Resource": "*", - }, - ], - "Version": "2012-10-17", - }, - "PolicyName": "ssm-run-command-policy", - "Roles": [ - { - "Ref": "InstanceRoleTestguec2appC325BE42", - }, - ], - }, - "Type": "AWS::IAM::Policy", - }, "TargetGroupTestguec2app9F67D503": { "Properties": { "HealthCheckIntervalSeconds": 10,