根据先前配置的 Kubernetes 服务的 AWS ELB,从 CI 动态创建 Route53 托管区域 A 记录

Create Route53 hosted zone A record dynamically from CI based on previously provisioned Kubernetes Service' AWS ELB

我们有一个 AWS EKS 设置 (full repo here), where we install Traefik using Helm。这会创建一个名为 traefik 的 Kubernetes Service,它会配置一个 AWS 弹性负载均衡器。ELB url 可以像这样使用 kubectl 获得:

$ kubectl get service traefik -n default --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}'
ad07f3f3013fc4539811de662a07cf9a-1862511283.eu-central-1.elb.amazonaws.com

我们还注册了一个 AWS Route53 域,我们想指向后面配置的动态配置的 AWS ELB Traefik。

现在,由于此设置是使用 GitHub 基于潜在的新 EKS 集群(使用 Pulumi)的操作动态配置的,我们无法将 ELB url 硬编码到我们的 Route53 托管区域 A 记录中。相反,我们每次都必须创建或更新它,Pulumi 提供的 EKS 设置或 Traefik 服务会更改 ELB(例如,通过提供新的 ELB 并修剪旧的)。

那么我们如何从 GitHub 操作中动态创建(和更新)Route53 托管区域 A 记录?

我们选择使用AWS CLI to do that for us. The docs provide a starting point。但是我们不能像建议的 --change-batch file://sample.json 那样使用静态文件来做到这一点 - 相反,我们需要让它动态化,这样我们就可以在我们的 GitHub 操作工作流程中使用命令。

思路导出from this so answer, where we can simply use the json snippet inline without an extra file. Also need to have an idempotent solution which we can run 1 or many times in GitHub Actions CI. Therefore we used the "Action" : "UPSERT" (see https://aws.amazon.com/premiumsupport/knowledge-center/simple-resource-record-route53-cli/).

aws route53 change-resource-record-sets \
  --hosted-zone-id $ROUTE53_DOMAIN_HOSTED_ZONE_ID \
  --change-batch '
  {
    "Comment": "Create or update Route53 hosted zone A record to point to ELB Traefik is configured to"
    ,"Changes": [{
      "Action"              : "UPSERT"
      ,"ResourceRecordSet"  : {
        "Name"              : "*.'"$ROUTE53_DOMAIN_NAME"'"
        ,"Type"             : "A"
        ,"AliasTarget": {
            "HostedZoneId": "'"$ELB_HOSTED_ZONE_ID"'",
            "DNSName": "dualstack.'"$ELB_URL"'",
            "EvaluateTargetHealth": true
        }
      }
    }]
  }
  '

Using variables inside the json provided to the --change-batch parameter, we need to use single quotes and open them up immediately after (also see )

如你所见,我们需要配置4个变量来使这个命令运行:

  1. $ROUTE53_DOMAIN_HOSTED_ZONE_ID:这是您之前需要注册的 Route53 域的托管区域 ID(注册本身是一个手动步骤)
  2. $ROUTE53_DOMAIN_NAME:你的Route53注册域名。由于我们希望所有路由都由 Traefik 完成,因此我们可以在此处使用 *.$ROUTE53_DOMAIN_NAME
  3. 配置通配符记录
  4. $ELB_HOSTED_ZONE_ID。这是 Elastic Load Balancer 的托管区域 ID,它通过 Traefik 服务部署(通过 Helm)进行配置。
  5. $ELB_URL:Traefik服务的ELBurl。我们需要在它前面加上 dualstack. 以使其工作(参见 https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html

获取所有这些变量并非易事。我们可以从 Route53 域名开始,我们需要在 provision.yml:

的顶部配置静态 GitHub Actions 环境变量
name: provision

on: [push]

env:
  ...
  ROUTE53_DOMAIN_NAME: tekton-argocd.de
...

      - name: Create or update Route53 hosted zone A record to point to ELB Traefik is configured to
        run: |
          echo "--- Obtaining the Route53 domain's hosted zone id"
          ROUTE53_DOMAIN_HOSTED_ZONE_ID="$(aws route53 list-hosted-zones-by-name | jq --arg name "$ROUTE53_DOMAIN_NAME." -r '.HostedZones | .[] | select(.Name=="\($name)") | .Id')"

          echo "--- Obtaining the ELB hosted zone id"
          echo "Therefore cutting the ELB url from the traefik k8s Service using cut (see 
          ELB_NAME="$(kubectl get service traefik -n default --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}' | cut -d "-" -f 1)"
          echo "Extracting the hosted zone it using aws cli and jq (see 
          ELB_HOSTED_ZONE_ID="$(aws elb describe-load-balancers | jq --arg name "$ELB_NAME" -r '.LoadBalancerDescriptions | .[] | select(.LoadBalancerName=="\($name)") | .CanonicalHostedZoneNameID')"

          echo "--- Obtaining the Elastic Load Balancer url as the A records AliasTarget"
          ELB_URL="$(kubectl get service traefik -n default --output=jsonpath='{.status.loadBalancer.ingress[0].hostname}')"

填写完所有变量后,我们就可以使用 AWS CLI 动态创建 Route53 记录了:

      echo "--- Creating or updating ('UPSERT') Route53 hosted zone A record to point to ELB Traefik (see https://aws.amazon.com/premiumsupport/knowledge-center/simple-resource-record-route53-cli/)"
      echo "--- Creating Route53 hosted zone record (mind to wrap the variables in double quotes in order to get them evaluated, see 
      aws route53 change-resource-record-sets \
        --hosted-zone-id $ROUTE53_DOMAIN_HOSTED_ZONE_ID \
        --change-batch '
        {
          "Comment": "Create or update Route53 hosted zone A record to point to ELB Traefik is configured to"
          ,"Changes": [{
            "Action"              : "UPSERT"
            ,"ResourceRecordSet"  : {
              "Name"              : "*.'"$ROUTE53_DOMAIN_NAME"'"
              ,"Type"             : "A"
              ,"AliasTarget": {
                  "HostedZoneId": "'"$ELB_HOSTED_ZONE_ID"'",
                  "DNSName": "dualstack.'"$ELB_URL"'",
                  "EvaluateTargetHealth": true
              }
            }
          }]
        }
        '

运行 您的 GitHub 操作工作流程应该会导致创建 Route53 记录。您可以查看 AWS 控制台:

Here's a build log and also the full GitHub Actions workflow yaml: https://github.com/jonashackt/tekton-argocd-eks/blob/main/.github/workflows/provision.yml