#amazon-web-services #amazon-cloudformation #amazon-ecs #aws-cdk
#amazon-веб-сервисы #aws-cloudformation #amazon-ecs #aws-cdk
Вопрос:
У меня есть 2 стека, первый определяет мое приложение LB, а другой определяет мою службу ECS.
В первом стеке я определил несколько целевых групп для своих нескольких служб ECS и хотел бы зарегистрировать соответствующую службу.
Для справки, я последовал этому примеру здесь, чтобы разделить свое приложение
Как я могу зарегистрировать свою службу ECS в целевой группе, определенной в другом стеке?
Моя служба ECS…
const service = new ecs.Ec2Service(this, 'jenkinsService', {
cluster: props.cluster,
taskDefinition,
serviceName: 'Jenkins-Master',
minHealthyPercent: 0,
maxHealthyPercent: 100
});
props.targetGroup.addTarget(service) // I want to register against a specific Target Group
Моя пользовательская целевая группа
const jenkinsMastertargetGroup = this.targetGroup = new elbv2.ApplicationTargetGroup(this, 'Jenkins-Master', {
vpc: props.vpc,
port: 80,
targetType: elbv2.TargetType.INSTANCE,
targetGroupName: 'WDD-Jenkins-Master',
deregistrationDelay: cdk.Duration.seconds(250),
healthCheck:{
port: '8080',
path:'/log/all',
interval: cdk.Duration.minutes(3)
}
});
Действие на моем слушателе для пересылки в TG
elbHTTPlistener.addAction('JenkinsMasterResponse', {
priority: 5,
conditions: [
//ListenerCondition.hostHeaders(['sub1.test.com.au/jenkins']),
ListenerCondition.pathPatterns(['/jenkins']),
],
action: ListenerAction.forward([jenkinsMastertargetGroup]),
});
Комментарии:
1. если вы следуете примеру, предоставленному aws, вы уже должны быть в состоянии передать свой объект TargetGroup из одного «стека» в другой «стек». Если только каждый ваш «стек» не находится в разных развертываниях, например, вам нужно запустить «развертывание cdk» в каждом стеке. Я сделал аналогичную вещь в 2 разных развертываниях cdk.
2. Не могли бы вы поделиться примером? @Chun
Ответ №1:
Я нашел относительно простое решение этой проблемы, используя импорт / экспорт в cloudformation.
В 1-м стеке, где я определил ELB моего приложения, я определяю пустую целевую группу, а затем экспортирую ARN для целевой группы.
Обязательно добавьте правило для вашего TG.
const emptytg = new elbv2.ApplicationTargetGroup(this, 'tg1', {
vpc,
port: 80,
targetGroupName: 'name',
targetType: elbv2.TargetType.INSTANCE,
});
Listener.addAction('tg1', {
priority: 2,
conditions:[
ListenerCondition.pathPatterns(['/tg1']),
],
action: ListenerAction.forward([tg1])
});
new cdk.CfnOutput(this,'tg1Export', {
value: emptytg.targetGroupArn,
exportName: 'emptytgARN'
});
Ниже приведен другой стек, содержащий службу ECS, вы можете импортировать TG, а затем использовать целевой метод .addTarget.
const importedGroup = elbv2.ApplicationTargetGroup.fromTargetGroupAttributes(this, 'imported-tg',{
targetGroupArn: cdk.Fn.importValue('wddSharedResourcesjenkinsMastertargetGrouptargetGroupArn'),
});
importedGroup.addTarget(service);
Это работает довольно хорошо для меня, и я надеюсь, что это поможет другим в будущем.
Ответ №2:
В моем варианте использования используется 1 балансировщик нагрузки приложений (и 1 прослушиватель HTTPS), и у него разные пути, которые указывают на разные развертывания ECS
например
- https://app.example.com/application-a / для развертывания ECS A
- https://app.example.com/application-b / для развертывания ECS B
И способ, которым я настраиваю, отличается от вашего. Вместо того, чтобы указывать всю целевую группу в стеке слушателей, я определяю эти целевые группы в стеке ECS.
StackLoadBalancer
const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
vpc,
internetFacing: true
});
// make sure allow Application Load Balancer can accessing out to reach private service
lb.connections.securityGroups[0].addEgressRule(
ec2.Peer.ipv4(vpc.vpcCidrBlock),
ec2.Port.allTcp(),
"Allow Local Balancer to access service");
lb.logAccessLogs(logBucket)
const defaultTargetGroup = new elbv2.ApplicationTargetGroup(this, 'TargetGroup', {
vpc: vpc,
port: 80
});
const listener = lb.addListener('Listener', {
port: 443,
certificates: [certification],
defaultTargetGroups: [defaultTargetGroup],
open: true
});
new cdk.CfnOutput(this, 'listenerarn', { value: listener.listenerArn, exportName: this.stackName "-listenerarn" })
stackA
const ecsService = new ecs.Ec2Service(this, 'Service', {
cluster,
taskDefinition
});
ecsService.connections.securityGroups[0].addIngressRule(
ec2.Peer.ipv4(vpc.vpcCidrBlock),
ec2.Port.allTcp(),
"Allow CloudFormation ECS Service Update Properly"
);
const targetGroup = new elbv2.ApplicationTargetGroup(this, 'application-a-tg', {
vpc,
port: portNumber,
protocol: elbv2.ApplicationProtocol.HTTP,
healthCheck: {
interval: cdk.Duration.seconds(60),
path: "/",
timeout: cdk.Duration.seconds(5),
healthyHttpCodes: "200-499"
},
stickinessCookieDuration: cdk.Duration.hours(1),
deregistrationDelay: cdk.Duration.seconds(30),
targets: [
ecsService.loadBalancerTarget({
containerName: 'web'
})]
});
const rule1 = new elbv2.CfnListenerRule(this, "rule1", {
listenerArn: cdk.Fn.importValue("StackLoadBalancerStack-listenerarn"),
actions: [{
type: "forward",
targetGroupArn: targetGroup.targetGroupArn
}],
conditions: [{
field: "path-pattern",
pathPatternConfig: {
values: ["/application-a/*"]
},
}],
priority: 10
});
Наиболее важной частью в stackA является CfnListenerRule, я не смог настроить «собственный» код CDK для этого во время разработки.
Комментарии:
1. Привет @Chun спасибо за помощь, которую я обновил с помощью решения, которое сработало для меня. Мое решение может помочь, поскольку оно более «родное» и использует меньше кода. Еще раз спасибо!