はじめに
本記事では、AWS CDK (Cloud Development Kit) を使用して AWS Lambda 関数と AWS Step Functions ステートマシンを作成します。AWS CDKは、クラウドリソースを定義するためのオープンソースのソフトウェア開発フレームワークで、本記事では TypeScript を使用しています。
ディレクトリ構造
本プロジェクトのディレクトリ構造は以下の通りです:
.
├── bin
│ └── cdk_sfn.ts
├── cdk.json
├── jest.config.js
├── lambda
│ └── lambda_function.py
├── lib
│ └── cdk_sfn-stack.ts
├── node_modules
├── package.json
├── stepfunctions
│ └── asl.json
├── test
└── tsconfig.json
環境
本記事では以下のバージョンの AWS CDK を使用しています。
$ cdk version
2.80.0 (build bbdb16a)
Lambda 関数
デプロイする Lambda 関数は以下です。Python で記述しています。
import boto3
def update_cloudfront_distribution(event):
try:
distribution_id = event["distribution_id"]
new_acl_id = event["new_acl_id"]
except KeyError as e:
return {"statusCode": 400, "body": f"Missing key in event: {e}"}
client = boto3.client("cloudfront")
try:
dist_config_response = client.get_distribution_config(Id=distribution_id)
dist_config = dist_config_response["DistributionConfig"]
e_tag = dist_config_response["ETag"]
dist_config["WebACLId"] = new_acl_id
client.update_distribution(Id=distribution_id, IfMatch=e_tag, DistributionConfig=dist_config)
except Exception as e:
return {"statusCode": 500, "body": f"Failed to update distribution config: {e}"}
return {"statusCode": 200, "body": f"Updated WAF ACL for distribution {distribution_id} to {new_acl_id}"}
def lambda_handler(event, context):
print(event)
response = update_cloudfront_distribution(event)
return response
CDK のコード
以下に CDK のコードを示します。
- Lambda のコードで CloudFront や WAF に操作を行っているため、
- Escape Hatch を利用して、既存のASLを使用してステートマシンを作成します。Escape Hatch を使用することで、低レベルの CloudFormation リソースを直接操作することが可能になります。
import * as cdk from 'aws-cdk-lib';
import { ManagedPolicy, Role, IRole, ServicePrincipal } from "aws-cdk-lib/aws-iam";
import { Code, Function, Runtime } from "aws-cdk-lib/aws-lambda";
import { CfnStateMachine, Pass, StateMachine } from 'aws-cdk-lib/aws-stepfunctions';
import * as fs from 'fs';
const POLICY_ARN_WAF = "arn:aws:iam::aws:policy/AWSWAFFullAccess";
const POLICY_ARN_LAMBDA = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole";
const POLICY_ARN_CLOUDFRONT = "arn:aws:iam::aws:policy/CloudFrontFullAccess";
export class CdkSfnStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const environment = this.node.tryGetContext('environment')
const contextValues = this.node.tryGetContext(environment)
const stepFunctionFile = fs.readFileSync(`./stepfunctions/asl.json`)
const lambdaRole = this.createLambdaRole();
const lambdaFunction = this.createLambdaFunction(lambdaRole);
const commonRole = Role.fromRoleArn(this, 'CommonRole', `arn:aws:iam::${contextValues['account']}:role/stepfunctions-common-role`);
this.createStateMachine(stepFunctionFile, commonRole);
}
private createLambdaRole(): Role {
return new Role(this, "lambdaRole", {
assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
managedPolicies: [
ManagedPolicy.fromManagedPolicyArn(this, "wafPolicy", POLICY_ARN_WAF),
ManagedPolicy.fromManagedPolicyArn(this, "lambdaPolicy", POLICY_ARN_LAMBDA),
ManagedPolicy.fromManagedPolicyArn(this, "cloudfrontPolicy", POLICY_ARN_CLOUDFRONT),
],
description: "Basic Lambda Role",
});
}
private createLambdaFunction(lambdaRole: Role): Function {
return new Function(this, "python-function", {
functionName: "switch_acl",
runtime: Runtime.PYTHON_3_9,
code: Code.fromAsset("lambda"),
handler: "lambda_function.lambda_handler",
role: lambdaRole,
timeout: cdk.Duration.seconds(30)
});
}
private createStateMachine(stepFunctionFile: Buffer, commonRole: IRole): StateMachine {
const stateMachine = new StateMachine(this, 'MyStateMachine', {
definition: new Pass(this, 'StartState'),
role: commonRole,
stateMachineName: "SwitchWafAcl"
});
const cfnStateMachine = stateMachine.node.defaultChild as CfnStateMachine;
cfnStateMachine.definitionString = stepFunctionFile.toString();
return stateMachine;
}
}
おわりに
本記事では、AWS CDK を使用して AWS Lambda 関数と AWS Step Functions ステートマシンを作成する方法を説明しました。AWS CDK を使用することで、クラウドリソースのプロビジョニングを自動化し、繰り返し可能で信頼性の高い方法で行うことが可能です。
この記事がどなたかの参考になれば幸いです。
コメント