question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

aws-ecs-patterns: Allow ScheduledFargateTask and ScheduledEc2Task to run on a public subnet

See original GitHub issue

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

Use Case

I’m currently using the ScheduledFargateTask class to run a number of simple tasks. The tasks need access to the internet, but there’s no need for them to be accessible from the internet. I could run the tasks on a private subnet, but this would mean I would need either a NAT Gateway (expensive) or run a NAT Instance on EC2 (maintenance/complexity overhead).

Since the tasks only run for a few minutes every week I’m willing to sacrifice the extra security that a private subnet provides in favour of a simpler/cheaper system where the tasks run on a public subnet.

However, currently ScheduledFargateTask will only run a task if its VPC has a private subnet - if there is no private subnet available, an error is reported. I would like to be able to run my tasks on a VPC defined along the following lines:

    const vpc = new ec2.Vpc(stack, 'Vpc', {
      maxAzs: 1,
      natGateways: 0,
      subnetConfiguration: [
        { name: 'public', cidrMask: 24, subnetType: SubnetType.PUBLIC }
      ],
    });
    const cluster = new ecs.Cluster(stack, 'EcsCluster', { vpc });

Proposed Solution

Currently the addTaskDefinitionToEventTarget method on ScheduledTaskBase instantiates the underlying EcsTask, but there is no way to specify the subnetSelection property of that EcsTask and so it defaults to { subnetType: ec2.SubnetType.PRIVATE }.

I propose that we add a subnetSelection property to the ScheduledTaskBaseProps interface and supply that property when instantiating the underlying EcsTask. This new property would default to { subnetType: ec2.SubnetType.PRIVATE } thus retaining the existing behaviour.

Other

  • In this comment @skinny85 mentioned that this is a gap in the ScheduledFargateTask construct.

  • In this comment @moofish32 suggested that using only a public subnet is a reasonable option in some circumstances.

  • Reading between the lines, it sounds as if others commenting on this issue might welcome this functionality.

  • 👋 I may be able to implement this feature request

  • ⚠️ This feature might incur a breaking change


This is a 🚀 Feature Request

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
floehoppercommented, Mar 6, 2020

@SoManyHs @pkandasamy91 I checked the “I may be able to implement this feature request” checkbox in the issue description as per the contribution guidelines. Is it worth me submitting a PR for this issue or are you unlikely to accept it…?

1reaction
pepastachcommented, Mar 7, 2020

Here’s a working solution in Python. I had to inherit from aws_ecs_patterns.ScheduledTaskBase instead of aws_ecs_patterns.ScheduledFargateTask, because the overridden method _add_task_definition_to_event_target() would never get called.

class ScheduledFargateTaskOnPublicSubnet(aws_ecs_patterns.ScheduledTaskBase, metaclass=jsii.JSIIMeta, jsii_type="@aws-cdk/aws-ecs-patterns.ScheduledFargateTask"):
    def __init__(self, scope: core.Construct, id: str, *,
                 schedule: aws_applicationautoscaling.Schedule,
                 scheduled_fargate_task_definition_options: Optional[aws_ecs_patterns.ScheduledFargateTaskDefinitionOptions] = None,
                 scheduled_fargate_task_image_options: Optional[aws_ecs_patterns.ScheduledFargateTaskImageOptions] = None,
                 cluster: Optional[aws_ecs.ICluster] = None,
                 desired_task_count: Optional[jsii.Number] = None,
                 vpc: Optional[aws_ec2.IVpc] = None) -> None:
        super().__init__(scope, id, schedule=schedule, cluster=cluster, desired_task_count=desired_task_count, vpc=vpc)
        self.task_definition = aws_ecs.FargateTaskDefinition(
            self, 'MyTaskDef',
            memory_limit_mib=scheduled_fargate_task_image_options.memory_limit_mib or 512,
            cpu=scheduled_fargate_task_image_options.cpu or 256
        )
        self.task_definition.add_container(
            'MyContainer',
            image=scheduled_fargate_task_image_options.image,
            command=scheduled_fargate_task_image_options.command,
            environment=scheduled_fargate_task_image_options.environment,
            secrets=scheduled_fargate_task_image_options.secrets,
            logging=scheduled_fargate_task_image_options.log_driver
        )

        self._add_task_definition_to_event_target(self.task_definition)

    @jsii.member(jsii_name="taskDefinition")
    def task_definition(self) -> aws_ecs.FargateTaskDefinition:
        """The Fargate task definition in this construct."""
        return self.task_definition

    @jsii.member(jsii_name="addTaskDefinitionToEventTarget")
    def _add_task_definition_to_event_target(self, task_definition: aws_ecs.TaskDefinition) -> aws_events_targets.EcsTask:
        event_rule_target = aws_events_targets.EcsTask(
            cluster=self.cluster,
            task_definition=task_definition,
            subnet_selection=aws_ec2.SubnetSelection(subnet_type=aws_ec2.SubnetType.PUBLIC),
            task_count=self.desired_task_count
        )
        self.event_rule.add_target(event_rule_target)

        return event_rule_target

And then you can create your VPC with a public subnet only and no NAT gateways:

def vpc(self) -> aws_ec2.Vpc:
    return aws_ec2.Vpc(
        self, 'MyVPC',
        cidr='172.16.0.0/28',  # 172.16.0.1 -> 172.16.0.14
        subnet_configuration=[
            aws_ec2.SubnetConfiguration(
                name='Public',
                subnet_type=aws_ec2.SubnetType.PUBLIC
            )
        ],
        max_azs=1,
        nat_gateways=0
    )
Read more comments on GitHub >

github_iconTop Results From Across the Web

aws-cdk/aws-ecs-patterns module - AWS Documentation
// Instantiate an Amazon EC2 Task to run at a scheduled interval declare const cluster: ecs.Cluster; const ecsScheduledTask = new ecsPatterns.ScheduledEc2Task( ...
Read more >
Scheduled Fargate Task example in AWS CDK
To start using Scheduled Fargate Tasks, you first need to set up a virtual private cloud (VPC). A VPC is a logically isolated...
Read more >
awsecspatterns - Go Packages
A Fargate service running on an ECS cluster fronted by an application load balancer. Example: var cluster cluster loadBalancedFargateService := ecsPatterns.
Read more >
ecs-patterns 1.182.0 javadoc (software.amazon.awscdk)
The properties for the base ScheduledEc2Task or ScheduledFargateTask task. ... An EC2 service running on an ECS cluster fronted by an application load ......
Read more >
ECS: Unable to start task from within a private subnet without ...
Oh, the run time is Fargate. The result is that the task get stuck in "Pending" state for ever. If I enable the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found