[小ネタ] AWS SAMのGoアプリケーションビルド時に -trimpath オプションを付ける方法
しばたです。
前回の記事でAWS SAMでGo言語アプリケーションをビルドする際に「条件により -trimpath パラメーターが付くこともある」旨を記載しました。
その手順自体はシンプルなのですが、どうも公式にドキュメント化されてない様なので本記事で軽く紹介しようと思います。
AWS SAMにおけるGoアプリケーションのビルド基本
AWS SAMではランタイム毎にアプリケーションのビルド方法が定められており、その実装はAWS Lambda Buildersにあります。
Go言語の場合はAWS::Serverless::Function
リソースで2パターンの指定方法があります。
- Runtimeプロパティを
go1.x
に指定する :go1.x
ランタイムの場合 - メタデータのBuildMethodプロパティに
go1.x
を指定する : カスタムランタイムの場合
# go1.x ランタイムの場合
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: TestFunction
CodeUri: function/
Handler: main
Runtime: go1.x
# カスタムランタイムの場合
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: TestFunction
CodeUri: function/
Handler: bootstrap
Runtime: provided.al2
Metadata:
BuildMethod: go1.x
どちらの場合もsam build
コマンド時に内部でgo build
コマンドを実行します。
# sam build内で呼ばれるビルドイメージ
export GOOS=linux
export GOARCH=Architecturesで指定されたアーキテクチャ
go build -o "Handlerパラメーターで指定された値" "CodeUriで指定されたパス"
ビルド時に-trimpathオプションを付ける方法
go build
時のオプションを開発者が自由に設定することはできません。
ただ、-trimpath
オプションに関しては利用者からのIssue起票[1]もあり設定可能となっています。
設定方法は簡単でAWS::Serverless::Function
リソースのメタデータのBuildProperties
プロパティ内でTrimGoPath: True
を設定してやればOKです。
これでAWS Lambda Builders側で-trimpath
オプションを付けたビルドをしてくれます。
# BuildPropertiesを設定することでgo buildに介入可能
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: TestFunction
CodeUri: function/
Handler: bootstrap
Runtime: provided.al2
Metadata:
BuildMethod: go1.x
BuildProperties:
TrimGoPath: True
この場合のビルドイメージはこんな感じです。
# TrimGoPathプロパティを指定した際のビルドイメージ
export GOOS=linux
export GOARCH=Architecturesで指定されたアーキテクチャ
go build -trimpath -o "Handlerパラメーターで指定された値" "CodeUriで指定されたパス"
その他のオプションを設定したい場合
AWS Lambda Buildersのソースを見る限り-trimpath
以外のオプションは指定できない感じでした。
(ローカルデバッグ時は別途専用のオプションが付く)
このため他のオプションも指定したい場合はMakefileを使ったビルドを選び、自分でgo build
のコマンドラインをカスタマイズしてやる必要があります。
具体的な内容については前回の記事の「補足 : Makefileビルドする場合」を参照してください。
余談1 : GOFLAGS環境変数も使えた、が...
Go言語ではグローバルな環境変数GOFLAGS
が存在し既定のオプションを設定することができます。
このGOFLAGS
環境変数を使ってAWS SAMの設定を無視してgo build
時のオプションを指定することができました。
# PowerShell環境での実行例
# GOFLAGS環境変数を設定して既定のオプションを指定
$env:GOFLAGS="-trimpath -tags=lambda.norpc"
sam build
一応動作したのですが、このためだけにグローバルな設定を変えてしまうよりは前述のMakefileビルドを選ぶ方が良いでしょう。
余談2 : 他言語での BuildProperties
Go言語だけでなく他の言語で使えるBuildProperties
を調べたところざっくり以下のプロパティを見つけることができました。
Node.jsについてはドキュメントも見つけたので細かい点はこちらを見ると良いでしょう。
言語 | プロパティ名 | 内容 | 設定値 |
---|---|---|---|
Go | TrimGoPath | go build時に-trimpathオプションを設定 | True or False (デフォルトFalse) |
Node.js (npm) | UseNpmCi | npm ciを使うか否か | True or False (デフォルトFalse) |
Node.js (esbuild) | EntryPoint | アプリケーションのエントリポイント | 値で指定 |
Node.js (esbuild) | External | ビルドから除外するパッケージ名 | 値で指定 |
Node.js (esbuild) | Format | ビルド時の出力フォーマット | 値で指定 |
Node.js (esbuild) | Loader | esbuild --loader パラメーターに設定する値を指定するっぽい |
値で指定 |
Node.js (esbuild) | MainFields | package.jsonのメインフィールド | 値で指定 (デフォルトmain ,module ) |
Node.js (esbuild) | Minify | 出力コードをminifyするか否か | True or False (デフォルトTrue) |
Node.js (esbuild) | OutExtension | 出力ファイルの拡張子 | 値で指定 |
Node.js (esbuild) | Sourcemap | ソースマップを出力するか否か | True or False (デフォルトFalse) |
Node.js (esbuild) | SourcesContent | ソースマップにソースコードを含むか否か | True or False (デフォルトTrue) |
Node.js (esbuild) | Target | ECMAScriptのバージョン | 値で指定 (デフォルトes2020 ) |
Rust (cargo-lambda) | Binary | 複数関数ある場合にビルド対象を指定 | 値で指定 |
たぶんこれ以外にもプロパティはあると思うので気が向いたら追記します。
最後に
簡単ですが以上となります。
メタデータに関する設定のためあまり厳密にドキュメント化されていない様です。
個人的には「-trimpath
はデフォルトで付けてしまっても良かったのでは?」と思いますが、現状オプション設定ですので原則設定する様にしておくと良いでしょう。
一般的に-trimpathオプションはセキュリティの文脈で語られることが多いと思いますが、このIssueではバイナリの同一性を担保したい点が発端になっています ↩︎