使用AWS CDK创建具有多个DNS记录的Discovery Service

72次阅读
没有评论

问题描述

正在尝试使用CDK在AWS上部署Jenkins。他遵循了两篇文章的指导:
https://tomgregory.com/deploying-jenkins-into-aws-ecs-using-cdk/
https://tomgregory.com/jenkins-jobs-in-aws-ecs-with-slave-agents/

他已经成功将大部分远程ECS Jenkins代理代码迁移到CDK,但是他无法找到一种简单的方法来在CDK中创建Discovery Service,这在这里有所提及。

在CDK中,我们只能创建一个DnsRecords属性的实例,而该服务需要A记录和SRV记录。创建两个服务也会失败,因为FargateService只接受一个ServiceRegistry

他尝试使用传统的CloudFormation模板,使用这个,但是在CDK中导入一个单独的”name”字符串并在其中使用它非常复杂。

如果有人能够向我展示如何:
– 在CDK中复制具有多个DnsRecords属性的DiscoveryService
或者
– 在CDK中包含单个DiscoveryService CloudFormation块,从DiscoveryService中获取name属性,并将其作为FargateService的服务注册表添加到CDK中

我将非常感激!

谢谢大家。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据您的描述,CDK中的FargateService只接受一个ServiceRegistry,而您需要创建多个DNS记录。为了解决这个问题,您可以使用AWS CDK的CustomResource来创建自定义资源,以创建多个DNS记录。

以下是在CDK中实现的步骤:
1. 在您的CDK项目中,安装@aws-cdk/custom-resources模块。
2. 导入所需的模块:

import * as cdk from 'aws-cdk-lib';
import * as customResources from 'aws-cdk-lib/aws-custom-resources';
import * as iam from 'aws-cdk-lib/aws-iam';
  1. 创建一个自定义资源:
const discoveryServiceCustomResource = new customResources.AwsCustomResource(this, 'DiscoveryServiceCustomResource', {
  onCreate: {
    service: 'CloudFormation',
    action: 'createStack',
    parameters: {
      StackName: 'DiscoveryServiceStack',
      TemplateBody: `
        Resources:
          DiscoveryService:
            Type: AWS::ServiceDiscovery::Service
            Properties:
              Name: your_service_name
              DnsConfig:
                DnsRecords:
                  - TTL: 60
                    Type: A
                  - TTL: 60
                    Type: SRV
              NamespaceId: your_namespace_id
      `,
    },
    physicalResourceId: customResources.PhysicalResourceId.of('DiscoveryServiceStack'),
  },
  onDelete: {
    service: 'CloudFormation',
    action: 'deleteStack',
    parameters: {
      StackName: 'DiscoveryServiceStack',
    },
  },
  policy: customResources.AwsCustomResourcePolicy.fromSdkCalls({resources: customResources.AwsCustomResourcePolicy.ANY_RESOURCE}),
});

在上面的代码中,我们使用AwsCustomResource创建了一个自定义资源DiscoveryServiceCustomResource。在onCreate属性中,我们指定了创建CloudFormation堆栈的操作,并提供了堆栈的模板。您需要根据您的需求修改模板中的NameDnsRecordsNamespaceId

  1. 将自定义资源添加到FargateService的服务注册表中:
fargateService.addServiceRegistry({
  registryArn: discoveryServiceCustomResource.getResponseField('Stacks[0].Outputs[0].OutputValue'),
});

在上面的代码中,我们使用getResponseField方法从自定义资源的响应中获取堆栈的输出值,并将其添加到FargateService的服务注册表中。

请注意,这只是一个示例,您需要根据您的实际需求进行修改。

方案2

另一种方法是将单个DiscoveryService CloudFormation块导入到CDK中,并从中获取name属性。然后,您可以将该属性添加为FargateService的服务注册表。

以下是在CDK中实现的步骤:
1. 创建一个CloudFormation模板文件discovery-service.yml,并将以下内容复制到文件中:

Resources:
  DiscoveryService:
    Type: AWS::ServiceDiscovery::Service
    Properties:
      Name: your_service_name
      DnsConfig:
        DnsRecords:
          - TTL: 60
            Type: A
          - TTL: 60
            Type: SRV
      NamespaceId: your_namespace_id

在上面的模板中,您需要根据您的需求修改NameDnsRecordsNamespaceId

  1. 在CDK项目中,使用CfnInclude导入CloudFormation模板:
import * as cdk from 'aws-cdk-lib';
import * as cfn from 'aws-cdk-lib/aws-cloudformation';
const discoveryServiceStack = new cfn.CfnInclude(this, 'DiscoveryServiceStack', {
  templateFile: 'path/to/discovery-service.yml',
});

在上面的代码中,我们使用CfnInclude创建了一个DiscoveryServiceStack,并指定了CloudFormation模板的路径。

  1. 将服务注册表添加到FargateService中:
fargateService.addServiceRegistry({
  registryArn: discoveryServiceStack.getOutputValue('DiscoveryService'),
});

在上面的代码中,我们使用getOutputValue方法从DiscoveryServiceStack中获取DiscoveryService的输出值,并将其添加到FargateService的服务注册表中。

请注意,这只是一个示例,您需要根据您的实际需求进行修改。

以上是两种在CDK中创建具有多个DNS记录的Discovery Service的解决方案。您可以根据您的需求选择其中一种方法,并根据您的实际情况进行修改。

希望对您有所帮助!

正文完