-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ecs: service.serviceConnectConfiguration generates bogus CloudMap namespaces #25616
Comments
Hi I tried this in my environment and looks like it only create one namespace? export class Demo2Stack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const vpc = getOrCreateVpc(this);
const cluster = new ecs.Cluster(this, "MyCluster", {
clusterName: PhysicalName.GENERATE_IF_NEEDED,
vpc,
defaultCloudMapNamespace: {
name: "passmate.private",
useForServiceConnect: true,
type: servicediscovery.NamespaceType.DNS_PRIVATE,
vpc
},
});
const task = new ecs.FargateTaskDefinition(this, 'Task', {
cpu: 256,
memoryLimitMiB: 512,
});
task.addContainer('keycloak', {
image: ecs.ContainerImage.fromRegistry('quay.io/keycloak/keycloak'),
portMappings: [
{ name: 'keycloak_http', containerPort: 8080 },
]
});
new ecs.FargateService(this, 'Service', {
cluster,
taskDefinition: task,
serviceConnectConfiguration: {
services: [{
portMappingName: "keycloak_http",
dnsName: "keycloak",
port: 80,
}]
}
});
};
}; Resources |
BTW, if you are building keycloak service on ECS or Fargate, you probably can refer to this aws-sample which does not use cloudmap but JDBC_PING and stickinessCookie instead. It's not perfect but worth a look. https://github.com/aws-samples/cdk-keycloak/blob/main/src/keycloak.ts |
I suspect the issue arises because the cluster and the service are defined in different stacks (see the Fn::ImportValue below)? Cluster template:
Service template:
|
I am using DNS_PING for the cluster itself, I need Cloudmap for Keycloak integration with by backend services (Quarkus admin client). And I am trying to avoid the cost of an internal load balancer... |
I think you probably should configure it like this(using nginx as a example): const vpc = getOrCreateVpc(this);
const cluster = new ecs.Cluster(this, `MyCluster${id}`, {
vpc,
defaultCloudMapNamespace: {
name: `${id}-ns`,
useForServiceConnect: true,
type: servicediscovery.NamespaceType.DNS_PRIVATE,
vpc
},
});
const task = new ecs.FargateTaskDefinition(this, 'Task', {
cpu: 256,
memoryLimitMiB: 512,
});
task.addContainer('nginx', {
image: ecs.ContainerImage.fromRegistry('nginx'),
portMappings: [
{ name: 'nginx_http', containerPort: 80 },
],
});
const service = new ecs.FargateService(this, 'Service', {
cluster,
taskDefinition: task,
serviceConnectConfiguration: {
services: [{
portMappingName: "nginx_http",
dnsName: "nginx",
port: 80,
}],
},
});
service.node.addDependency(cluster.defaultCloudMapNamespace!);
Let me know if it works for you. |
Any workaround you can suggest? If I use the CloudMap APIs directly to create the keycloak record, do I need to additionally configure something on the service to enable ServiceConnect? |
The duplicate namespace is in fact created by the Infra stack. If I manually delete the spurious "API only" namespace before deploying the service stack, the service deployment fails with this errror:
I can see the namespace in the console, its resource name though is "passmate.private-fm7n2lxfyexstqq5", not passmate.private. |
Yep, that seems to be the issue, the service deployment works as expected if I configure service connect by manually specifying the namespace resource name:
Is there any way to obtain that resource name from cdk after deploying the Infra stack but before deploying the service stack? |
The console is a bit of a mess when it comes to namespaces? For the same namespace, I have this in
... but in
So the ECS name becomes the CloudMap HTTP Name, would this be the origin of the bug? I can't figure out how to lookup the actual namespace from the service stack even though I have its ARN, because |
Using the ARN to setup the service ServiceConnect options works:
then
This was painful :( |
It looks like I may have to give up on ServiceConnect... with the steps above the PrivateDnsNamespace has the service, but it doesn't have any DNS record for it. |
I would like to point out that @franck102 is not the only one facing this issue: As shown in the image I am also getting two namespaces generated while using EC2 Services with very similar timestamps My CDK code is below:
ApplicationLoadBalancedEc2Service Construct:
Ec2Service:
Note that I first create the cluster, then use I've checked the Cloud Formation Template and it also only shows that 1 namespace is getting created at the cft level:
The API Call only namespace has the I also +1 the need for documentation, I've spent many hours trying to figure out how service discovery, cloudmap, and service connect all fit into each other and how it all works with the CDK. |
This question on StackOverflow explains a lot about how Service Connect works. Apparently Service Connect isn't meant to be used together with DNS. |
Thanks for reporting a bug and we apologize for any inconvenience caused by an issue. We are investigating this issue and will update this thread once we have a findings. |
This issue looks like it's caused by Service Connect's default behavior of creating a namespace with the given name if one does not exist. To mitigate this issue, I've cut a PR (#25891) which implicitly creates a dependency between the default Cloudmap namespace and the cluster by using the namespace ARN instead of it's string id. This will avoid the problem at cluster creation. It's still possible to create a namespace accidentally by passing the string name to declare const ns cloudmap.INamespace; // example.com
declare const svc ecs.FargateService;
svc.node.addDependency(ns);
svc.enableServiceConnect({
namespace: 'example.com',
}); A good next step to stop this from happening in the future altogether would be to deprecate the |
…ervice connect (#25891) This PR should fix #25616, where service connect accidentally creates a duplicate HTTP namespace when a customer sets a service connect default namespace on the cluster. Closes #25616 However, I think that a broader fix for this issue should include deprecation of the `namespace` parameter in `ServiceConnectProps` in favor of a `cloudmapNamespace: INamespace` parameter; that way, we can force resolution by ARN under the hood of the construct and never trigger the namespace duplication behavior. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
|
Describe the bug
This cdk code:
... and in a different stack:
generates two namespaces in CloudMap:
The "DNS Queries" contains no services, the second namespace (API calls only) contains the keycloak service defined above.
Expected Behavior
I expected a private DNS entry to be created for the keycloak service, with the DNS name keycloak.passmate.private.
Current Behavior
No DNS record gets created.
The first namespace ("API calls and DNS queries in VPCs") has the expected aws:cloudformation:stack-id, aws:cloudformation:stack-name and aws:cloudformation:logical-id tags.
The second namespace ("API calls" only) which contains the service has a single "AmazonECSManaged" tag.
Reproduction Steps
Create a simple stack with cluster with a default CloudMap namespace & a ServiceConnect-enabled service as described above.
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.79.1 (build 2e7f8b7)
Framework Version
"version": "2.79.0",
Node.js Version
v18.3.0
OS
macOS 12.6
Language
Typescript
Language Version
5.0.4
Other information
No response
The text was updated successfully, but these errors were encountered: