如何使用 CLI 在云前端分配中更新lambda@edge ARN



我想使用 CLI 使用最新的 lambda@edge 函数更新 cloudfront 发行版。

我看到了这个文档,但无法弄清楚如何仅更新 lambda ARN。

有人可以帮忙吗?

这是脚本,正是这样做的。它是根据@cloudbud答案实现的。没有参数检查。它将像这样执行:./script QF234ASD342FG my-lambda-at-edge-function us-east-1.就我而言,执行时间不到 10 秒。有关详细信息,请参阅更新分发。

#!/bin/bash
set -xeuo pipefail
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
distribution_id="$1"
function_name="$2"
region="$3"
readonly lambda_arn=$(
aws lambda list-versions-by-function 
--function-name "$function_name" 
--region "$region" 
--query "max_by(Versions, &to_number(to_number(Version) || '0'))" 
| jq -r '.FunctionArn'
)
readonly tmp1=$(mktemp)
readonly tmp2=$(mktemp)
aws cloudfront get-distribution-config 
--id "$distribution_id" 
> "$tmp1"
readonly etag=$(jq -r '.ETag' < "$tmp1")
cat "$tmp1" 
| jq '(.DistributionConfig.CacheBehaviors.Items[] | select(.PathPattern=="dist/sxf/*") | .LambdaFunctionAssociations.Items[] | select(.EventType=="origin-request") | .LambdaFunctionARN ) |= "'"$lambda_arn"'"' 
| jq '.DistributionConfig' 
> "$tmp2"
# the dist config has to be in the file
# and be referred in specific way.
aws cloudfront update-distribution 
--id "$distribution_id" 
--distribution-config "file://$tmp2" 
--if-match "$etag"
rm -f "$tmp1" "$tmp2"

无法弄清楚如何仅更新lambda arn。

您提供的链接说明了该过程:

更新

过程包括获取当前分发配置、更新返回的 XML 文档以进行更改,然后提交 UpdateDistribution 请求以进行更新

这意味着您不能直接更新 lambda arn。你有:

  1. 调用 get-distribution-config 以获取完整的当前配置。

  2. 更改获取的配置数据中的 lambda arn。

  3. 使用更新分发上传整个新配置。

该过程需要特别注意,这也在警告下的文档中进行了说明:

必须删除返回的 ETag 参数。

更新分配时需要其他字段

等等。

这个过程确实很复杂。因此,如果可以的话,我建议您在某些测试/虚拟CloudFront 发行版上尝试此操作,而不是直接在生产版本上尝试此操作。

像这样:

#!/bin/bash
set -x
TEMPDIR=$(mktemp -d)
CONFIG=$(aws cloudfront get-distribution-config --id CGSKSKLSLSM)
ETAG=$(echo "${CONFIG}" | jq -r '.ETag')
echo "${CONFIG}" | jq '.DistributionConfig' > ${TEMPDIR}/orig.json
echo "${CONFIG}" | jq '.DistributionConfig | .DefaultCacheBehavior.LambdaFunctionAssociations.Items[0].LambdaFunctionARN= "arn:aws:lambda:us-east-1:xxxxx:function:test-func:3"' > ${TEMPDIR}/updated.json
aws cloudfront update-distribution --id CGSKSKLSLSM --distribution-config file://${TEMPDIR}/updated.json --if-match "${ETAG}"

如果你需要一个 Jenkins 工作来做到这一点,我最终得到了以下内容

#!groovy
def functionName = "<insert yours here>"
def versions = []
pipeline {
stages {
stage('Resolve lambda versions') {
steps {
script {
withAWS(role: "${JENKINS_ROLE}", roleAccount: "${AWS_ACCOUNT}", region: "us-east-1") {
versions = sh(returnStdout: true, script: "aws lambda list-versions-by-function " +
"--function-name ${functionName} --query 'Versions[].Version' --output text").replaceAll('\$LATEST', "")
.trim()
.split("t")
.collect { it as int }
.sort()
.reverse()
echo "Versions found ${versions}"
}
}
}
}
stage('Update CloudFront distribution') {
steps {
script {
withAWS(role: "${JENKINS_ROLE}", roleAccount: "${AWS_ACCOUNT}", region: "us-east-1") {
def distributionId = "<insert yours here>"
def config = UUID.randomUUID().toString()
def distributionConfig = UUID.randomUUID().toString()
sh "aws cloudfront get-distribution-config --id ${distributionId} > ${config}"
def etag = sh(returnStdout: true, script: "cat ${config} | jq -r .ETag").trim()
sh """
sed -i 's/\("LambdaFunctionARN": ".*:${functionName}:\)[^:]*"/\1${versions.first()}"/' ${config}
"""
sh "cat ${config} | jq -r '.DistributionConfig' > ${distributionConfig}"
sh "aws cloudfront update-distribution --id ${distributionId} --if-match ${etag} --distribution-config file://${distributionConfig}"
}
}
}
}
stage('Remove old lambda versions') {
steps {
script {
withAWS(role: "${JENKINS_ROLE}", roleAccount: "${AWS_ACCOUNT}", region: "us-east-1") {
if (versions.size() < 3) {
echo "Not deleting any versions!"
} else {
versions[2..-1].each { version ->
sh "aws lambda delete-function --function-name ${functionName}:${version}"
}
}
}
}
}
}
}
}

最后阶段是可选的,但通常最好不要堆积较旧的 lambda 版本

最新更新