From 9bcc5233f2d90cd734609b50bf5d9cdf6ca685fb Mon Sep 17 00:00:00 2001 From: kazuho cryer-shinozuka Date: Wed, 3 Jan 2024 02:57:28 +0900 Subject: [PATCH] feat(ecs): `interactive` option in `ContainerDefinitionOptions` (#28536) This pull request adds the `interactive` argument to `ContainerDefinitionOptions`. This argument is used when deploying containerized applications that require the allocation of standard input (stdin) or a terminal (tty). This parameter corresponds to `OpenStdin` in the "Create a container" section of the Docker Remote API and the `--interactive` option to `docker run`. Closes #24326. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-ecs-integ.assets.json | 19 ++ .../aws-ecs-integ.template.json | 81 ++++++++ ...efaultTestDeployAssert6E49E825.assets.json | 19 ++ ...aultTestDeployAssert6E49E825.template.json | 36 ++++ .../cdk.out | 1 + .../integ.json | 12 ++ .../manifest.json | 119 +++++++++++ .../tree.json | 196 ++++++++++++++++++ ...sk-definition-add-interactive-container.ts | 22 ++ packages/aws-cdk-lib/aws-ecs/README.md | 14 ++ .../aws-ecs/lib/container-definition.ts | 9 + .../aws-ecs/test/container-definition.test.ts | 26 +++ 12 files changed, 554 insertions(+) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.assets.json new file mode 100644 index 0000000000000..682cc29bb2614 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "3ec26ce81958ec34f75b10a9cf74a9b069629a04fbb143ee6fee92eba0fa2458": { + "source": { + "path": "aws-ecs-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "3ec26ce81958ec34f75b10a9cf74a9b069629a04fbb143ee6fee92eba0fa2458.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/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.template.json new file mode 100644 index 0000000000000..5754189392d4b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/aws-ecs-integ.template.json @@ -0,0 +1,81 @@ +{ + "Resources": { + "TaskDefinitionTaskRoleFD40A61D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDefinitionB36D86D9": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "amazon/amazon-ecs-sample", + "Interactive": true, + "Name": "Container" + } + ], + "Cpu": "256", + "Family": "awsecsintegTaskDefinition11DF163D", + "Memory": "512", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "TaskDefinitionTaskRoleFD40A61D", + "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/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets.json new file mode 100644 index 0000000000000..7ecc620071e9d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.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/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.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/base/integ.task-definition-add-interactive-container.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/integ.json new file mode 100644 index 0000000000000..90b4d741db54c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "aws-ecs-container-definition-interactive/DefaultTest": { + "stacks": [ + "aws-ecs-integ" + ], + "assertionStack": "aws-ecs-container-definition-interactive/DefaultTest/DeployAssert", + "assertionStackName": "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/manifest.json new file mode 100644 index 0000000000000..5b73d89d7ed59 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/manifest.json @@ -0,0 +1,119 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-ecs-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-ecs-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-ecs-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-ecs-integ.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}/3ec26ce81958ec34f75b10a9cf74a9b069629a04fbb143ee6fee92eba0fa2458.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-ecs-integ.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-integ.assets" + ], + "metadata": { + "/aws-ecs-integ/TaskDefinition/TaskRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TaskDefinitionTaskRoleFD40A61D" + } + ], + "/aws-ecs-integ/TaskDefinition/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TaskDefinitionB36D86D9" + } + ], + "/aws-ecs-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-ecs-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-ecs-integ" + }, + "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.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": [ + "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.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": [ + "awsecscontainerdefinitioninteractiveDefaultTestDeployAssert6E49E825.assets" + ], + "metadata": { + "/aws-ecs-container-definition-interactive/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-ecs-container-definition-interactive/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-ecs-container-definition-interactive/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/base/integ.task-definition-add-interactive-container.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/tree.json new file mode 100644 index 0000000000000..f63fa10eb0620 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.js.snapshot/tree.json @@ -0,0 +1,196 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-ecs-integ": { + "id": "aws-ecs-integ", + "path": "aws-ecs-integ", + "children": { + "TaskDefinition": { + "id": "TaskDefinition", + "path": "aws-ecs-integ/TaskDefinition", + "children": { + "TaskRole": { + "id": "TaskRole", + "path": "aws-ecs-integ/TaskDefinition/TaskRole", + "children": { + "ImportTaskRole": { + "id": "ImportTaskRole", + "path": "aws-ecs-integ/TaskDefinition/TaskRole/ImportTaskRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-ecs-integ/TaskDefinition/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-integ/TaskDefinition/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ECS::TaskDefinition", + "aws:cdk:cloudformation:props": { + "containerDefinitions": [ + { + "essential": true, + "image": "amazon/amazon-ecs-sample", + "interactive": true, + "name": "Container" + } + ], + "cpu": "256", + "family": "awsecsintegTaskDefinition11DF163D", + "memory": "512", + "networkMode": "awsvpc", + "requiresCompatibilities": [ + "FARGATE" + ], + "taskRoleArn": { + "Fn::GetAtt": [ + "TaskDefinitionTaskRoleFD40A61D", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ecs.CfnTaskDefinition", + "version": "0.0.0" + } + }, + "Container": { + "id": "Container", + "path": "aws-ecs-integ/TaskDefinition/Container", + "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-integ/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-ecs-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "aws-ecs-container-definition-interactive": { + "id": "aws-ecs-container-definition-interactive", + "path": "aws-ecs-container-definition-interactive", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "aws-ecs-container-definition-interactive/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "aws-ecs-container-definition-interactive/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "aws-ecs-container-definition-interactive/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-ecs-container-definition-interactive/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-ecs-container-definition-interactive/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.3.0" + } + } + }, + "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/base/integ.task-definition-add-interactive-container.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.ts new file mode 100644 index 0000000000000..5372bc8ed7195 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ecs/test/base/integ.task-definition-add-interactive-container.ts @@ -0,0 +1,22 @@ +import * as cdk from 'aws-cdk-lib'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; +import * as integ from '@aws-cdk/integ-tests-alpha'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-ecs-integ'); + +const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDefinition', { + memoryLimitMiB: 512, + cpu: 256, +}); + +taskDefinition.addContainer('Container', { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + interactive: true, +}); + +new integ.IntegTest(app, 'aws-ecs-container-definition-interactive', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-ecs/README.md b/packages/aws-cdk-lib/aws-ecs/README.md index 47db5bb4b1f55..669f91846defa 100644 --- a/packages/aws-cdk-lib/aws-ecs/README.md +++ b/packages/aws-cdk-lib/aws-ecs/README.md @@ -482,6 +482,20 @@ const taskDef = new ecs.TaskDefinition(this, 'TaskDef', { taskDef.grantRun(role); ``` +To deploy containerized applications that require the allocation of standard input (stdin) or a terminal (tty), use the `interactive` property. + +This parameter corresponds to `OpenStdin` in the [Create a container](https://docs.docker.com/engine/api/v1.35/#tag/Container/operation/ContainerCreate) section of the [Docker Remote API](https://docs.docker.com/engine/api/v1.35/) +and the `--interactive` option to [docker run](https://docs.docker.com/engine/reference/run/#security-configuration). + +```ts +declare const taskDefinition: ecs.TaskDefinition; + +taskDefinition.addContainer("Container", { + image: ecs.ContainerImage.fromRegistry("amazon/amazon-ecs-sample"), + interactive: true, +}); +``` + ### Images Images supply the software that runs inside the container. Images can be diff --git a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts index 5c9ebf3df039c..0478a059df68d 100644 --- a/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts +++ b/packages/aws-cdk-lib/aws-ecs/lib/container-definition.ts @@ -251,6 +251,14 @@ export interface ContainerDefinitionOptions { */ readonly hostname?: string; + /** + * When this parameter is true, you can deploy containerized applications that require stdin or a tty to be allocated. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinition.html#cfn-ecs-taskdefinition-containerdefinition-interactive + * @default - false + */ + readonly interactive?: boolean; + /** * The amount (in MiB) of memory to present to the container. * @@ -797,6 +805,7 @@ export class ContainerDefinition extends Construct { essential: this.essential, hostname: this.props.hostname, image: this.imageConfig.imageName, + interactive: this.props.interactive, memory: this.props.memoryLimitMiB, memoryReservation: this.props.memoryReservationMiB, mountPoints: cdk.Lazy.any({ produce: () => this.mountPoints.map(renderMountPoint) }, { omitEmptyArray: true }), diff --git a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts index f537852fae364..76c1d5c254109 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/container-definition.test.ts @@ -2636,4 +2636,30 @@ describe('container definition', () => { }); }); }); + + test('can specify interactive parameter', () => { + // GIVEN + const stack = new cdk.Stack(); + const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + + new ecs.ContainerDefinition(stack, 'Container', { + image: ecs.ContainerImage.fromRegistry('/aws/aws-example-app'), + taskDefinition, + memoryLimitMiB: 2048, + interactive: true, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ECS::TaskDefinition', { + ContainerDefinitions: [ + { + Essential: true, + Image: '/aws/aws-example-app', + Memory: 2048, + Name: 'Container', + Interactive: true, + }, + ], + }); + }); });