问题描述
正在尝试使用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';
- 创建一个自定义资源:
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堆栈的操作,并提供了堆栈的模板。您需要根据您的需求修改模板中的Name
、DnsRecords
和NamespaceId
。
- 将自定义资源添加到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
在上面的模板中,您需要根据您的需求修改Name
、DnsRecords
和NamespaceId
。
- 在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模板的路径。
- 将服务注册表添加到FargateService中:
fargateService.addServiceRegistry({
registryArn: discoveryServiceStack.getOutputValue('DiscoveryService'),
});
在上面的代码中,我们使用getOutputValue
方法从DiscoveryServiceStack
中获取DiscoveryService
的输出值,并将其添加到FargateService
的服务注册表中。
请注意,这只是一个示例,您需要根据您的实际需求进行修改。
以上是两种在CDK中创建具有多个DNS记录的Discovery Service的解决方案。您可以根据您的需求选择其中一种方法,并根据您的实际情况进行修改。
希望对您有所帮助!