AWS LambdaがPowerShell 7に対応しました

2020.04.19

しばたです。
AWS Lambdaが.NET Core 3.1に対応した記事で軽く触れてますが、AWS Lambdaが.NET Core 3.1に対応したのに合わせてPowerShell LambdaがPowerShell 7上で動作する様になりました。

AWS公式のアナウンスは以下。

本記事では以前試してみた際の内容を踏まえてLambdaのPowerShell 7対応について解説します。

PowerShell 7 と .NET Core 3.1

以前の記事でも触れましたが、PowerShellのLambdaは実体としては 「PowerShellスクリプトを実行するC# Lambda」 としてビルドおよびデプロイされています。
Lambdaのランタイムが.NET Core 3.1に更新されるのに合わせてOSに同梱されるPowerShellもPowerShell Core 6.xからPowerShell 7に変更されています。

PowerShell 7は.NET Core 3.1製ですので開発時に.NET Coreランタイムの違いといったことを意識する必要は特にありません。

AWSLambdaPSCore モジュール

Lambda関数テンプレートの提供やパッケージのビルド・デプロイ用に提供されているAWSLambdaPSCoreモジュールが.NET Core 3.1に対応するために Ver. 2.0.0.0 にメジャーバージョンアップしています。

AWSLambdaPSCore Ver.2以降を使えばそれだけで.NET Core 3.1ランタイムに対応します。

ランタイムバージョンの使い分けについて

ただ、残念ながらAWSLambdaPSCoreモジュールではデプロイするランタイムバージョンを振り分ける機能は提供されておらず、AWSLambdaPSCore Ver.2から.NET Core 2.1ランタイムへのデプロイはできません。

既存の.NET Core 2.1ランタイムで動作する関数を使っている場合は、.NET Core 3.1へ移行してしまうかAWSLambdaPSCoreモジュールのバージョンを使い分ける必要があります。

  • AWSLambdaPSCore Ver. 2.x : .NET Core 3.1ランタイム
  • AWSLambdaPSCore Ver. 1.x : .NET Core 2.1ランタイム

複数のバージョンのモジュールを使い分けるには以下の様にRemove-ModuleImport-Moduleを組み合わせてバージョン指定でモジュールを再ロードしてやればOKです。

Remove-Module AWSLambdaPSCore
Import-Module AWSLambdaPSCore -MaximumVersion 1.2.0.0

AWSLambdaPSCore Ver. 2.x の更新点

メジャーバージョンアップとなるAWSLambdaPSCore Ver. 2ですが、基本.NET Core 3.1対応であり新機能はほとんどありません。
唯一の新機能として、

  • Publish-AWSPowerShellLambda-Layerパラメーターが追加されLambda Layerに対応

があるくらいです。
この他に各種関数テンプレートで使用されるAWS Tools for PowerShellのバージョンが、Ver.3.3系 (AWSPowerShell.NetCoreモジュール)から Ver.4系 (AWS.Tools.*モジュール)に更新されており、これが一番大きな違いになると思います。

以前の記事で紹介したとおりAWS Tools for PowerShell 4からサービス毎にPowerShellモジュールが分割され、モジュールサイズの縮小やロード時間の改善が図られています。この更新はLambdaでPowerShellを扱う上で非常に大きな改善になると思います。

より詳細な更新点については以下のプルリクエストをご覧ください。

試してみた

それでは改めてPowerShell 7 Lambdaを試してみます。

開発環境のセットアップ

まず開発環境のセットアップについてですが、こちらは以前から変わりません。
各種ツールで要求されるバージョンが上がっているくらいの違いしかありません。

1. PowerShell 7

PowerShell 7 Lambdaですので開発環境にもPowerShell 7が必要です。
PowerShell 7のインストール方法については以下の記事を参考にしてください。

2. AWSLambdaPSCore モジュール

前節で触れた通りAWSLambdaPSCore Ver. 2が必要です。
PowerShell 7を起動しInstall-Moduleで最新バージョンがインストールできます。

Install-Module -Name AWSLambdaPSCore -Scope CurrentUser

Ver.1系を既にインストール済みの場合はUpdate-Moduleで最新バージョンを追加インストールできます。

Update-Module -Name AWSLambdaPSCore

3. .NET Core SDK 3.1

エントリ中でさんざん.NET Core 3.1に触れているとおり、関数パッケージを作成するために.NET Core SDK 3.1が必要です。
.NETのサイトから最新の.NET Core 3.1 SDKのMSIインストーラーをダウンロードしてインストールします。

今回は以前の記事でインストールしたVer. 3.1.201 をそのまま使っています。

4. (Optional) AWS.Tools.* モジュール

前節で触れた通りテンプレートで使用するAWS Tools for PowerShellのバージョンが変わっていますので、関数を作るのに必要な分のAWS.Tools.*なモジュールをインストールする必要があります。
モジュールの管理にはAWS.Tools.Installerモジュールを使うと便利です。

