是否可以通过 AWS CLI 从 Origin 找到云端分布?

Is it possible to find cloudfront distributions from Origin via AWS CLI?

我有多个 Cloudfront 分布指向单个 S3 存储桶以创建不同的 URL。现在,当我部署时,很难一一手动清除所有存储桶的缓存。所以我认为应该有一个选项可以让我找到所有 ID 并清除缓存,但我只能找到

aws cloudfront  get-distribution-config
--id <value>
[--cli-input-json <value>]
[--generate-cli-skeleton <value>] 

其中 id 取我想找出的云端分发本身的 id。

我不能使用它,也不想清除所有发行版的缓存

aws cloudfront list-distributions
[--max-items <value>]
[--cli-input-json <value>]
[--starting-token <value>]
[--page-size <value>]
[--generate-cli-skeleton <value>]

我正在尝试寻找类似的方法,但到目前为止这似乎不是正确的方法

aws cloudfront --origing <value>

您可以使用查询参数来仅获取 ID

aws cloudfront list-distributions --query "DistributionList.Items[*].Origins.Items[*].Id" --output text

S3-test1.example.com
S3-Website-test2.example.com.s3-website-us-west-1.amazonaws.com

然后您可以使用 grep

过滤列表
aws cloudfront list-distributions --query "DistributionList.Items[*].Origins.Items[*].Id" --output text | grep test2

S3-test1.example.com

您可以使用查询参数return多个值

aws cloudfront list-distributions --query "DistributionList.Items[*].Origins.Items[*].{id:Id,name:DomainName}" --output text

S3-test1.example.com  test1.example.com.s3.amazonaws.com
S3-Website-test2.example.com.s3-website-us-west-1.amazonaws.com test2.example.com.s3-website-us-west-1.amazonaws.com

虽然这个解决方案不是我想要的,但它帮助我找到了确切的答案。我发布了最终帮助我实现这一目标的答案。

aws cloudfront list-distributions --query "DistributionList.Items[*].{id:Id,origin:Origins.Items[0].Id}[?origin=='S3-BUCKET_NAME'].id" --output text

这将给出这样的结果

EXXXXXXXXXXX1 EXXXXXXXXXXX2

并且为了清除多个发行版的缓存

for id in $(aws cloudfront list-distributions --query "DistributionList.Items[*].{id:Id,origin:Origins.Items[0].Id}[?origin=='S3-BUCKET_NAME'].id" --output text);do aws cloudfront create-invalidation --distribution-id $id --paths "/*";done;

您可以使用此 python 脚本

获取 CloudFront 分发 ID、域、证书源和来源的列表
#!/usr/bin/env python
import boto3
cf = boto3.client('cloudfront') # Create CloudFront client
print("\nCloudFront Distributions:\n")  # List distributions
distributions=cf.list_distributions()
if distributions['DistributionList']['Quantity'] > 0:
  for distribution in distributions['DistributionList']['Items']:
    print("Domain: " + distribution['DomainName'])
    print("Distribution Id: " + distribution['Id'])
    print("Certificate Source: " + distribution['ViewerCertificate']['CertificateSource'])
    for name in distribution['Origins']['Items']:
        print ("origin:" + name['DomainName'])
    if (distribution['ViewerCertificate']['CertificateSource'] == "acm"):
      print("Certificate: " + distribution['ViewerCertificate']['Certificate'])
    print("")
else:    
  print("Error - No CloudFront Distributions Detected.")

虽然 Ritik Patni 的回答最接近我的需要,但我将以下内容解释为我可以替换存储桶名称并过滤掉我正在寻找的 CF 分布:

[?origin=='S3-BUCKET_NAME']

我没有发现是这种情况,因为当我在 TF 中创建资源时,我使用了与存储桶名称不同的名称来区分变量。在我的例子中,Origins.Items[0].Idstaticsite_s3_bucket,这与 s3 存储桶的名称 dev-it-static-site-mvp 不同。所以一个空集被 returned.

我在 Jenkins 内部执行此操作,控制台输出有点困难,看起来像是在误解引号,所以我在这里发布从管道中取出的 sh 脚本,以防实际实现可以帮助任何人。请注意,Jenkins 的行为可能不像开箱即用的那样。该解决方案适用于 Cloudbees Jenkins Enterprise v 2.249.3.1-rolling。

另外有趣的是,我正在引用 s3 存储桶的域名以匹配存储桶名称。 AFAIK,对于未配置静态网站托管的存储桶,这是一个安全的假设。但是您的里程可能会有所不同。

sh '''#!/bin/sh
set -e
set -x

bucket_name="${ENVIRONMENT}-it-${APP_NAME}"
aws s3 ls ${bucket_name}
aws cloudfront list-distributions

echo "Getting CF distributions matching ${bucket_name} ?"
distributions=$(aws cloudfront list-distributions --query "DistributionList.Items[*].{id:Id,origin_domain:Origins.Items[0].DomainName}[?starts_with(origin_domain,'${bucket_name}.')].id" --output text)
echo ${distributions}
for id in "${distributions}"; do aws cloudfront create-invalidation --distribution-id $id --paths "/*";done;

'''

最后,我还想指出,这个 URL 非常方便地帮助我找出我做错了什么:https://jmespath.org/。我能够粘贴 aws cloudfront list-distributions 的原始内容并四处查看,直到我弄清楚为什么我得到一个空 return.