0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CloudFormation Hookを使ってみた:自作Lambdaを利用する版

0
Last updated at Posted at 2026-10-24

はじめに

前回、CloudFormation Hookを試用してみました。

今回は自作Lambdaを使うケースを、簡単な例で作ってみました。

概要

今回は"S3の名前をチェックするCloudFormation Hook"を作ります。

  • Lambdaを作成
    • 権限は、Lambdaを実行するだけなので、CloudWatch Logsに出力するもののみです
      • 作成するS3名は、入力からとってこれます
  • CloudFormation Hookを作成
    • 権限は、先ほど作ったLambdaを実行するもののみです

参考

やってみた

Lambda作成

S3名をチェックするLambdaを作成します。今回は簡単に、"プレフィックスにsales|hr|infraが指定"されていることをチェックする関数にしました。
権限は、他リソースは呼び出さないので、最低限のログ出力のみです。

validate_s3_bucket_name
import json
import re


def validate_bucket_name(bucket_name):
    if not bucket_name:
        return False

    pattern = r"^(sales|hr|infra)-"

    return re.match(pattern, bucket_name) is not None


def lambda_handler(event, context):
    properties = event.get("requestData", {}).get("targetModel", {}).get("resourceProperties", {})
    bucket_name = properties.get("BucketName")

    print("BucketName:", bucket_name)

    if not validate_bucket_name(bucket_name):
        return {
            "hookStatus": "FAILED",
            "message": "Bucket name must start with 'sales-', 'hr-', or 'infra-'.",
            "clientRequestToken": event.get("clientRequestToken"),
            "errorCode": "NonCompliant"
        }

    return {
        "hookStatus": "SUCCESS",
        "message": "Bucket name passed validation.",
        "clientRequestToken": event.get("clientRequestToken")
    }

テストで使用した、想定される入力eventのJSONは以下になります。

event
{
  "awsAccountId": "123456789012",
  "stackId": "arn:aws:cloudformation:ap-northeast-1:123456789012:stack/TestStack/example-id",
  "changeSetId": null,
  "hookTypeName": "Company::S3::Naming",
  "hookTypeVersion": "00000001",
  "hookModel": {
    "LambdaFunction": "arn:aws:lambda:ap-northeast-1:123456789012:function:CheckS3BucketName"
  },
  "actionInvocationPoint": "CREATE_PRE_PROVISION",
  "requestData": {
    "targetName": "AWS::S3::Bucket",
    "targetType": "AWS::S3::Bucket",
    "targetLogicalId": "TestBucket",
    "targetModel": {
      "resourceProperties": {
        "BucketName": "hr-acme-dev-test-12345"
      },
      "previousResourceProperties": {}
    }
  },
  "requestContext": {
    "invocation": 1,
    "callbackContext": null
  },
  "clientRequestToken": "local-test-token"
}


Pythonをローカルでチェックした際、以下のコードを入れて行いました。先のeventは同ディレクトリにevent.jsonというファイルで保存しておきます。

def main():
    with open("event.json", "r", encoding="utf-8") as file:
        event = json.load(file)

    result = lambda_handler(event, None)

    print("=== result ===")
    print(json.dumps(result, indent=2, ensure_ascii=False))


if __name__ == "__main__":
    main()

CloudFormation Hookを作成

先に作ったLambdaを使うCloudFormation Hookを作ります。

コンソールから Lambdaを利用 を選択します。
image.png

設定は以下のようにしました。
image.png

初めて作るので、専用の新しいロールを作ります。
image.png

今回の環境では、デフォルトロールを作成を選択すると先に進ませんでした。他の指定項目が問題なくても動かず、ここだけ別のロールを使用にしたら通るようになりました。エラーにもなりませんでしたので、注意ください。

専用のロールを作るため、設定値を埋めていきます。
image.png
Hookの名前も指定して、専用のロールにできます。
image.png
image.png

正常に作成されました。
image.png

モードを変更しつつ、実行を確認してみました。正常に動いているようです。
image.png

おわりに

今回はチェックに自作Lambdaを使ったCloudFormation Hookを作ってみました。
組織独自のチェックが必要なケースもあるかと思います、そういった際を想定して記事を作成してみました。
この記事がどなたかのお役に立てれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?