# 前準備として AWS.Tools.Installer モジュールをインストールしておくと便利
Install-Module -Name AWS.Tools.Installer

# あとは必要な分のモジュールをインストール
# 古いバージョンのモジュールを削除し、 EC2, S3 用の最新モジュールをインストールする例
Install-AWSToolsModule AWS.Tools.EC2, AWS.Tools.S3 -CleanUp

Lambda関数を作ってみる

以前の記事に倣ってLambda関数を作っていきます。

テンプレートの取得

Get-AWSPowerShellLambdaTemplateコマンドレットで関数テンプレートの一覧を取得できます。

C:\> Get-AWSPowerShellLambdaTemplate

Template                     Description
--------                     -----------
Basic                        Bare bones script
CloudFormationCustomResource PowerShell handler base for use with CloudFormation custom resource events
CodeCommitTrigger            Script to process AWS CodeCommit Triggers
DetectLabels                 Use Amazon Rekognition service to tag image files in S3 with detected labels.
KinesisStreamProcessor       Script to be process a Kinesis Stream
S3Event                      Script to process S3 events
S3EventToSNS                 Script to process SNS Records triggered by S3 events
S3EventToSNSToSQS            Script to process SQS Messages, subscribed to an SNS Topic that is triggered by S3 events
S3EventToSQS                 Script to process SQS Messages triggered by S3 events
SNSSubscription              Script to be subscribed to an SNS Topic
SNSToSQS                     Script to be subscribed to an SQS Queue, that is subscribed to an SNS Topic
SQSQueueProcessor            Script to be subscribed to an SQS Queue

いまは12個のテンプレートが用意されています。
個々のテンプレートのソースはGitHubで確認できます。

テンプレートから関数生成

本記事では一番基本的なBasicテンプレートからHelloPowerShellLambda7という名前の関数を生成してみます。
任意のディレクトリに移動しNew-AWSPowerShellLambdaコマンドレットから関数を生成します。

cd [任意のディレクトリ]
New-AWSPowerShellLambda -ScriptName HelloPowerShellLambda7 -Template Basic

生成されたHelloPowerShellLambda.ps1スクリプトはこんな感じ。
AWS.Tools.Commonモジュールが要求される様に変わっているのがわかります。

# PowerShell script file to be executed as a AWS Lambda function. 
# 
# When executing in Lambda the following variables will be predefined.
#   $LambdaInput - A PSObject that contains the Lambda function input data.
#   $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment.
#
# The last item in the PowerShell pipeline will be returned as the result of the Lambda function.
#
# To include PowerShell modules with your Lambda function, like the AWS.Tools.S3 module, add a "#Requires" statement
# indicating the module and version. If using an AWS.Tools.* module the AWS.Tools.Common module is also required.

#Requires -Modules @{ModuleName='AWS.Tools.Common';ModuleVersion='4.0.5.0'}

# Uncomment to send the input event to CloudWatch Logs
# Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5)

関数の修正

今回はこのテンプレートを以下の様に修正してみます。
入力をそのまま出力するだけの非常に簡単な関数です。

$message = $LambdaInput.Message
Write-Output ("Hello {0}!(on PowerShell Core {1})" -f $message, ($PSVersionTable.PSVersion.ToString()))

Lambda関数の入出力や特殊変数については.NET Core 2.1ランタイムと変わりありません。

Lambda関数をデプロイしてみる

作成した関数をデプロイするにはPublish-AWSPowerShellLambdaコマンドレットを使います。
基本的には以下の引数を指定すればOKです。

  • ScriptPath : デプロイするスクリプト
  • Name : 関数名
  • Region : デプロイするリージョン
  • Profile : 使用するプロファイル
cd .\HelloPowerShellLambda7\
Publish-AWSPowerShellLambda -ScriptPath .\HelloPowerShellLambda7.ps1 -Name HelloPowerShellLambda7 -Region ap-northeast-1 -Profile MyProfile

関数を新規作成する場合、不足している情報があれば都度プロンプトで入力を求められる点は従来通りです。
今回はIAMロールに既存のtest-lambda-roleを使う様にしています。

エラーなく終了すればデプロイは完了です。
コンソールを確認するとちゃんと関数が登録されています。

あとはよしなにLambdaの設定を施しください。

Lambda関数をテストしてみる

最後に関数をテストして結果を確認しておきます。
次の単純なJSONSampleInputを定義してこの関数をテストします。

{
  "Message": "Lambda"
}

結果は以下の様になり、ちゃんとPowerShell 7.0.0上で実行されていることがわかります。

最後に

ざっとこんな感じです。
PowerShell Lambdaを使っている人が世界的に見てもどの程度いるのか若干ビミョーなところはありますが、お使いの方は積極的にPowerShell 7対応していくと良いと思います。