Skip to content

Commit

Permalink
fix(aws-ecs-pattern): allow ScheduledTaskBase to run on a public subnet
Browse files Browse the repository at this point in the history
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
  • Loading branch information
floehopper committed Mar 14, 2020
1 parent 32c1808 commit f8fdc4f
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 f8fdc4f

Please sign in to comment.