AWS SAM CLIのvalidate経由でcfn-lintが実行できるようになりました

2023.01.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS SAM CLIのテンプレートチェック機能であるsam validateが拡張され
--lintオプションを付与することでcfn-lintによるチェックが可能になっていました。

Validate AWS Serverless Application Model (SAM) templates with CloudFormation Linter to speed up development

なお執筆時点でで既にv1.70.0がリリースされていますが
この機能自体はv1.69.0での実装となります。

https://github.com/aws/aws-sam-cli/releases/tag/v1.69.0

実行バージョン

  • SAM CLI, version 1.70.0

この変更により何が良いか

ざっくりsamコマンドの一環でできるチェックの範囲が広がりました。

sam validateコマンドはテンプレートを構造的に正しいかどうかを判定するのみで、
内容的に正しいかどうかまで検証が行われていません。

そのため!Refの参照先が正しいかといった内容的なチェックまではされません。

通常のvalidate

例えば以下のテンプレートの場合、
明らかに必須パラメータ不足といった構造的に判定できるものはエラーとされますが
参照するパラメーターの存在などまではチェックしてくれません。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Parameters:
  NonUsedParam: # 利用していないパラメータを指定
    Type: String
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - !Ref hoge  #存在しないパラメータを指定
      Events:
        Montyly:
          Type: Schedule 
          Properties:
            Name: hogehoge
            #Schedule: cron(0 0 1 * ? *)  ## 必須パラメーター不足

この場合のvalidateの実行結果は以下となります。

$ sam validate
2023-01-19 10:49:13 Loading policies from IAM...
2023-01-19 10:49:20 Finished loading policies from IAM.
Template provided at '/Users/xxxxxxxx/template.yaml' was invalid SAM Template.
Error: [InvalidResourceException('HelloWorldFunctionMontyly', "Missing required property 'Schedule'.")] ('HelloWorldFunctionMontyly', "Missing required property 'Schedule'.")

構造的に明らかに足りないScheduleの有無判定までは行ってくれています。

しかしScheduleのコメントアウトを解除すると!Ref hogeの元となるパラメータが存在しないにもかかわらずチェックは通ります。

% sam validate
2023-01-19 10:53:49 Loading policies from IAM...
2023-01-19 10:53:56 Finished loading policies from IAM.
/Users/xxxx/template.yaml is a valid SAM Template. This is according to basic SAM Validation, for additional validation, please run with "--lint" option

現在のバージョンでは--lintの存在はチェック後のメッセージで示唆されるようになっているようです。優しい。

--lintを利用したチェック

--lintを付与してチェックをしてみます。

$ sam validate --lint
E0001 Error transforming template: Resource with id [HelloWorldFunctionMontyly] is invalid. Missing required property 'Schedule'.
/Users/xxxxx/template.yaml:1:1

...構造的なチェックで引っかかるとそれ以外のエラーが出ないのでコメントアウトは外して実行しましょう。
この時点でもメッセージがcfn-lintのものになってるのがわかります。

$ sam validate --lint
W2001 Parameter NonUsedParam not used.
/Users/xxxxx/template.yaml:5:3

E1012 Ref hogehoge not found as a resource or parameter
/Users/xxxxx/template.yaml:15:11

cfn-lint同様にパラメーター系のチェックまで行われ出力されるようになりました。

また実はこちらの方が嬉しいのですが--lintで呼び出すことで実行時にIAMの権限が不要になります。

これまでのvalidateではaws configureでデフォルトのユーザにMFAが設定されている等で
権限が不足している場合チェック前にエラーとなっておりました。

$ sam validate
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the ListPolicies operation: User: arn:aws:iam::xxxxx:user/xxxxxx is not authorized to perform: iam:ListPolicies on resource: policy path / with an explicit deny in an identity-based policy

これがcfn-lint経由となることでprofileを指定したリ別途アクセスキーを発行せずとも実行できるようになります。
ちょっとだけ直してチェックの時にありがたいです。

ちなみにざっと見とはなりますがcfn-lint相当のものが独自で実装されているわけではなく
本当にcfn-lintを呼び出しているようです。
https://github.com/aws/aws-sam-cli/pull/4556/files#diff-b2bbfce852be5285658199f5081d96c27de030f402fd4a70a19c466bb64d2a73R110

終わりに

今回のアップデートでSAM CLIの機能として(といっていいのかは微妙ですが)テンプレートのチェック機能が強化されました。

現時点ではcfn-lintを別に呼び出せばといってしまえばそこまでみたいなところはありますが、
個人的にSAMを使っている中でsamコマンドを読んでいる合間に別のコマンドを呼び出す必要が減ったというのが
作業中の脳的には優しく嬉しいアップデートです。

またSAMの処理の一連として実行できるようになったことでプラスアルファの処理をSAM CLIとして実行できるようになる部分ではありますので
まだまだ今後に期待の部分でもあるかと思います。