App-FargateStack

 view release on metacpan or  search on metacpan

lib/App/EC2.pm  view on Meta::CPAN

package App::EC2;

use strict;
use warnings;

use App::FargateStack::Constants;
use Carp;
use Data::Dumper;
use File::Temp qw(tempfile);
use List::Util qw(any none uniq);
use JSON;
use Text::ASCIITable::EasyTable;

use Role::Tiny::With;
with 'App::AWS';

use parent 'App::Command';

__PACKAGE__->follow_best_practice;
__PACKAGE__->mk_accessors(
  qw(
    profile
    region
    security_group_name
    subnets
    vpc_id
  )
);

########################################################################
sub new {
########################################################################
  my ( $class, @args ) = @_;

  my $self = $class->SUPER::new(@args);

  if ( !$self->get_vpc_id ) {
    my @eligible_vpcs = $self->find_eligible_vpcs;
    $self->get_logger->info( sprintf 'eligible VPCS: [%s]', join q{,}, @eligible_vpcs );

    croak 'ERROR: could not find a Fargate-compatible VPC'
      if !@eligible_vpcs;

    croak sprintf "ERROR: found more than one Fargate-compatible VPC:\n%s", join "\n  - ", q{}, @eligible_vpcs
      if @eligible_vpcs > 1;

    $self->get_logger->warn( sprintf 'WARNING: no vpc_id set in config, using compatible VPC: [%s]', $eligible_vpcs[0] );

    $self->set_vpc_id( $eligible_vpcs[0] );
  }

  my $subnets = $self->get_subnets;
  my $vpc_id  = $self->get_vpc_id;

  # if the caller did not send any subnets, find all usable public and
  # private subnets
  if ( !$subnets ) {
    my $result = $self->describe_subnets( $vpc_id, 'Subnets' );

    croak sprintf "ERROR: there are no subnets in %s\n", $vpc_id
      if !@{$result};

    $subnets = $self->categorize_subnets;  # find private, public subnets
    $self->set_subnets($subnets);
  }
  else {
    my $usable_subnets = $self->categorize_subnets;

    my @all_subnets = map { @{ $usable_subnets->{$_} || [] } } qw(public private);

    $self->get_logger->debug(
      sub {
        return Dumper(
          [ all_subnets    => \@all_subnets,
            usable_subnets => $usable_subnets,
            subnets        => $subnets,
          ]
        );
      }
    );

    my $warning = <<'END_OF_WARNING';
WARNING: %s is not in the list of subnets with a route to the internet.

Tasks in private subnets require either:
- A NAT gateway (for general internet access), or
- Properly configured VPC endpoints for ECR, S3, STS, Logs, etc.

Without one of these, your task may fail to start or access required services.
END_OF_WARNING

    foreach my $type (qw(public private)) {
      foreach my $id ( @{ $subnets->{$type} || [] } ) {
        next if any { $_ eq $id } @all_subnets;
        $self->get_logger->warn( sprintf $warning, $id );



( run in 0.588 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )