简体   繁体   English

基于先前配置的 Kube.netes 服务的 AWS ELB 从 CI 动态创建 Route53 托管区域 A 记录

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

We have a AWS EKS setup ( full repo here ), where we install Traefik using Helm .我们有一个 AWS EKS 设置(此处为完整存储库),我们在其中使用 Helm 安装 Traefik This creates a Kube.netes Service called traefik which gets provisioned an AWS Elastic Load Balancer.这会创建一个名为traefik的 Kube.netes Service ,它会配置一个 AWS 弹性负载均衡器。 The ELB url can be obtained using kubectl like this:可以使用kubectl获取 ELB url,如下所示:

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

We also have a AWS Route53 domain registered, which we want to point to the dynamically provisioned AWS ELB Traefik is beeing configured behind.我们还注册了一个 AWS Route53 域,我们想指向动态配置的 AWS ELB Traefik 正在后面配置。

Now since this setup is dynamically provisioned using GitHub Actions based on a potentially new EKS cluster (using Pulumi), we cannot hard code the ELB url into our Route53 hosted zone A record.现在,由于此设置是使用基于潜在新 EKS 集群(使用 Pulumi)的 GitHub 操作动态配置的,我们无法将 ELB url 硬编码到我们的 Route53 托管区域 A 记录中。 Instead we have to create or update it every time, the Pulumi provisioned EKS setup or the Traefik Service changes the ELB (eg by provisioning a new ELB and pruning the old).相反,我们每次都必须创建或更新它,Pulumi 提供的 EKS 设置或 Traefik 服务会更改 ELB(例如,通过提供新的 ELB 并修剪旧的)。

So how can we create (and update) the Route53 hosted zone A record dynamically from within GitHub Actions?那么我们如何从 GitHub 操作中动态创建(和更新)Route53 托管区域 A 记录?

We choose to use AWS CLI to do that for us.我们选择使用AWS CLI为我们做这件事。 The docs provide a starting point . 文档提供了一个起点 But we can't do this using a static file like with the proposed --change-batch file://sample.json - instead we need to have it dynamic so we can use a command inside our GitHub Actions workflow.但是我们不能像建议的--change-batch file://sample.json那样使用 static 文件来执行此操作 - 相反,我们需要使其动态,以便我们可以在 GitHub 操作工作流中使用命令。

The idea is derived from this so answer , where we can simply use the json snippet inline without an extra file.这个想法来源于这个 so answer ,我们可以简单地使用内联的 json 片段而不需要额外的文件。 Also need to have an idempotent solution which we can run 1 or many times in GitHub Actions CI.还需要有一个幂等解决方案,我们可以在 GitHub Actions CI 中运行 1 次或多次。 Therefore we used the "Action": "UPSERT" (see https://aws.amazon.com/premiumsupport/knowledge-center/simple-resource-record-route53-cli/ ).因此我们使用了"Action": "UPSERT" (参见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 https://stackoverflow.com/a/49228748/4964553 )使用提供给--change-batch参数的 json 中的变量,我们需要使用单引号并在之后立即打开它们(另请参阅https://stackoverflow.com/a/49228748/4964553

As you can see, we need to configure 4 variables to make this command run:如您所见,我们需要配置 4 个变量来运行此命令:

  1. $ROUTE53_DOMAIN_HOSTED_ZONE_ID : This is the hosted zone id of your Route53 domain you need to register before (the registration itself is a manual step) $ROUTE53_DOMAIN_HOSTED_ZONE_ID :这是您之前需要注册的 Route53 域的托管区域 ID(注册本身是一个手动步骤)
  2. $ROUTE53_DOMAIN_NAME : Your Route53 registered domain name. $ROUTE53_DOMAIN_NAME :您的 Route53 注册域名。 As we want all routing to be done by Traefik, we can configure a wildcard record here using *.$ROUTE53_DOMAIN_NAME由于我们希望所有路由都由 Traefik 完成,因此我们可以在此处使用*.$ROUTE53_DOMAIN_NAME配置通配符记录
  3. $ELB_HOSTED_ZONE_ID : A different hosted zone id than your domain! $ELB_HOSTED_ZONE_ID与您的域不同的托管区域 ID! . . This is the hosted zone id of the Elastic Load Balancer, which gets provisioned through the Traefik Service deployment (via Helm).这是 Elastic Load Balancer 的托管区域 ID,它通过 Traefik 服务部署(通过 Helm)进行配置。
  4. $ELB_URL : The ELB url of the Traefik Service. $ELB_URL :Traefik服务的ELB url。 We need to preface it with dualstack.我们需要用dualstack. in order to make it work (see https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html )为了让它工作(见https://docs.aws.amazon.com/Route53/latest/APIReference/API_AliasTarget.html

Obtaining all those variables isn't trivial.获取所有这些变量并非易事。 We can start with the Route53 domain name, we need to configure as a static GitHub Actions environment varialbe at the top of our provision.yml:我们可以从 Route53 域名开始,我们需要在 provision.yml 的顶部配置一个 static 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 https://stackoverflow.com/a/29903172/4964553)"
          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 https://stackoverflow.com/a/53230627/4964553)"
          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}')"

Having all the variables filled we are able to use AWS CLI to create the Route53 record dynamically:填好所有变量后,我们就可以使用 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 https://stackoverflow.com/a/49228748/4964553)"
      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
              }
            }
          }]
        }
        '

Running your GitHub Actions workflow should result in the Route53 record beeing created.运行 GitHub Actions 工作流应该会创建 Route53 记录。 You can have a look into the AWS console:您可以查看 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 这是构建日志以及完整的 GitHub 操作工作流 yaml: https://github.com/jonashackt/tekton-argocd-eks/blob/main/.github/workflows/provision.yml

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AWS Route53 公共区域名称服务器和记录类型 NS 记录 - AWS Route53 public zone name servers and record type NS records AWS APIGateway 仅来自 route53 - AWS APIGateway From route53 only 指向经典负载均衡器的 AWS Route53 A 记录(由 Kube.netes 创建)适用于 http 但不适用于 https - AWS Route53 A-record pointing to classic load balancer (created by Kubernetes) works with http but not https 如何通过aws cli删除Route53中的一条DNS记录? - How to delete a DNS record in Route53 via aws cli? AWS Route53 记录创建“DomainLabelTooLong”错误 - AWS Route53 record creation "DomainLabelTooLong" Error AWS 简单 Email 服务域验证和在 Route 53 私有托管区域中创建的域 - AWS Simple Email Service Domain Validation and Domain created in Route 53 Private Hosted Zone “找不到匹配的 Route53Zone”:Terraform 的 Route53 数据源无法识别托管区域名称 - "no matching Route53Zone found": Terraform's Route53 data source is not recognizing the hosted zone name 是否可以使用 Java AWS API 更新 Route53 记录? - Is it possible using the Java AWS API to update a Route53 record? 使用 Terraform 创建多个 DNS Route53 A 记录 - Create multiple DNS Route53 A record using Terraform 如何在 AWS Route 53 托管区域中使用 Google 名称服务器 - How to use Google Name Servers in AWS Route 53 Hosted Zone
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM