AWS lambda---以S3为源的cloudfront域自动过期方案

1. 创建一个s3桶my-test

2. 创建cloudfront域并使用自定义域名CNAME my-test.xxx.cn

由于中国区的cloudfront自定义域名无法使用Amazon Certificate Manager中免费的SSL证书,如果需要使用需要自行购买。

在源中使用上述创建的s3桶的域名。

3. 编写aws lambda

创建aws iam role

在iam中创建role lambda_cloudfront_create_invalidation 信任实体为lambda.amazonaws.com

role包含两个策略

aws 原生策略AWSLambdaVPCAccessExecutionRole

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "ec2:CreateNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:DeleteNetworkInterface",
                "ec2:AssignPrivateIpAddresses",
                "ec2:UnassignPrivateIpAddresses"
            ],
            "Resource": "*"
        }
    ]
}

自定义策略cloudfront-createInvalidation

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "cloudfront:CreateInvalidation",
            "Resource": "*"
        }
    ]
}

初始化python环境

pip install python-lambda
mkdir function_s3object_cloudfront_invalid
cd function_s3object_cloudfront_invalid
lambda init function_s3object_cloudfront_invalid

编辑function_s3object_cloudfront_invalid/config.yaml

region: cn-north-1

function_name: function_s3object_cloudfront_invalid
handler: service.handler
description: 当s3对象更新时候,将cloudfront的缓存失效
runtime: python3.8
# role 为上面创建的
role: lambda_cloudfront_create_invalidation

# S3 upload requires appropriate role with s3:PutObject permission
# (ex. basic_s3_upload), a destination bucket, and the key prefix
# bucket_name: 'example-bucket'
# s3_key_prefix: 'path/to/file/'

# if access key and secret are left blank, boto will use the credentials
# defined in the [default] section of ~/.aws/credentials.
aws_access_key_id:
aws_secret_access_key:

# dist_directory: dist
# timeout: 15
# memory_size: 512
# concurrency: 500
#

# Experimental Environment variables
#environment_variables:
#    env_1: foo
#    env_2: baz

# If `tags` is uncommented then tags will be set at creation or update
# time.  During an update all other tags will be removed except the tags
# listed here.

# Build options
build:
  source_directories: lib # a comma delimited list of directories in your project root that contains source to package.

编辑function_s3object_cloudfront_invalid/lib/setting.py

#!/usr/bin/env python
from pytz import timezone, utc
from datetime import datetime
import logging.config
import os

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple"
        },
    },
    "loggers": {
        "my_module": {
            "level": "INFO",
            "handlers": ["console"],
            "propagate": 0
        }
    },
}

logging.config.dictConfig(LOGGING)

def custom_time(*args):
    utc_dt = utc.localize(datetime.utcnow())
    my_tz = timezone("Asia/Shanghai")
    converted = utc_dt.astimezone(my_tz)
    return converted.timetuple()

logging.Formatter.converter = custom_time

CLOUDFRONT = {
		
    "my-test.xxx.cn": {cloudfront域的ID号,自行替换}
}

编辑function_s3object_cloudfront_invalid/service.py

# -*- coding: utf-8 -*-
import boto3
import logging
from lib import setting
import time

logger = logging.getLogger("my_module")

def s3_obj_info(event):
    s3_object_list = []
    records = event["Records"]
    s3_bucket = ""
    for record in records:
        s3_bucket = record["s3"]['bucket']['name']
        s3_obj = record["s3"]['object']['key']
        event_name = record["eventName"]
        logger.info(f"{event_name=},{s3_bucket=},{s3_obj=}")
        s3_object_list.append(s3_obj)

    paths = [f"/{i}" for i in s3_object_list]

    logger.info(f"需要失效的文件:{s3_bucket=},{paths=}")

    cf = boto3.client('cloudfront')
    distribution_id = setting.CLOUDFRONT[s3_bucket]
    quantity = len(paths)

    res = cf.create_invalidation(
        DistributionId=distribution_id,
        InvalidationBatch={
            'Paths': {
                'Quantity': quantity,
                'Items': paths
            },
            'CallerReference': str(time.time()).replace(".", "")
        }
    )
    invalidation_id = res['Invalidation']['Id']
    logger.info(f'创建失效完成:{invalidation_id=}')
    return invalidation_id

def handler(event, context):
    s3_obj_info(event)

编辑function_s3object_cloudfront_invalid/requirements.txt

boto3==1.18.21
pytz==2018.9

上传代码到aws lambda

lambda deploy --requirements  requirements.txt 

4. 设置S3桶的通知事件到lambda

事件类型

 

目标为刚刚上传的lambda

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值