[アップデート]AWS SAM CLIのsam syncコマンドが一定条件下でドリフトの生成をスキップするようになりました
初めに
Release 1.78.0 - SAM Accelerate Skip Infra Sync and Python3.10 Support Latest
AWS SAM CLI v1.78.0においてsam sync
の実行時に一定条件下でスタックのドリフトのスキップをコントロールするオプションの
--no-skip-deploy-sync
および--skip-deploy-sync
オプションが追加されました。
変更について
これまではsam sync
の実行直後にはSAMテンプレートには変更がなくともドリフトを発生させる仕様でしたが、
今回実行前後のテンプレートの単純比較で変更がなかった場合はこのドリフトをスキップする機能が追加されました。
これまでの挙動が--no-skip-deploy-sync
の動作、今回追加された挙動が--skip-deploy-sync
となります。
また今後はsam sync
実行時のデフォルトの動作が--skip-deploy-sync
に変更されます。
これまで通り実行時にドリフトを発生させたい場合は明示的に--no-skip-deploy-sync
を指定する必要が出てきます。
What's newのにまだ上がっていませんがドキュメントは既に更新され該当のオプションが追加されていました。
Using the AWS SAM CLI sam sync command - Skip the initial AWS CloudFormation deployment
ただし--skip-deploy-sync
が明示的に指定されている場合であっても
前回の実行から7日が経過もしくは一定以上のLambda関数のコードに変更が入っている場合はオプションの指定状況に関わらずドリフトが生成されます。
Using the AWS SAM CLI sam sync command - Skip the initial AWS CloudFormation deployment
- If its been 7 days or more since your last AWS CloudFormation deployment.
- If a large number of Lambda function code changes are detected, making AWS CloudFormation deployment the quickest method to update your application.
ちなみに大量の変更というのはいくつだろうと思ったのですがコードを流し見する限り具体的には50以上のようです。
(SYNC_FLOW_THRESHOLD
の値より)
具体的にはこの辺りの変更となるので興味のある方はコードを読んでみてはいかがでしょうか。
https://github.com/aws/aws-sam-cli/compare/v1.77.0...v1.78.0
また7日については最後にsam sync
を実行したタイミングではなくドリフトが実行されてタイミングのようです。
ただしこの比較となる値はCloudFormation側に見に行っているわけではなくsync.toml
に記載されている値を読んでいるようなので、
手動で調整すれば実際は7日過ぎていても無理やりスキップが可能とは思われます(やらない方がいい気はしますが...)。
[sync_state] dependency_layer = true latest_infra_sync_time = "2023-03-24T18:13:34.750262"
実際に試してみる
準備
SAM CLIのバージョンは今回リリースされた1.78.0を利用します。
% sam --version SAM CLI, version 1.78.0
サンプルの適当なプロジェクトを作成しまずはベースとなるコードをデプロイしておきます。
$ sam init #Hello Worldのサンプルで作成しています ... $ sam deploy ....
しばらく前はsamconfig.toml
は手動で作るかdeploy時に--guided
オプションを指定するなどで作らないといけなかったような気がするのですがいつの間にかinit時に作成されるようになっていました。
--no-skip-deploy-syncを指定し実行する
まずはこれまで相当の挙動を改めて確認してみます。
上記の準備処理の後特に何も変更を行わずsam sync --no-skip-deploy-sync
を実行します。
% sam sync --no-skip-deploy-sync ... Deploying with following values =============================== Stack name : sam-app Region : ap-northeast-1 Disable rollback : False Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxx Capabilities : ["CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"] Parameter overrides : {} Signing Profiles : null Initiating deployment ===================== 2023-03-25 02:37:07 - Waiting for stack create/update to complete CloudFormation events from stack operations (refresh every 0.5 seconds) --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- UPDATE_IN_PROGRESS AWS::CloudFormation::Stack sam-app User Initiated UPDATE_IN_PROGRESS AWS::CloudFormation::Stack sam-app Transformation succeeded UPDATE_IN_PROGRESS AWS::CloudFormation::Stack AwsSamAutoDependencyLayerNestedStack - UPDATE_COMPLETE AWS::CloudFormation::Stack AwsSamAutoDependencyLayerNestedStack - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS AWS::CloudFormation::Stack sam-app - UPDATE_COMPLETE AWS::CloudFormation::Stack AwsSamAutoDependencyLayerNestedStack - UPDATE_COMPLETE AWS::CloudFormation::Stack sam-app - --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ... CodeTrigger not created as CodeUri or DefinitionUri is missing for ServerlessRestApi. Infra sync completed.
CLI上の表示でスタックの開始が02:37:07
、
マネジメントコンソール上でスタックの更新完了が02:37:30
のためおおよそ20秒ほどかかっています。
実際はスタックの作成までの時間もあるのでiTermの機能で表示されたタイミングを確認していたのですが全体としてはおおよそ30秒ほどです。 (検証のために何度か試しましたが割と早いケースした)
あくまでサンプルのデフォルトプロジェクトでの実施ですので内容によってはもっと長くなる可能性があります。
--skip-deploy-syncを指定し実行する
これまでの動作が確認できたので新しく追加されたオプションを試してみます。
% sam sync --skip-deploy-sync The SAM CLI will use the AWS Lambda, Amazon API Gateway, and AWS StepFunctions APIs to upload your code without performing a CloudFormation deployment. This will cause drift in your CloudFormation stack. **The sync command should only be used against a development stack**. Queued infra sync. Waiting for in progress code syncs to complete... Starting infra sync. Manifest is not changed for (HelloWorldFunction), running incremental build Building codeuri: /xxxx/sam-app/hello_world runtime: python3.9 metadata: {} architecture: x86_64 functions: HelloWorldFunction Running PythonPipBuilder:CopySource Build Succeeded Successfully packaged artifacts and wrote output template to file /var/folders/8m/xxxxx/T/xxxxxx. Execute the following command to deploy the packaged template sam deploy --template-file /var/folders/8m/xxxxx/T/xxxxx --stack-name <YOUR STACK NAME> Template haven't been changed since last deployment, skipping infra sync...
スキップの判定が出るまでは先ほどとほとんど同じで7秒ほどでしたが、
スキップの部分は1秒もかからずほぼ一瞬でした。
ちょうどスキップ前にMFAの要求が出るため比較その点を基準としていますが、
入力直ほぼ一瞬で表示される感じです。
(コードを読む限り)嬉しいことにネストスタックにも対応していますが、
ファイル量が多くなると単純に比較量が増えるので多少変わってくるかもしれません。
ただ流石にドリフトを待つよりは早いのではないかなと思っています。
終わりに
今回のアップデートで条件次第でsam sync
の起動が高速化する変更が行われました。
sam sync
は一度起動してしまえば--code
オプションをつけた時を筆頭に高速に反映を適用可能です。
一度起動して仕舞えば早いとはいえ起動が遅いという地味にストレスになる部分が条件付きですが大きく改善したため是非試してみてはいかがでしょうか。
MFA入力失敗時の挙動が怪しい(余談)
検証している中で--skip-deploy-sync
を指定しているにも関わらずなぜかドリフトが走るケースがありました。
試している限りどうもMFAの入力を途中に挟むような場合
MFAの入力に失敗あると次に実行する際に指定に関わらずドリフトがスキップされないケースがあるようです。
別タブ等で起動すると直るため環境変数か何かの周りでもしかしたらバグがあるのかもしれません(未報告)。