Skip to content

Commit

Permalink
fix(aws-ecs-pattern): allow ScheduledTaskBase to run on a public subn…
Browse files Browse the repository at this point in the history
…et (aws#6624)

Allow instances of ScheduledFargateTask and ScheduledEc2Task to run in a
*public* subnet via a configuration option.

The default remains that such instances are restricted to run on private
subnets, but it is now possible to allow them to run on public subnets
if the user is willing to sacrifice the extra security that a private
subnet provides in favour of a simpler/cheaper system that does not
require a NAT gateway or a NAT instance.

The new unit test schedules a Fargate task to run on a container in a
VPC with no private subnet. Before the changes to ScheduledTaskBase in
this commit, this test caused the following error:

    Error: There are no 'Private' subnet groups in this VPC. Available types: Public

fixes aws#6312

Co-authored-by: Wesley Pettit <[email protected]>
  • Loading branch information
floehopper and PettitWesley authored Mar 16, 2020
1 parent e850209 commit b9a1408
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 3 deletions.
24 changes: 22 additions & 2 deletions packages/@aws-cdk/aws-ecs-patterns/lib/base/scheduled-task-base.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Schedule } from "@aws-cdk/aws-applicationautoscaling";
import { IVpc } from '@aws-cdk/aws-ec2';
import { IVpc, SubnetSelection, SubnetType } from '@aws-cdk/aws-ec2';
import { AwsLogDriver, Cluster, ContainerImage, ICluster, LogDriver, Secret, TaskDefinition } from "@aws-cdk/aws-ecs";
import { Rule } from "@aws-cdk/aws-events";
import { EcsTask } from "@aws-cdk/aws-events-targets";
Expand Down Expand Up @@ -39,6 +39,15 @@ export interface ScheduledTaskBaseProps {
* @default 1
*/
readonly desiredTaskCount?: number;

/**
* In what subnets to place the task's ENIs
*
* (Only applicable in case the TaskDefinition is configured for AwsVpc networking)
*
* @default Private subnets
*/
readonly subnetSelection?: SubnetSelection;
}

export interface ScheduledTaskImageProps {
Expand Down Expand Up @@ -95,6 +104,15 @@ export abstract class ScheduledTaskBase extends Construct {
*/
public readonly desiredTaskCount: number;

/**
* In what subnets to place the task's ENIs
*
* (Only applicable in case the TaskDefinition is configured for AwsVpc networking)
*
* @default Private subnets
*/
public readonly subnetSelection: SubnetSelection;

/**
* The CloudWatch Events rule for the service.
*/
Expand All @@ -111,6 +129,7 @@ export abstract class ScheduledTaskBase extends Construct {
throw new Error('You must specify a desiredTaskCount greater than 0');
}
this.desiredTaskCount = props.desiredTaskCount || 1;
this.subnetSelection = props.subnetSelection || { subnetType: SubnetType.PRIVATE };

// An EventRule that describes the event trigger (in this case a scheduled run)
this.eventRule = new Rule(this, 'ScheduledEventRule', {
Expand All @@ -128,7 +147,8 @@ export abstract class ScheduledTaskBase extends Construct {
const eventRuleTarget = new EcsTask( {
cluster: this.cluster,
taskDefinition,
taskCount: this.desiredTaskCount
taskCount: this.desiredTaskCount,
subnetSelection: this.subnetSelection
});

this.eventRule.addTarget(eventRuleTarget);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect, haveResource } from '@aws-cdk/assert';
import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert';
import * as ec2 from '@aws-cdk/aws-ec2';
import * as ecs from '@aws-cdk/aws-ecs';
import * as events from '@aws-cdk/aws-events';
Expand Down Expand Up @@ -251,4 +251,47 @@ export = {

test.done();
},

"Scheduled Fargate Task - with subnetSelection defined"(test: Test) {
// GIVEN
const stack = new cdk.Stack();
const vpc = new ec2.Vpc(stack, 'Vpc', {
maxAzs: 1,
subnetConfiguration: [
{ name: 'Public', cidrMask: 28, subnetType: ec2.SubnetType.PUBLIC }
],
});
const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });

new ScheduledFargateTask(stack, 'ScheduledFargateTask', {
cluster,
scheduledFargateTaskImageOptions: {
image: ecs.ContainerImage.fromRegistry('henk'),
},
subnetSelection: { subnetType: ec2.SubnetType.PUBLIC },
schedule: events.Schedule.expression('rate(1 minute)')
});

// THEN
expect(stack).to(haveResourceLike('AWS::Events::Rule', {
Targets: [
{
EcsParameters: {
NetworkConfiguration: {
AwsVpcConfiguration: {
AssignPublicIp: 'ENABLED',
Subnets: [
{
Ref: 'VpcPublicSubnet1Subnet5C2D37C4'
}
]
}
},
}
}
]
}));

test.done();
},
};

0 comments on commit b9a1408

Please sign in to comment.