こんにちは!SRE2課の篠﨑です。
Cloudformation Guardご存じですか?私は知らなかったです。。。
本日、Build AWS Config rules using AWS CloudFormation Guardというアップデートを見て、気になったので簡単にやってみました。
こんな機能あるんだぁと思ってもらえたらと思います!
Cloudformation Guardとは?
ざっくりですが、作成したCloudFormationテンプレートがコンプライアンスに沿って作成されているかチェックするツールで、テンプレートを作成する端末にインストールをして利用することができます。
例えば、ルールとしてS3バケットは暗号化しないといけないというものがあった場合、CloudFormation Guardに記載します。 CloudFormation Guardで作成したS3用のCloudFormationがそのルールに沿っているかをチェックすることができます。
やってみた
概要を書いてみましたが、やってみた方が早いかなと思いますので、やってみました!
実行環境は Amazon Linux2ですが、WindowsやmacOSなども対応していますので、興味のある方はぜひやってみてください。
CloudFormation Guardのインストール
インストール方法はこちらです
Amazon Linux2で実行したコマンドは以下の通りです。
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh
その後、公式ドキュメントでは以下のようにPATHを編集するようになっていますが、このようにするとcfn-guard以外のコマンドが打てなくなりますので、ご注意ください。
PATH=~/.guard/bin/
今回は~/.bash_profileに追記をし、再起動します。
echo 'export PATH="$HOME/.guard/bin:$PATH"' >> ~/.bash_profile sudo reboot
ルールの作成
どのようにルールを記載するのか、イメージを持ってもらうためCloudFormationからルールを作成します。
初めに以下のようなテンプレートファイルを作成します。 今回は、sample-s3.yamlというファイル名で保存しました。
Resources: S3Bucket: Type: "AWS::S3::Bucket" Properties: BucketName: "MyServiceS3Bucket" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: 'aws:kms' KMSMasterKeyID: 'arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400' Tags: - Key: "stage" Value: "prod" - Key: "service" Value: "myService"
次に、このテンプレートからルーツの抽出をして、test.guardというファイルに出力します。
cfn-guard rulegen --template sample-s3.yaml --output test.guard
test.guardは次のようになっていました。
let aws_s3_bucket_resources = Resources.*[ Type == 'AWS::S3::Bucket' ] rule aws_s3_bucket when %aws_s3_bucket_resources !empty { %aws_s3_bucket_resources.Properties.Tags == [{"Key":"stage","Value":"prod"},{"Key":"service","Value":"myService"}] %aws_s3_bucket_resources.Properties.BucketName == "MyServiceS3Bucket" %aws_s3_bucket_resources.Properties.BucketEncryption == {"ServerSideEncryptionConfiguration":[{"ServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400"}}]}
よく見ると、暗号化についてや、タグの設定、バケット名についてのルールが作成されました。 バケット名はすべてのAWSアカウントでユニークである必要があるため、バケット名はルールから削除します。
ルールに準拠しているかのチェック
次に、作成したルールにテンプレートが準拠しているかのチェックを行います。
$ cfn-guard validate --data sample-s3.yaml --output-format yaml --rules test.guard --show-summary all Other sample-s3.yaml Status = PASS PASS rules output.guard/aws_s3_bucket PASS --- --- name: "" metadata: {} status: PASS not_compliant: [] not_applicable: [] compliant: - aws_s3_bucket
抽出した元となっているテンプレートファイルをチェックしているのでPASSするのは当たり前ですね。
それでは、以下のように、SSEAlgorithmeの部分を変更します。
Resources: S3Bucket: Type: "AWS::S3::Bucket" Properties: BucketName: "MyServiceS3Bucket" BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: 'AES256' Tags: - Key: "stage" Value: "prod" - Key: "service" Value: "myService"
次に同じようにコマンドを打つとどうなるでしょうか。
$ cfn-guard validate --data sample-s3.yaml --output-format yaml --rules test.guard --show-summary all Other sample-s3.yaml Status = FAIL FAILED rules output.guard/aws_s3_bucket FAIL --- --- name: "" metadata: {} status: FAIL not_compliant: - Rule: name: aws_s3_bucket metadata: {} messages: custom_message: ~ error_message: ~ checks: - Clause: Binary: context: " %aws_s3_bucket_resources[*].Properties.BucketEncryption EQUALS {\"ServerSideEncryptionConfiguration\":[{\"ServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"aws:kms\",\"KMSMasterKeyID\":\"arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400\"}}]}" messages: custom_message: "" error_message: "Check was not compliant as property value [Path=/Resources/S3Bucket/Properties/BucketEncryption[L:7,C:40] Value={\"ServerSideEncryptionConfiguration\":[{\"ServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"AES256\"}}]}] not equal to value [Path=[L:0,C:0] Value={\"ServerSideEncryptionConfiguration\":[{\"ServerSideEncryptionByDefault\":{\"SSEAlgorithm\":\"aws:kms\",\"KMSMasterKeyID\":\"arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400\"}}]}]." check: Resolved: from: path: /Resources/S3Bucket/Properties/BucketEncryption value: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 to: path: "" value: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: "aws:kms" KMSMasterKeyID: "arn:aws:kms:us-east-1:123456789:key/056ea50b-1013-3907-8617-c93e474e400" comparison: - Eq - false not_applicable: [] compliant: []
すると、このようにルールに非準拠な箇所がFAILとして表示されました。
おわりに
今回はCloudFormation Guardについてインストールから実際に触ってみるところまでやってみました。
ドキュメントが日本語対応していないなど、少しとっつきにくいところはありますが、チーム単位で構築する際には利用してもいいかもしれないですね!
気になる方はぜひ触ってみてはいかがでしょうか!!
参考:
篠﨑 勇輔(書いた記事を見る)
クラウドインテグレーション部 SA1課