AWS ECS: Ec2Service too many resources
See original GitHub issueProblem
Current ECS design is close to unusable when one wants to re-use an ECS Cluster across multiple ECS services (across multiple git repos) because there is too much going on under the hood.
Please make the flow less strict so that the CDK can have greater ECS adoption.
Description
Hey Guys,
So a couple of months ago year ago I tried CDK but realized it wants to create too many unwanted resources (https://github.com/aws/aws-cdk/issues/2234). Today, I gave it another chance.
I tied to create an ECS Ec2Service but I’m failing at the point where I need to provide the cluster. So we (I guess other companies, too) have a single cluster where we host a lot of services. These services live in different Git repos.
As you can see in the official documentation, the cluster parameter of EcsService is a string where aws-cdk
asks for a goddamn ICluster
.
I guess it’s needless to say how unconvenient this is when you only know the name of the cluster. Well, if I want to import my existing cluster with Cluster.fromClusterAttributes
(ref), I must know it’s VpcId
and SecurityGroups
which I really don’t want to provide, it’s too low-level information. (My company has a raw cloudformation template right now where we only provide the cluster name.) Also: why? In the official CF docs, nothing is required.
So I took a look at why Ec2Service
needs a full-fledged ICluster
. When looking at the constructor I sadly realized that once again the CDK wants to create all kinds of resources here and here. Needless to say that Troposphere only requires a string.
Now, I’m genuinely confused about the general philosophy of the CDK. We have ecs-patterns module and I thought that one is for providing really high-level constructs and if someone is a fan of creating unwanted resouces, it’s for those people. Now, looks like we can’t even create an ECS Ec2Service
conveniently.
So, let me ask: what’s the goal of CDK? It’s for companies who don’t want to control all their AWS resources and only care about higher level abstractions? It’s supposed to serve every use case? By looking at the constructor of Ec2Service
, I can’t really decide. It feels like it dances around the edge of high and low level abstractions.
Recommendations
- In
Cluster
nothing should be required, maximumclusterName
. Dumb downCluster.fromClusterAttributes
to only require aclusterName
, this meansvpc
andsecurityGroups
should be optional. - In the constructor of
Ec2Cluster
, if theICluster
does not havevpc
andsecurityGroups
defined, do not create additional resources like a new security group. I think this part of the code is too magical anyway.
edit.: I think I solved it with a nasty workaround.
import { CfnService } from '@aws-cdk/aws-ecs';
new CfnService(scope, "MobileService", {
taskDefinition: taskDefinition.taskDefinitionArn,
cluster: "clusterName-as-a-string"
});
This gets the job done but attaching a load balancer is not easy…
edit2: never mind guys, load balancer also require importing an existing Vpc instead of VpcId. I guess if I want to keep use CDK I’ll need to use raw Cfn*
sources. 😦
Issue Analytics
- State:
- Created 4 years ago
- Comments:7 (2 by maintainers)
Top GitHub Comments
First off let me apologize if this sounds a bit ranty. I was looking for this error explicitly though regarding setting up ECS services with existing resources. I’m just not sure CDK is intended for shops that have already heavily invested in cloudformation. Importing and using existing resources seems to be as much or more code than is necessary. Especially with all the required ITypes. We export a lot of string values already using Cfn exports like sgs, vpcs, subnets, azs, lb’s, log groups, clusters, roles and so on. All of these are just either resource id’s or ARN’s and I’m finding I have to practically reconstruct resources which were just referable directly in the property as a Fn::ImportValue. Complex workarounds to essentially refer a property to an IType instead of just a string is bulky to say the least.
I really want to use this tool I’m just finding it hard to justify the learning curve right now when everyone is already familiar with yaml and their pre-existing stack resources.
FYI @SomayaB I got it figured out in a funky way, haha. It’s a bit risky, because there’s multiple fake values provided that are not used in the CF template (and I can just hope it stays that way).
Here it is:
And the fact that this works perfectly makes my point even stronger:
securityGroups
andvpc
should be optional inCluster.fromClusterAttributes
Cluster.fromClusterName(scope, clusterName)
(Disclaimer:
cfParameter
is a helper method that wrappsCfnParameter
)I also figured out how to create a load balancer if you only know the VpcId and the subnets. This one also uses a couple of fake inputs which is a bit risky. 😕
The whole thing: