簡體   English   中英

CDK:將源/行為添加到現有 CloudFront 分配

[英]CDK: Add origin/behavior to existing CloudFront distribution

我們有一個 CF 分布,用於緩存來自 MediaPackage 的響應。 我們有多個 MediaPackage 端點,對於每個端點,在同一個 CF 分布上都有一個對應的起源/行為。

使用 CDK 我們如何在現有的 CF 發行版上添加新的起源/行為?。 我在下面嘗試但遇到了錯誤:

        // load existing distribution
        const distribution = Distribution.fromDistributionAttributes(scope, `${props.stackName}-Distribution`, {
            distributionId: 'E33333B',
            domainName: 'test.example.com'
        }) as Distribution;

        // Convert to CfnDistribution
        const distributionLive = distribution.node.defaultChild as CfnDistribution;
        const distributionConfig =
            distributionLive.distributionConfig as CfnDistribution.DistributionConfigProperty;
        
        // Fetch origin/behaviors list
        const cacheBehaviors = distributionConfig.cacheBehaviors as CfnDistribution.CacheBehaviorProperty[];
        const origins = distributionConfig.origins as CfnDistribution.OriginProperty[];

       // Add new origin/behavior
       origins.push({..})
       cacheBehaviors.push({..})

錯誤:

/dist/lib/resources/cloudfront.js:95
        const distConfig = distributionLive.distributionConfig;
                                                   ^

TypeError: Cannot read property 'distributionConfig' of undefined

很容易完成,這里有一個例子

https://kuchbhilearning.blogspot.com/2022/10/add-cloudfront-behavior-and-origin.html

我們需要使用addBehavior分發公開的 addBehavior 方法。 將模式和來源傳遞給此行為。

您可以創建一個 lambda function 來更新 CF 分發以添加新行為。 然后創建自定義 AWS 資源以在創建/更新時調用此 lambda function,如下所示 -

#lambda function code to be saved in lambda_codes/update_cf/update_distribution.py

import boto3
import os

client = boto3.client('cloudfront')

def lambda_handler(event,context):
    responseData={}
    try:
        if (event['RequestType'] == 'Create') or (event['RequestType'] == 'Update'):
            config_res = client.get_distribution_config(Id=event['ResourceProperties']["Id"])
            config_req = dict(config_res["DistributionConfig"])
            ETag = config_res["ETag"]
            LambdaFunctionARN = event['ResourceProperties']["LambdaFunctionARN"]
                
            LambdaFunctionAssociations = {
                            'Quantity': 1,
                            'Items': [{
                                'LambdaFunctionARN': LambdaFunctionARN,
                                'EventType': 'viewer-request',
                                'IncludeBody': False
                            }]
                        }
            CacheBehaviors= {}
            CacheBehaviors_Item=dict(config_req['DefaultCacheBehavior'])
            CacheBehaviors_Item['PathPattern'] ='/index.html'
            CacheBehaviors['Items'] = [CacheBehaviors_Item]
            CacheBehaviors['Items'][0]['LambdaFunctionAssociations'] = LambdaFunctionAssociations
            CacheBehaviors['Quantity'] = 1

            config_req['CacheBehaviors']=CacheBehaviors
            print(config_req)

            response = client.update_distribution(Id=event['ResourceProperties']["Id"],
                            IfMatch=ETag,
                            DistributionConfig=config_req)

            print("Response",response)
            responseData['Status'] = 'SUCCESS'
            print ('SUCCESS')
            return { "status" : responseData['Status'] }
        else:
            print("SUCCESS - operation not Create or Update, ResponseData=" + str(responseData))
            return { "status" : 'SUCCESS' }


    except Exception as e:
        responseData['Error'] = str(e)
        print("FAILED ERROR: " + responseData['Error'])

下面是在更新 CF lambda 和調用它的自定義資源之上創建的 python CDK 堆棧。

from constructs import Construct
import json
import os
import base64
from aws_cdk import (
    Duration,
    Stack,
    aws_iam as iam,
    aws_lambda as lambda_,

)


class InfraCodeStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        
        #Policy Statement for CF access
        cf_update_lambda_role_policy_statement = iam.PolicyDocument(
                    statements= [
                    iam.PolicyStatement(
                        effect = iam.Effect.ALLOW,
                        actions= [
                            "cloudfront:GetDistributionConfig",
                            "cloudfront:UpdateDistribution" 
                            ],
                        resources= ["*"],
                        )
                    ]
        )

        #Cf_Update lambda role
        cf_lambda_iamrole = iam.Role(
            self, "Cf_Update_Lambda_Role",
            role_name= "Cf_Update_Lambda_Role",
            assumed_by= iam.CompositePrincipal(iam.ServicePrincipal("lambda.amazonaws.com")),
            description= 'Role to allow lambda to update cloudfront config',
            inline_policies= {'CF_Update_lambda_Cloudfront_Policy':cf_update_lambda_role_policy_statement },
            managed_policies= [
            iam.ManagedPolicy.from_aws_managed_policy_name('service-role/AWSLambdaBasicExecutionRole')
            ]
        ) 

        #Cf_Update lambda function
        cf_update_lambda = lambda_.Function(self, "cf-update-lambda-dev",
                                        code=lambda_.Code.from_asset("lambda_codes/update_cf"),
                                        function_name="cf-update-lambda-dev",
                                        handler='update_distribution.lambda_handler',
                                        role=cf_lambda_iamrole,
                                        tracing=lambda_.Tracing.ACTIVE,
                                        runtime=lambda_.Runtime.PYTHON_3_9
                                        )

        cf_update_lambda.node.add_dependency(get_version)

        #Updating cloudfront via custom sdk call 
        input_event_to_cf_update_lambda = { 
            "RequestType" : "Update",
            "ResourceProperties" : { 
                                "Id" : cloudfront_object.distribution_id, ## your cloudfront object created in the stack's id
                                "LambdaFunctionARN" : function_arn,       ## lambda@edge arn to be attached to behavior
                                "AWSRegion": "us-east-1"
                                 }
            }
            
        
        def lambda_context(custom=None,env=None,client=None):
            client_context = dict(
                custom=custom,
                env=env,
                client=client)
            json_context = json.dumps(client_context).encode('utf-8')
            return base64.b64encode(json_context).decode('utf-8')

        context = {
            "custom": {},
            "env": {},
            "client": {}
            }
            
        cf_update_lambda_custom = cr.AwsCustomResource(self, "cf_update_lambda_custom",
                on_update=cr.AwsSdkCall( 
                        service="Lambda",
                        action="invoke",
                        parameters={ "FunctionName": cf_update_lambda.function_name,
                                    "InvocationType" : "RequestResponse",
                                    "LogType" : "Tail",
                                    "ClientContext" : lambda_context(**context),
                                    "Payload" : json.dumps(input_event_to_cf_update_lambda),
                                    },
                        physical_resource_id=cr.PhysicalResourceId.of("lambda_update_cf_custom_resource")
                        ),
                policy=cr.AwsCustomResourcePolicy.from_statements(
                        [ iam.PolicyStatement(
                            effect = iam.Effect.ALLOW,
                            actions= [
                                "lambda:InvokeAsync",
                                "lambda:InvokeFunction"                                                
                                ],
                            resources= ['*'],
                            )]
                    
                ),
                )
                
        cf_update_lambda_custom.node.add_dependency(cf_update_lambda)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM