🕶️
Lambda Function URLsをCloudFormationとCDKでデプロイする
やったこと
- Lambda関数URLsをCfnでデプロイ
- Lambda関数URLsをCDKでデプロイ
やってないこと
- Lambda関数URLsでできること/できないことを試したりは、していません
Lambda Function URLsとは
CloudFormation
ymlファイル
lambda_function_url_demo.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: "Lambda Function Url sample"
Resources:
LambdaTestFunction:
Type: 'AWS::Lambda::Function'
Properties:
Code:
ZipFile:
Fn::Sub: |
exports.handler = async (event, context) => {
console.log('Event= ' + JSON.stringify(event));
const query_string = event.rawQueryString;
const response = {
statusCode: 200,
body: JSON.stringify({
hello: 'Hello from Lambda Function Urls!',
message: query_string
})
};
return response;
};
Description: Lambda function return message
FunctionName: LambdaFunctionUrlsTest
Handler: index.handler
Role: !GetAtt "LambdaFunctionUrlIAMRole.Arn"
Runtime: nodejs16.x
LambdaTestFunctionUrl:
Type: AWS::Lambda::Url
Properties:
AuthType: NONE
TargetFunctionArn: !Ref LambdaTestFunction
permissionForURLInvoke:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref LambdaTestFunction
FunctionUrlAuthType: 'NONE'
Action: lambda:InvokeFunctionUrl
Principal: '*'
LambdaFunctionUrlIAMRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "sts:AssumeRole"
Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Policies:
- PolicyName: CloudWatchLogsPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- "logs:*"
Resource: !Sub "arn:${AWS::Partition}:logs:*:*:*"
使い方
- 上記を保存してCloudFormationでデプロイしてくだい
- 作られたLambda関数のページで、Function URLを調べます
- ``https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld`という風にしてブラウザで開きます。こんな風に表示されるはずです。
{"hello":"Hello from Lambda Function Urls!","message":"message=HelloWorld"}
メモなど
- LambdaのCfnから、
Type: AWS::Lambda::Url
とType: AWS::Lambda::Permission
(リソースポリシー)を追加すればよい -
permissionForURLInvoke
でFunctionUrlAuthType: 'NONE'
を書き忘れてデプロイしたら、This policy could enable public access to your lambda function as it allows all Principals (*) to perform lambda:InvokeFunctionUrl action. You must specify lambda:FunctionUrlAuthType condition if intend to enable public access
というエラー。この公式docのPublic Function URL Invokeのところにきちんと書いてありました。 - GETでの呼び出しのパラメータとして
https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld
ということが紹介されていますが、event.rawQueryString
がそのままmessage=HelloWorld
として返ります。(message=
はなくてもいいかも) - TODO:アクセスをPublicにしていて、URLが漏れてDoS攻撃を受けたらどうなるのかが気になる。
CDK
minimum working example
lib/lambda-urls.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class CdkLambdaUrlStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const fn = new lambda.Function(this, 'HelloLambdaHandler', {
runtime: lambda.Runtime.PYTHON_3_9,
code: lambda.Code.fromAsset('lambda'),
handler: 'my_lambda.handler',
});
const fnUrl = fn.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
});
}
}
lambda/my_lambda.py
import json
def handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
使い方
-
cdk init app --language=typescript
でスタートして、上記2ファイルだけ変えています - CDKだと、
addFunctionUrl
するときにPermissionも自動で設定してくれて便利です。
まとめ感想
- AWS Lambda Function URLsを実装したかったので、CloudFormationとCDKでやってみました
- やっぱりCDKが便利
注意
- リソースの削除をお忘れなく
Discussion