From 26be3e9ebce11f368495620d2dc288788b1cb9e8 Mon Sep 17 00:00:00 2001 From: maz Date: Fri, 20 Dec 2024 07:19:28 +0900 Subject: [PATCH 1/7] feat(ecs): enbale fault injection flag --- packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index 7ab075ae777ce..7ebde7852c4ce 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -99,6 +99,13 @@ export interface CommonTaskDefinitionProps { * @default - No volumes are passed to the Docker daemon on a container instance. */ readonly volumes?: Volume[]; + + /** + * Enables fault injection and allows for fault injection requests to be accepted from the task's containers. + * + * @default false + */ + readonly enableFaultInjection?: boolean; } /** @@ -514,6 +521,7 @@ export class TaskDefinition extends TaskDefinitionBase { cpuArchitecture: this.runtimePlatform?.cpuArchitecture?._cpuArchitecture, operatingSystemFamily: this.runtimePlatform?.operatingSystemFamily?._operatingSystemFamily, } : undefined, + enableFaultInjection: props.enableFaultInjection, }); if (props.placementConstraints) { From 35008e6abfa9f0311cb170f6269e80acc7c8b04c Mon Sep 17 00:00:00 2001 From: maz Date: Fri, 20 Dec 2024 08:13:25 +0900 Subject: [PATCH 2/7] update --- ...efaultTestDeployAssert16EB808C.assets.json | 19 ++ ...aultTestDeployAssert16EB808C.template.json | 36 +++ ...inition-enable-fault-injection.assets.json | 19 ++ ...ition-enable-fault-injection.template.json | 124 ++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 134 ++++++++ .../tree.json | 291 ++++++++++++++++++ ....task-definition-enable-fault-injection.ts | 27 ++ packages/aws-cdk-lib/aws-ecs/README.md | 22 +- .../aws-ecs/lib/base/task-definition.ts | 18 +- .../aws-ecs/test/task-definition.test.ts | 33 ++ 12 files changed, 727 insertions(+), 9 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets.json new file mode 100644 index 0000000000000..a55289a57059d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.assets.json new file mode 100644 index 0000000000000..9599cb8f22cdf --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.assets.json @@ -0,0 +1,19 @@ +{ + "version": "38.0.1", + "files": { + "1f3359944a7dd8e04b4348673a74c55d7a4cf0f9645dcc981b79e1b9bb77dbd9": { + "source": { + "path": "aws-ecs-task-definition-enable-fault-injection.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "1f3359944a7dd8e04b4348673a74c55d7a4cf0f9645dcc981b79e1b9bb77dbd9.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.template.json new file mode 100644 index 0000000000000..6074f7be58a3d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/aws-ecs-task-definition-enable-fault-injection.template.json @@ -0,0 +1,124 @@ +{ + "Resources": { + "Ec2TaskDefinitionTaskRole0B78BC85": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "Ec2TaskDefinitionB25030BE": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "Memory": 512, + "Name": "Ec2Container" + } + ], + "EnableFaultInjection": true, + "Family": "awsecstaskdefinitionenablefaultinjectionEc2TaskDefinition28DF45DB", + "NetworkMode": "host", + "RequiresCompatibilities": [ + "EC2" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "Ec2TaskDefinitionTaskRole0B78BC85", + "Arn" + ] + } + } + }, + "FargateTaskDefinitionTaskRoleE3C2BCAA": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "FargateTaskDefinition8E3B365E": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "Memory": 512, + "Name": "FargateContainer" + } + ], + "Cpu": "256", + "EnableFaultInjection": true, + "Family": "awsecstaskdefinitionenablefaultinjectionFargateTaskDefinition203B68EF", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "FargateTaskDefinitionTaskRoleE3C2BCAA", + "Arn" + ] + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/cdk.out new file mode 100644 index 0000000000000..c6e612584e352 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"38.0.1"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/integ.json new file mode 100644 index 0000000000000..1779997e6b8dc --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "38.0.1", + "testCases": { + "TaskDefinitionEnableFaultInjection/DefaultTest": { + "stacks": [ + "aws-ecs-task-definition-enable-fault-injection" + ], + "assertionStack": "TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert", + "assertionStackName": "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/manifest.json new file mode 100644 index 0000000000000..ffc554651abf2 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/manifest.json @@ -0,0 +1,134 @@ +{ + "version": "38.0.1", + "artifacts": { + "aws-ecs-task-definition-enable-fault-injection.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-ecs-task-definition-enable-fault-injection.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-ecs-task-definition-enable-fault-injection": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-ecs-task-definition-enable-fault-injection.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/1f3359944a7dd8e04b4348673a74c55d7a4cf0f9645dcc981b79e1b9bb77dbd9.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-ecs-task-definition-enable-fault-injection.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-ecs-task-definition-enable-fault-injection.assets" + ], + "metadata": { + "/aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/TaskRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Ec2TaskDefinitionTaskRole0B78BC85" + } + ], + "/aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Ec2TaskDefinitionB25030BE", + "trace": [ + "!!DESTRUCTIVE_CHANGES: WILL_REPLACE" + ] + } + ], + "/aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/TaskRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FargateTaskDefinitionTaskRoleE3C2BCAA" + } + ], + "/aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "FargateTaskDefinition8E3B365E" + } + ], + "/aws-ecs-task-definition-enable-fault-injection/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-ecs-task-definition-enable-fault-injection/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-ecs-task-definition-enable-fault-injection" + }, + "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TaskDefinitionEnableFaultInjectionDefaultTestDeployAssert16EB808C.assets" + ], + "metadata": { + "/TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/tree.json new file mode 100644 index 0000000000000..4c4bc5c338169 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.js.snapshot/tree.json @@ -0,0 +1,291 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-ecs-task-definition-enable-fault-injection": { + "id": "aws-ecs-task-definition-enable-fault-injection", + "path": "aws-ecs-task-definition-enable-fault-injection", + "children": { + "Ec2TaskDefinition": { + "id": "Ec2TaskDefinition", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition", + "children": { + "TaskRole": { + "id": "TaskRole", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/TaskRole", + "children": { + "ImportTaskRole": { + "id": "ImportTaskRole", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/TaskRole/ImportTaskRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/TaskRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECS::TaskDefinition", + "aws:cdk:cloudformation:props": { + "containerDefinitions": [ + { + "essential": true, + "image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "memory": 512, + "name": "Ec2Container" + } + ], + "enableFaultInjection": true, + "family": "awsecstaskdefinitionenablefaultinjectionEc2TaskDefinition28DF45DB", + "networkMode": "host", + "requiresCompatibilities": [ + "EC2" + ], + "taskRoleArn": { + "Fn::GetAtt": [ + "Ec2TaskDefinitionTaskRole0B78BC85", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.CfnTaskDefinition", + "version": "0.0.0" + } + }, + "Ec2Container": { + "id": "Ec2Container", + "path": "aws-ecs-task-definition-enable-fault-injection/Ec2TaskDefinition/Ec2Container", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.ContainerDefinition", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.Ec2TaskDefinition", + "version": "0.0.0" + } + }, + "FargateTaskDefinition": { + "id": "FargateTaskDefinition", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition", + "children": { + "TaskRole": { + "id": "TaskRole", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/TaskRole", + "children": { + "ImportTaskRole": { + "id": "ImportTaskRole", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/TaskRole/ImportTaskRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/TaskRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECS::TaskDefinition", + "aws:cdk:cloudformation:props": { + "containerDefinitions": [ + { + "essential": true, + "image": "public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest", + "memory": 512, + "name": "FargateContainer" + } + ], + "cpu": "256", + "enableFaultInjection": true, + "family": "awsecstaskdefinitionenablefaultinjectionFargateTaskDefinition203B68EF", + "memory": "512", + "networkMode": "awsvpc", + "requiresCompatibilities": [ + "FARGATE" + ], + "taskRoleArn": { + "Fn::GetAtt": [ + "FargateTaskDefinitionTaskRoleE3C2BCAA", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.CfnTaskDefinition", + "version": "0.0.0" + } + }, + "FargateContainer": { + "id": "FargateContainer", + "path": "aws-ecs-task-definition-enable-fault-injection/FargateTaskDefinition/FargateContainer", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.ContainerDefinition", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.FargateTaskDefinition", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-ecs-task-definition-enable-fault-injection/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-ecs-task-definition-enable-fault-injection/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "TaskDefinitionEnableFaultInjection": { + "id": "TaskDefinitionEnableFaultInjection", + "path": "TaskDefinitionEnableFaultInjection", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "TaskDefinitionEnableFaultInjection/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "TaskDefinitionEnableFaultInjection/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TaskDefinitionEnableFaultInjection/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.4.2" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.ts new file mode 100644 index 0000000000000..2eb3338db7262 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/integ.task-definition-enable-fault-injection.ts @@ -0,0 +1,27 @@ +import * as cdk from 'aws-cdk-lib'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-ecs-task-definition-enable-fault-injection'); + +const ec2TaskDefinition = new ecs.Ec2TaskDefinition(stack, 'Ec2TaskDefinition', { + enableFaultInjection: true, + networkMode: ecs.NetworkMode.HOST, +}); +ec2TaskDefinition.addContainer('Ec2Container', { + image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), + memoryLimitMiB: 512, +}); + +const fargateTaskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDefinition', { + enableFaultInjection: true, +}); +fargateTaskDefinition.addContainer('FargateContainer', { + image: ecs.ContainerImage.fromRegistry('public.ecr.aws/ecs-sample-image/amazon-ecs-sample:latest'), + memoryLimitMiB: 512, +}); + +new IntegTest(app, 'TaskDefinitionEnableFaultInjection', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index dce4c0c88c817..b802279ee5be9 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -85,12 +85,12 @@ const cluster = new ecs.Cluster(this, 'Cluster', { }); ``` -To encrypt the fargate ephemeral storage configure a KMS key. +To encrypt the fargate ephemeral storage configure a KMS key. ```ts declare const key: kms.Key; -const cluster = new ecs.Cluster(this, 'Cluster', { - managedStorageConfiguration: { +const cluster = new ecs.Cluster(this, 'Cluster', { + managedStorageConfiguration: { fargateEphemeralStorageKmsKey: key, }, }); @@ -646,6 +646,22 @@ taskDefinition.addContainer('container', { }); ``` +### Enable Fault Injection +You can utilize fault injection with Amazon ECS on both Amazon EC2 and Fargate to test how their application responds to certain impairment scenarios. These tests provide information you can use to optimize your application's performance and resiliency. + +When fault injection is enabled, the Amazon ECS container agent allows tasks access to new fault injection endpoints. +Fault injection only works with tasks using the awsvpc or host network modes. + +For more infomation, see [Use fault injection with your Amazon ECS and Fargate workloads](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fault-injection.html). + +To enable Fault Injection for the task definiton, set `enableFaultInjection` to true. + +```ts +new ecs.Ec2TaskDefinition(this, 'Ec2TaskDefinition', { + enableFaultInjection: true, +}); +``` + ## Docker labels You can add labels to the container with the `dockerLabels` property or with the `addDockerLabel` method: diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index 7ebde7852c4ce..759fba1c3d216 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -103,6 +103,8 @@ export interface CommonTaskDefinitionProps { /** * Enables fault injection and allows for fault injection requests to be accepted from the task's containers. * + * Fault injection only works with tasks using the awsvpc or host network modes. + * * @default false */ readonly enableFaultInjection?: boolean; @@ -465,6 +467,10 @@ export class TaskDefinition extends TaskDefinitionBase { throw new Error('Cannot specify runtimePlatform in non-Fargate compatible tasks'); } + if (props.enableFaultInjection && ![NetworkMode.AWS_VPC, NetworkMode.HOST].includes(this.networkMode)) { + throw new Error(`Only AWSVPC and HOST Network Modes are supported for enabling Fault Injection, got ${this.networkMode} mode.`); + } + this._executionRole = props.executionRole; this.taskRole = props.taskRole || new iam.Role(this, 'TaskRole', { @@ -573,7 +579,7 @@ export class TaskDefinition extends TaskDefinitionBase { private renderInferenceAccelerators(): CfnTaskDefinition.InferenceAcceleratorProperty[] { return this._inferenceAccelerators.map(renderInferenceAccelerator); - function renderInferenceAccelerator(inferenceAccelerator: InferenceAccelerator) : CfnTaskDefinition.InferenceAcceleratorProperty { + function renderInferenceAccelerator(inferenceAccelerator: InferenceAccelerator): CfnTaskDefinition.InferenceAcceleratorProperty { return { deviceName: inferenceAccelerator.deviceName, deviceType: inferenceAccelerator.deviceType, @@ -683,7 +689,7 @@ export class TaskDefinition extends TaskDefinitionBase { this.volumes.push(volume); } - private validateVolume(volume: Volume):void { + private validateVolume(volume: Volume): void { if (volume.configuredAtLaunch !== true) { return; } @@ -892,7 +898,7 @@ export class TaskDefinition extends TaskDefinitionBase { private checkFargateWindowsBasedTasksSize(cpu: string, memory: string, runtimePlatform: RuntimePlatform) { if (Number(cpu) === 1024) { - if (Number(memory) < 1024 || Number(memory) > 8192 || (Number(memory)% 1024 !== 0)) { + if (Number(memory) < 1024 || Number(memory) > 8192 || (Number(memory) % 1024 !== 0)) { throw new Error(`If provided cpu is ${cpu}, then memoryMiB must have a min of 1024 and a max of 8192, in 1024 increments. Provided memoryMiB was ${Number(memory)}.`); } } else if (Number(cpu) === 2048) { @@ -901,7 +907,7 @@ export class TaskDefinition extends TaskDefinitionBase { } } else if (Number(cpu) === 4096) { if (Number(memory) < 8192 || Number(memory) > 30720 || (Number(memory) % 1024 !== 0)) { - throw new Error(`If provided cpu is ${ cpu }, then memoryMiB must have a min of 8192 and a max of 30720, in 1024 increments.Provided memoryMiB was ${ Number(memory) }.`); + throw new Error(`If provided cpu is ${cpu}, then memoryMiB must have a min of 8192 and a max of 30720, in 1024 increments.Provided memoryMiB was ${Number(memory)}.`); } } else { throw new Error(`If operatingSystemFamily is ${runtimePlatform.operatingSystemFamily!._operatingSystemFamily}, then cpu must be in 1024 (1 vCPU), 2048 (2 vCPU), or 4096 (4 vCPU). Provided value was: ${cpu}`); @@ -1039,7 +1045,7 @@ export interface Volume { * * @default false */ - readonly configuredAtLaunch ?: boolean; + readonly configuredAtLaunch?: boolean; /** * This property is specified when you are using Docker volumes. @@ -1139,7 +1145,7 @@ export interface DockerVolumeConfiguration { * * @default No options */ - readonly driverOpts?: {[key: string]: string}; + readonly driverOpts?: { [key: string]: string }; /** * Custom metadata to add to your Docker volume. * diff --git a/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts index f098b3e89afcb..db62adea3af95 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts @@ -457,6 +457,39 @@ describe('task definition', () => { Template.fromStack(stack); }).toThrow("ECS Container Container must have at least one of 'memoryLimitMiB' or 'memoryReservationMiB' specified"); }); + + test.each([true, false])('set enableFaultInjection to %s.', (enableFaultInjection) => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new ecs.TaskDefinition(stack, 'TD', { + cpu: '512', + compatibility: ecs.Compatibility.EC2, + enableFaultInjection, + networkMode: ecs.NetworkMode.HOST, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + EnableFaultInjection: enableFaultInjection, + }); + }); + + test('throws when enableFaultInjection is true with non AWSVPC or HOST Network Mode', () => { + // GIVEN + const stack = new cdk.Stack(); + + // THEN + expect(() => { + new ecs.TaskDefinition(stack, 'TD', { + cpu: '512', + compatibility: ecs.Compatibility.EC2, + enableFaultInjection: true, + networkMode: ecs.NetworkMode.BRIDGE, + }); + }).toThrow('Only AWSVPC and HOST Network Modes are supported for enabling Fault Injection, got bridge mode.'); + }); }); describe('When importing from an existing Task definition', () => { From 3edc10a1b6b7c2ff2adf969be82f00b47d7c14e0 Mon Sep 17 00:00:00 2001 From: Matsuda Date: Tue, 24 Dec 2024 19:43:27 +0900 Subject: [PATCH 3/7] Update packages/aws-cdk-lib/aws-ecs/README.md Co-authored-by: Jimmy Gaussen --- packages/aws-cdk-lib/aws-ecs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index b802279ee5be9..11a250fc21bd9 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -650,7 +650,7 @@ taskDefinition.addContainer('container', { You can utilize fault injection with Amazon ECS on both Amazon EC2 and Fargate to test how their application responds to certain impairment scenarios. These tests provide information you can use to optimize your application's performance and resiliency. When fault injection is enabled, the Amazon ECS container agent allows tasks access to new fault injection endpoints. -Fault injection only works with tasks using the awsvpc or host network modes. +Fault injection only works with tasks using the `AWS_VPC` or `HOST` network modes. For more infomation, see [Use fault injection with your Amazon ECS and Fargate workloads](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fault-injection.html). From 62fd4906591012fc497796c7726b946464cbc139 Mon Sep 17 00:00:00 2001 From: Matsuda Date: Tue, 24 Dec 2024 19:43:36 +0900 Subject: [PATCH 4/7] Update packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts Co-authored-by: Jimmy Gaussen --- packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index 759fba1c3d216..eb919fd85fae3 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -103,7 +103,7 @@ export interface CommonTaskDefinitionProps { /** * Enables fault injection and allows for fault injection requests to be accepted from the task's containers. * - * Fault injection only works with tasks using the awsvpc or host network modes. + * Fault injection only works with tasks using the {@link NetworkMode.AWS_VPC} or {@link NetworkMode.HOST} network modes. * * @default false */ From 94e40b81301628adf6ad581eff383be87d288688 Mon Sep 17 00:00:00 2001 From: Matsuda Date: Tue, 24 Dec 2024 19:43:49 +0900 Subject: [PATCH 5/7] Update packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts Co-authored-by: Jimmy Gaussen --- packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index eb919fd85fae3..d97daa86c5c35 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -468,7 +468,7 @@ export class TaskDefinition extends TaskDefinitionBase { } if (props.enableFaultInjection && ![NetworkMode.AWS_VPC, NetworkMode.HOST].includes(this.networkMode)) { - throw new Error(`Only AWSVPC and HOST Network Modes are supported for enabling Fault Injection, got ${this.networkMode} mode.`); + throw new Error(`Only AWS_VPC and HOST Network Modes are supported for enabling Fault Injection, got ${this.networkMode} mode.`); } this._executionRole = props.executionRole; From 67d97e6d8d443dfb0bbda037c4b145391df863b4 Mon Sep 17 00:00:00 2001 From: maz Date: Tue, 24 Dec 2024 19:45:01 +0900 Subject: [PATCH 6/7] update unit test --- packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts index db62adea3af95..72af3300eb88d 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/task-definition.test.ts @@ -488,7 +488,7 @@ describe('task definition', () => { enableFaultInjection: true, networkMode: ecs.NetworkMode.BRIDGE, }); - }).toThrow('Only AWSVPC and HOST Network Modes are supported for enabling Fault Injection, got bridge mode.'); + }).toThrow('Only AWS_VPC and HOST Network Modes are supported for enabling Fault Injection, got bridge mode.'); }); }); From ef75f21b4ff46cf271364eb002efee08214f02e4 Mon Sep 17 00:00:00 2001 From: maz Date: Tue, 7 Jan 2025 12:48:31 +0900 Subject: [PATCH 7/7] update --- packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts index d97daa86c5c35..c15e9ebdce9d5 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/base/task-definition.ts @@ -105,7 +105,7 @@ export interface CommonTaskDefinitionProps { * * Fault injection only works with tasks using the {@link NetworkMode.AWS_VPC} or {@link NetworkMode.HOST} network modes. * - * @default false + * @default undefined - ECS default setting is false */ readonly enableFaultInjection?: boolean; } @@ -467,6 +467,7 @@ export class TaskDefinition extends TaskDefinitionBase { throw new Error('Cannot specify runtimePlatform in non-Fargate compatible tasks'); } + // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fault-injection.html if (props.enableFaultInjection && ![NetworkMode.AWS_VPC, NetworkMode.HOST].includes(this.networkMode)) { throw new Error(`Only AWS_VPC and HOST Network Modes are supported for enabling Fault Injection, got ${this.networkMode} mode.`); }