AWS-Lambda

 view release on metacpan or  search on metacpan

author/update-aws-lambda-al.pl  view on Meta::CPAN

#!/usr/bin/env perl

use v5.36;
use FindBin;
use Parallel::ForkManager;
use Capture::Tiny ('capture');

my $archs = ['x86_64', 'arm64'];
my $regions = +{ map {
    my $arch = $_;
    open my $fh, '<', "$FindBin::Bin/regions-$arch.txt" or die "$!";
    my @regions = sort { $a cmp $b } map { chomp; $_; } <$fh>;
    close($fh);
    ($arch => \@regions);
} @$archs };

my $versions = [
    "5.38",
    "5.36",
    "5.34",
    "5.32",
    "5.30",
    "5.28",
    "5.26",
];
$versions = [sort {version->parse("v$b") <=> version->parse("v$a")} @$versions];

# get the list of layers on Amazon Linux 1
my $layers = {};
my $pm = Parallel::ForkManager->new(10);
$pm->run_on_finish(sub {
    my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data) = @_;
    return unless $data;
    my ($version, $region, $arn) = @$data;
    return unless $version && $region && $arn;
    $layers->{$version} //= {};
    $layers->{$version}{$region} = $arn;
});

for my $version (@$versions) {
    for my $region (@{$regions->{x86_64}}) {
        say STDERR "loading $version in $region...";
        $pm->start("$version/$region") and next;

        my $runtime_stack = "lambda-@{[ $version =~ s/[.]/-/r ]}-runtime";
        my $paws_stack = "lambda-@{[ $version =~ s/[.]/-/r ]}-paws";
        my ($stdout, $stderr, $exit);

        ($stdout, $stderr, $exit) = capture {
            system("aws --region $region cloudformation describe-stacks --output json --stack-name $runtime_stack | jq -r .Stacks[0].Outputs[0].OutputValue");
        };
        if ($exit != 0) {
            if ($stderr =~ /ValidationError/) {
                # the stack doesn't exist; skip it.
                $pm->finish;
                next;
            }
            die "failed to execute aws cli";
        }
        my $runtime_arn = $stdout;

        ($stdout, $stderr, $exit) = capture {
            system("aws --region $region cloudformation describe-stacks --output json --stack-name $paws_stack | jq -r .Stacks[0].Outputs[0].OutputValue");
        };
        if ($exit != 0) {
            if ($stderr =~ /ValidationError/) {
                # the stack doesn't exist; skip it.
                $pm->finish;
                next;
            }
            die "failed to execute aws cli";
        }
        my $paws_arn = $stdout;
 
        chomp($runtime_arn);
        chomp($paws_arn);
        $pm->finish(0, [$version, $region, {
            runtime_arn     => $runtime_arn,
            runtime_version => (split /:/, $runtime_arn)[-1],
            paws_arn        => $paws_arn,
            paws_version    => (split /:/, $paws_arn)[-1],
        }]);
    }
}
$pm->wait_all_children;

chomp(my $module_version = `cat $FindBin::Bin/../META.json | jq -r .version`);
my $latest_perl = $versions->[0];
my $latest_perl_layer = $latest_perl =~ s/[.]/-/r;
my $latest_runtime_arn = $layers->{$latest_perl}{'us-east-1'}{runtime_arn};
my $latest_runtime_version = $layers->{$latest_perl}{'us-east-1'}{runtime_version};
my $latest_paws_arn = $layers->{$latest_perl}{'us-east-1'}{paws_arn};
my $latest_paws_version = $layers->{$latest_perl}{'us-east-1'}{paws_version};

open my $fh, '>', "$FindBin::Bin/../lib/AWS/Lambda/AL.pm" or die "$!";

