taskcatでクロススタック参照のAWS CloudFormationテンプレートをテストする

記事タイトルとURLをコピーする

クラウドインテグレーション2部の水本です。

最近は「テスト」がマイブームでして、プログラムだとpytestやmockerについて調べつつSlack-botを作ってみる、なんてことをやったりしてました。
その中で「IaC、特に弊社でよく使うAWS CloudFormation(以下、CloudFormation)のテストってどうするのか?」に疑問を抱き、調べてみたところtaskcatに出会ったので、これを触り始めています。

taskcatとは?

taskcatはAWSが開発している、CloudFormationのテストツールです。
CloudFormationのテストを自動化してCI/CDパイプラインに組み込むことができるほか、デプロイ先のリージョンを複数指定して一斉実行なども可能です。
テストが終わった後は自動でStackを削除してくれるので、利用料が大きく跳ね上がる心配もありません。

github.com

最近困った事

私がよくCloudFormationテンプレートを作成する場合、クロススタック参照を前提にします。
いわゆる、「VPCのIDはOutputsに記述しておいて、他のStackから呼び出せるように」という実装です。
しかしながら、どうやらtaskcatはテストデプロイを順序づけて実行はしてくれず一斉実行してしまうようで、実際に複数テスト定義を書いてtaskcat test runを実行するとVPCのStack作成完了前にセキュリティグループのStackテストが始まり、エラー終了してしまいます。。。

対処

ここで語らずとも思い浮かぶ人はいると思いますが、スタックをネスト構造にすることで解決します。
テストするためのテンプレートを別で作り、それをテスト実行するだけです。

AWSTemplateFormatVersion: "2010-09-09"
Description: root stack template

Parameters:
  TemplateVPC:
    Description: VPC template URL(https://)
    Type: String

  TemplateSG:
    Description: SG template URL(https://)
    Type: String

Resources:
  VPC:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Ref TemplateVPC

  SG:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: !Ref TemplateSG
    DependsOn: VPC

taskcat側のconfig(.taskcat.yml)は以下のように記述します。
東京リージョンに対してテストを実行するものです。
各種「子テンプレート」のURLは確定しない(バケットにランダム値がセットされる)ので、taskcatが提供しているPsuedoパラメータで置換します。

project:
  name: my-project
  package_lambda: false
  regions:
    - ap-northeast-1
tests:
  root:
    template: ./templates/root.yaml
    parameters:
      TemplateVPC: https://s3.amazonaws.com/$[taskcat_autobucket]/$[taskcat_project_name]/templates/1_network.yaml
      TemplateSG: https://s3.amazonaws.com/$[taskcat_autobucket]/$[taskcat_project_name]/templates/2_sg.yaml

今回はローカルにtemplatesというディレクトリを作って、そこに各種テンプレートを配置しました。
このディレクトリは私が指定して作ったものです。
taskcatは実行するとS3バケットを作成し、上記のconfigと同一階層より下のファイル全てが階層そのままにアップされます。
configの配置場所には注意してください。 taskcat clean [projectname]でS3ごと消すことも可能です。

実際に実行してみる

では、実際に実行してみます。
taskcatがNested Stackを認識して、メッセージもちゃんと変更してくれます。
最高ですね。

❯ taskcat test run
 _            _             _
| |_ __ _ ___| | _____ __ _| |_
| __/ _` / __| |/ / __/ _` | __|
| || (_| \__ \   < (_| (_| | |_
 \__\__,_|___/_|\_\___\__,_|\__|



version 0.9.33
[INFO   ] : Linting passed for file: /Users/owner/development/hogehoge/templates/root.yaml
[S3: -> ] s3://tcat-my-project-g4z232nm/my-project/templates/2_sg.yaml
[S3: -> ] s3://tcat-my-project-g4z232nm/my-project/templates/1_network.yaml
[S3: -> ] s3://tcat-my-project-g4z232nm/my-project/templates/root.yaml
[INFO   ] : ┏ stack Ⓜ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411
[INFO   ] : ┣ stack Ⓝ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411-VPC-1T8ULTULOWBA2
[INFO   ] : ┣ stack Ⓝ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411-SG-WZA5XVINJTAE 
[INFO   ] : ┣ region: ap-northeast-1
[INFO   ] : ┗ status: CREATE_COMPLETE
[INFO   ] : Reporting on arn:aws:cloudformation:ap-northeast-1:123412341234:stack/tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411/6ee7d2a0-68b1-11ed-b69f-0e787f1b4501
[INFO   ] : Deleting stack: arn:aws:cloudformation:ap-northeast-1:123412341234:stack/tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411/6ee7d2a0-68b1-11ed-b69f-0e787f1b4501
[INFO   ] : ┏ stack Ⓜ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411
[INFO   ] : ┣ stack Ⓝ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411-VPC-1T8ULTULOWBA2
[INFO   ] : ┣ stack Ⓝ tCaT-my-project-root-cd0a4d60aa0a4c4cbad5d197d01ba411-SG-WZA5XVINJTAE  
[INFO   ] : ┣ region: ap-northeast-1
[INFO   ] : ┗ status: DELETE_COMPLETE

2022.11.26 追記

taskcatにはLambdaコードをパッケージ化する機能があり、これがDockerを暗黙的に求めるようです。

[ERROR  ] : DockerException Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

CIに組み込むなどの場合に面倒なので、今回のサンプルには当該の機能を使わない指示( package_lambda: false )を追記しました。

2022.12.01 追記

taskcatはテストで作ったテンプレートS3格納バケットを削除しません。
必要な場合は以下のように削除処理をCIなどに組み込んでください。

aws s3 ls | awk '{print $3}' | grep "^tcat" | xargs -I {} aws s3 rb s3://{} --force

まとめ

taskcatでは複数リージョンのデプロイ試験ができる以外にも、Nested Stack、クロススタック参照でもテストができます。
皆様、良いテストライフを。

水本 正敏(執筆記事の一覧)

エンタープライズクラウド部 ソリューションアーキテクト1課

国内ITベンダーのカスタマーエンジニアからAWSに魅了されサーバーワークスへ。