こんにちは!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課