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,