AWS CDK(TypeScript)で作成済みのLambda@EdgeをCloudFrontに設定する

AWS CDKでCloudFrontへ作成済みのLambda@Edgeを設定する方法をまとめました。

CloudFormationの場合

CloudFormationであれば、ARNとVersionをParametersで受け取ってそのままRefすればOKです。

Parameters:
  OriginDomain:
    Description: website url
    Type: String
  OriginRequestFunctionARN:
    Description: Lambda edge arn ( Origin Request )
    Type: String
  OriginRequestFunctionVersion:
    Description: Lambda edge version ( Origin Request )
    Type: String

Resources:
  Distribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
        - DomainName: !Ref OriginDomain
          Id: myOrigin
          CustomOriginConfig: 
            HTTPPort: '80'
            HTTPSPort: '443'
            OriginProtocolPolicy: http-only
        Enabled: 'true'
        Comment: 
          !Join
           - ''
           - - rabify CDN (
             - !Ref OriginDomain
             - )
        DefaultRootObject: !Ref DefaultRootObject
        CacheBehaviors:
          - TargetOriginId: myOrigin
            LambdaFunctionAssociations:
              - EventType: 'origin-request'
                LambdaFunctionARN: 
                  !Join 
                    - ':'
                    - - !Ref OriginRequestFunctionARN
                      - !Ref OriginRequestFunctionVersion
...

AWS CDKではlambda.Versionインスタンス化しないとだめ

AWS CDKの場合、LambdaFunctionAssociationsで受け取る値の型がlambda.IVersion のため、同じ書き方では動きません。

export interface LambdaFunctionAssociation {
    /**
     * The lambda event type defines at which event the lambda
     * is called during the request lifecycle
     */
    readonly eventType: LambdaEdgeEventType;
    /**
     * A version of the lambda to associate
     */
    readonly lambdaFunction: lambda.IVersion;
}

以下の例のようにlambda.Version インスタンス化してやりましょう。

import * as cdk from '@aws-cdk/core';
import { Version } from '@aws-cdk/aws-lambda';
import {
  CloudFrontWebDistribution,
  LambdaFunctionAssociation,
  LambdaEdgeEventType
} from '@aws-cdk/aws-cloudfront';

export class CfStackStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // CFN Parameters
    const originDomain = new cdk.CfnParameter(this, 'OriginDomain', {
      type: 'String',
      description: 'Website url'
    })
    const originRequestFunctionARN = new cdk.CfnParameter(this, 'OriginRequestFunctionARN', {
      type: 'string',
      description: 'Lambda edge arn ( Origin Request )',
    })
    const originRequestFunctionVersion = new cdk.CfnParameter(this, 'OriginRequestFunctionVersion', {
      type: 'string',
      description: 'Lambda version',
    })

    // Function
    const edgeOriginRequest = Version.fromVersionArn(this, 'OriginRequestVersion', [
      originRequestFunctionARN.valueAsString,
      originRequestFunctionVersion.valueAsString
    ].join(':'))

    // Associations
    const lambdaFunctionAssociations: LambdaFunctionAssociation[] = [{
      eventType: LambdaEdgeEventType.ORIGIN_REQUEST,
      lambdaFunction: edgeOriginRequest,
    }]

    // CloudFront
    new CloudFrontWebDistribution(this, 'CloudFront', {
      originConfigs: [{
        customOriginSource: {
          domainName: originDomain.valueAsString,
          originProtocolPolicy: OriginProtocolPolicy.MATCH_VIEWER,
          originReadTimeout: Duration.seconds(30)
        },
        behaviors: [{
          compress: true,
          minTtl: Duration.seconds(43200),
          pathPattern: '*.jpg',
          forwardedValues: {
            headers: ['Authorization', 'Host'],
            queryString: true,
            queryStringCacheKeys: ['d', 'v'],
            cookies: {
              forward: 'none'
            }
          },
          allowedMethods: CloudFrontAllowedMethods.GET_HEAD,
          cachedMethods: CloudFrontAllowedCachedMethods.GET_HEAD,
          lambdaFunctionAssociations
...

cdk synthすると同じ結果になっていることがわかります。

            LambdaFunctionAssociations:
              - EventType: origin-request
                LambdaFunctionARN:
                  Fn::Join:
                    - ""
                    - - Ref: OriginRequestFunctionARN
                      - ":"
                      - Ref: OriginRequestFunctionVersion

Conclusion

Version.fromVersionArnの第三引数にLambdaのARN+Versionを渡してやることで作成済みのLambda@EdgeをCloudFrontに設定することができます。

fromXXXARNというスタティックメソッド、随所に仕込まれてますので既存のリソースを連携させたい時はまずこれを探すと良いでしょう。

Comment