sub printfh :prototype($) {
    my $contents = shift;
    $contents =~ s/\@\@VERSION\@\@/$module_version/g;
    $contents =~ s/\@\@LATEST_PERL\@\@/$latest_perl/g;
    $contents =~ s/\@\@LATEST_PERL_LAYER\@\@/$latest_perl_layer/g;
    $contents =~ s/\@\@LATEST_RUNTIME_ARN\@\@/$latest_runtime_arn/g;
    $contents =~ s/\@\@LATEST_RUNTIME_VERSION\@\@/$latest_runtime_version/g;
    $contents =~ s/\@\@LATEST_PAWS_ARN\@\@/$latest_paws_arn/g;
    $contents =~ s/\@\@LATEST_PAWS_VERSION\@\@/$latest_paws_version/g;
    print $fh $contents;
}

printfh(<<'EOS');
package AWS::Lambda::AL;
use 5.026000;
use strict;
use warnings;

our $VERSION = "@@VERSION@@";

EOS

print $fh "# This list is auto generated by authors/update-aws-lambda-al.pl; DO NOT EDIT\n";
print $fh "our \$LAYERS = {\n";
for my $version (@$versions) {
    print $fh "    '$version' => {\n";
    for my $region (@{$regions->{x86_64}}) {
        next unless $layers->{$version}{$region}{runtime_arn};
        print $fh <<EOS
        '$region' => {
            runtime_arn     => "$layers->{$version}{$region}{runtime_arn}",
            runtime_version => $layers->{$version}{$region}{runtime_version},
            paws_arn        => "$layers->{$version}{$region}{paws_arn}",
            paws_version    => $layers->{$version}{$region}{paws_version},
        },
EOS
    }
    print $fh "    },\n";
}
print $fh "};\n\n";

printfh(<<'EOS');

sub get_layer_info {
    my ($version, $region) = @_;
    return $LAYERS->{$version}{$region};
}

sub print_runtime_arn {
    my ($version, $region) = @_;
    print $LAYERS->{$version}{$region}{runtime_arn};
}

sub print_paws_arn {
    my ($version, $region) = @_;
    print $LAYERS->{$version}{$region}{paws_arn};
}

1;
__END__

=encoding utf-8

=head1 NAME

AWS::Lambda::AL - AWS Lambda Custom Runtimes based on Amazon Linux

=head1 NO LONGER MAINTAINED

These layers are only for backward compatibility.
We recommend to migrate to Amazon Linux 2023.
These layers are NO LONGER MAINTAINED and WILL NOT RECEIVE ANY UPDATES.

=head1 SYNOPSIS

You can get the layer ARN in your script by using C<get_layer_info>.

    use AWS::Lambda::AL;
    my $info = AWS::Lambda::AL::get_layer_info(
        "@@LATEST_PERL@@",      # Perl Version
        "us-east-1", # Region
        "x86_64",    # Architecture ("x86_64" or "arm64", optional, the default is "x86_64")
    );
    say $info->{runtime_arn};     # @@LATEST_RUNTIME_ARN@@
    say $info->{runtime_version}; # @@LATEST_RUNTIME_VERSION@@
    say $info->{paws_arn}         # @@LATEST_PAWS_ARN@@
    say $info->{paws_version}     # @@LATEST_PAWS_VERSION@@,

Or, you can use following one-liner.

    perl -MAWS::Lambda -e 'AWS::Lambda::AL::print_runtime_arn("@@LATEST_PERL@@", "us-east-1")'
    perl -MAWS::Lambda -e 'AWS::Lambda::AL::print_paws_arn("@@LATEST_PERL@@", "us-east-1")'

The list of all available layer ARN is:

=over

EOS

for my $version (@$versions) {
    print $fh "=item Perl $version\n\n=over\n\n";
    for my $region (@{$regions->{x86_64}}) {
        next unless $layers->{$version}{$region}{runtime_arn};
        print $fh "=item C<$layers->{$version}{$region}{runtime_arn}>\n\n";
    }
    print $fh "=back\n\n";
}

printfh(<<'EOS');
=back

And Paws layers:

=over



( run in 0.723 second using v1.01-cache-2.11-cpan-99c4e6809bf )