こんにちは。ひるたんぬです。
最近は気温差が激しく、体調を崩しやすいですね。。私もこのビッグウェーブにしっかりと乗り、体調を崩しておりました。
そんなあるとき、ふと気になることがありました。
「なぜ、ティッシュは必ず二枚重ねなのか。。」と。
駅前で配っているポケットティッシュから保湿成分配合の高級ティッシュまで、必ずティッシュは二枚一組¹になっています。
気になって調べたところ、
- 紙には裏表があり、肌触りの良い面が必ず表面に来るようにするため
- 重ねることで空気の層ができ、柔らかさ・吸水性が向上する
などといった理由があるそうです。身の回りの不思議がまた一つ解決してスッキリしました。
下記リンクを参考にしたのですが、私は小学5年生と同じ疑問を抱いていたようです。
参考:朝日小学生新聞「ティッシュペーパーはなぜ2枚重ね? 4枚重ねは「贈り物」にも」
¹ 今日では3枚・4枚と重ねている商品もあるようです。
…さて、今回は私が個人的な要件でAWSで開発を進めるにあたって、必ずと言っていいほどお世話になっているAmazon CodeCatalystを使って、AWS CloudFormationのテンプレートを快適に作成する環境を考えてみましたのでご紹介いたします。
概要
今回は、CodeCatalystを使用して以下を満たす環境を構築することができます。
- CloudFormationテンプレートファイルのソースコード管理
➔ CodeCatalystの「Source repositories」を使用 - CloudFormationテンプレートのコーディング(実装)環境
➔ CodeCatalystの「Dev Environments」を使用 - CloudFormationテンプレートのテンプレートチェック
➔ CodeCatalystの「Workflows」を使用して各種テストを実行
上記の内最後の各種テストでは、yamlファイルの構文チェック・CloudFormationテンプレートの構文チェック・TaskCatを用いて実際にデプロイしてチェックという3つのチェックを実施します。
今回の実装にあたり、参考にさせていただいたサイトは最後にご紹介しております。
TaskCatとは?
TaskCatとはCloudFormationテンプレートのテストツールです。簡単なコマンドと設定ファイルで、複数のリージョンに対してデプロイのテストを実施可能です。また、テスト結果のレポートについてもHTML形式やテキストファイルにて生成してくれます。
調べてみたところ、有志の方が作成したのではなく、AWSのチーム(aws-ia)にて提供されているツールなんですね。。
TaskCatの公式サイトや開発チームのサイトは以下をご覧ください。
実装例
CodeCatalyst上の任意のスペースに、新規でプロジェクトを作成します。私は「TaskCat」というプロジェクトを作成しました。
本記事では以降の手順について解説します。
CloudFormationテンプレートファイルのソースコード管理
CodeCatalystのSource repositoriesを使用します。
今回はCodeCatalyst上で新規にリポジトリを作成します。
名前以外はデフォルトで設定しました。
. ├ cfn_template │ └ template.yaml ├ .cfnlintrc.yaml ├ .gitignore ├ .taskcat.yml ├ .yamllint.yaml ├ README.md └ junit_xml.py
それぞれのファイルは下記のように作成しました。
template.yaml
CloudFormationでデプロイしたいテンプレートファイルです。
今回は一例として以下のようなテンプレートファイルを作成しました。
--- AWSTemplateFormatVersion: "2010-09-09" Description: Sample CloudFormation Template Parameters: vpcIpv4CicdBlock: Type: String Default: 10.0.0.0/16 vpcNameTag: Type: String Resources: myVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref vpcIpv4CicdBlock EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Ref vpcNameTag Outputs: myVpcId: Description: VPC ID Value: !Ref myVPC Export: Name: myVpcId
.cfnlintrc.yaml
CloudFormationテンプレートの構文チェックを実施する「cfn-lint」の設定ファイルです。
--- templates: - cfn_template/*.yaml
.taskcat.yml
テンプレートをデプロイしてチェックする「TaskCat」の設定ファイルです。
デプロイ先のリージョンの情報やパラメータの値を指定することができます。
--- project: name: sample-taskcat-project regions: - ap-northeast-1 tests: test-my-vpc: parameters: vpcIpv4CicdBlock: 10.10.0.0/16 vpcNameTag: test-vpc template: cfn_template/template.yaml
.yamllint.yaml
YAMLファイルの構文チェックを実施する「yamllint」の設定ファイルです。
--- yaml-files: - '*.yaml' - '*.yml' - '.yamllint' rules: anchors: enable braces: enable brackets: enable colons: enable commas: enable comments: level: warning comments-indentation: level: warning document-end: disable document-start: level: warning empty-lines: enable empty-values: disable float-values: disable hyphens: enable indentation: enable key-duplicates: enable key-ordering: disable line-length: enable new-line-at-end-of-file: enable new-lines: enable octal-values: disable quoted-strings: disable trailing-spaces: enable truthy: level: warning
junit_xml.py
TaskCatのテスト結果(テキストファイル形式)をjunit形式に変換するためのPythonスクリプトです。
こちらは参考サイトよりそのまま使用させていただきました。
これを実施することにより、CodeCatalystのワークフロー上でテスト結果を簡単に確認することができます。
import sys import os import xml.etree.ElementTree as ET def convert_to_junit_xml(log): # Create the root element testsuite = ET.Element("testsuite") # Create a testsuite element testsuite = ET.SubElement(testsuite, "testsuite", name="taskcat-cnf-development") # Parse the log and create testcases lines = log.split("\n") success_count = 0 failure_count = 0 for line in lines: if "CREATE_COMPLETE" in line or "CREATE_FAILED" in line: date, time, resource_status, resource_type, logical_resource_id, *rest = line.split() if len(rest) >= 6: resource_status_reason = ' '.join(rest) else: resource_status_reason = "" testcase = ET.SubElement(testsuite, "testcase", classname=resource_type, name=logical_resource_id) if resource_status == "CREATE_COMPLETE": ET.SubElement(testcase, "success") success_count += 1 else: ET.SubElement(testcase, "failure", message=resource_status_reason) failure_count += 1 # Add summary information testsuite.set("tests", str(success_count + failure_count)) testsuite.set("failures", str(failure_count)) # Return the string representation of the XML return ET.tostring(testsuite, encoding="unicode") if __name__ == "__main__": # Check if the log file path is provided as a command line argument if len(sys.argv) < 2: print("Please provide the path to the log file as a command line argument.") sys.exit(1) # Read the log file log_file_path = sys.argv[1] with open(log_file_path, "r") as file: log = file.read() # Convert the log to JUnit XML format junit_xml = convert_to_junit_xml(log) print(junit_xml) # Save the XML as a file named "report.xml" in the same directory as the log file log_file_directory = os.path.dirname(log_file_path) report_file_path = os.path.join(log_file_directory, "report.xml") with open(report_file_path, "w") as file: file.write(junit_xml)
CloudFormationテンプレートのコーディング(実装)環境
CodeCatalystのDev Environmentsを使用します。
今回はVisual Studio Code上で操作可能な開発環境を設定します。
作成したリポジトリを取り込めるように設定します。
CloudFormationテンプレートのテンプレートチェック
CodeCatalystのWorkflowsを使用します。
ワークフローとしては非常にシンプルです。
mainブランチへのプルリクエストをトリガーにワークフローが動作するよう設定しました。
また、実際のワークフローのコード(YAMLファイル)を以下に示します。
今回は実行環境をLambdaではなくEC2で実行するようにします。
Name: CheckTemplate SchemaVersion: "1.0" # Optional - Set automatic triggers. Triggers: - Type: PULLREQUEST Branches: - main Events: - OPEN # Required - Define action configurations. Actions: TestTemplateTask: # Identifies the action. Do not modify this value. Identifier: aws/build@v1.0.0 # Specifies the source and/or artifacts to pass to the action as input. Inputs: # Optional Sources: - WorkflowSource # This specifies that the action requires this Workflow as a source Outputs: # Optional; Automatically discover reports for popular test frameworks AutoDiscoverReports: Enabled: true # Use as prefix for the report files ReportNamePrefix: rpt # Defines the action's properties. Configuration: # Required - Steps are sequential instructions that run shell commands Steps: - Run: pip install yamllint cfn-lint taskcat - Run: yamllint ./cfn_template - Run: cfn-lint - Run: taskcat test run - Run: report=`ls -rt taskcat_outputs/*.txt | tail -n 1` - Run: python3 junit_xml.py $report Container: Registry: CODECATALYST Image: CodeCatalystLinux_x86_64:2024_03 Compute: Type: EC2 Environment: Name: dev
実際に動かしてみた
では実際に開発→チェックまでの一連の流れを見てみましょう。
まずは、Dev EnvironmentsよりVisual Studio Codeの開発環境を起動します。
mainブランチより「dev」ブランチを作成し、その中で変更を実装していきます。
今回はAmazon Q Developerも活用してみます。
プロンプト入力画面を起動し、パブリックサブネットを追加してもらいましょう。
するとAmazon Qによりコードが生成されます。
パット見できていそうということで、変更を受け入れます。
devブランチに変更をプッシュします。
これにより、devブランチが作成され、その中にパブリックサブネットを追加したテンプレートファイルが配置されています。
次に、devブランチからmainブランチにプルリクエストを作成します。
CodeCatalystのPull requestsより新規で作成します。
プルリクエストのタイトルは自分で入力し、説明文はAmazonQに記載してもらいます。
「Write description for me」のボタンを押下します。すると、変更文が生成されます。
生成された説明文は以下のとおりです。
The code change defines a public subnet, internet gateway, route table, and associated resources in an AWS CloudFormation template. The public subnet allows internet access for resources deployed within it. This configuration enables internet connectivity for resources deployed in the public subnet.
パブリックサブネットが生成された旨がしっかりと表示されていますね。このまま「Accept and add to description」を押下します。
最終的に下の「Create」ボタンを押下します。これによりプルリクエストが作成されました。
プルリクエストが作成されると、ワークフローの動作が開始します。完了するまで気長に待ちましょう。
今回はyamllintのプロセスでエラーが発生しました。インデントがズレているというエラーですね。
コードを確認してみると、確かにズレていたため、修正しもう一度実行してみます。
今回はしっかりと実行できました。
また、「Reports」タブを押下することで、変換されたテストの結果を確認することができます。
追加の設定は行わず、「Merge」を押下します。
おわりに
今回はCodeCatalystを用いたCloudFormationテンプレートの開発環境をご紹介しました。
TaskCatのレポート機能などに課題は残っておりますが、個人的には割と使いやすいな…と感じた次第です。
TaskCat以外の部分の開発環境につきましては、CloudFormationテンプレートの開発以外にも活用できるので、改めてCodeCatalystの有用性を知ることができました。
Amazon Q Developerと一緒に開発できれば、一人の開発も怖くなさそうですね。。
もっと使いこなせるようになったらAmazon Q Developer Proも検討しようと思います。
参考サイト
今回は以下のサイトを参考にCodeCatalyst版のフローを作成しました。