How can I edit Nodegroup in AWS EKS from AWS CDK - amazon-web-services

I use AWS CDK to create eks cluster then use addNodegroupCapacity to add nodegroup.
const myNodeGroup = cluster.addNodegroupCapacity('my-node-group', {
nodegroupName: 'my-node-group',
instanceTypes: [
new ec2.InstanceType('t3a.small'),
],
minSize: 1,
desiredSize: 1,
maxSize: 1,
diskSize: 10,
capacityType: eks.CapacityType.SPOT,
amiType: eks.NodegroupAmiType.AL2_X86_64,
subnets: { subnetType: ec2.SubnetType.PUBLIC },
})
I want to change subnet to
subnets: { availabilityZones: ['ap-southeast-1a'] }
When I made change in CDK I got an error
Resource handler returned message: "NodeGroup already exists with name my-node-group and cluster name (Service: Eks, Status Code: 409, Request ID: {Request ID})" (RequestToken: {RequestToken}, HandlerErrorCode: AlreadyExists)
How can I edit this nodegroup from AWS CDK or I have to delete and recreate it?

Changing the subnet is a replacement operation, which means the NodeGroup will be destroyed and another created. However, your explicit nodegroupName is interfering with this CloudFormation process. For this reason it's best practice to use generated resource names, not physical names.
Delete the resource manually. Remove the nodegroupName prop to avoid this problem in the future.

Related

AWS ECS EC2 Capacity Provider not listed

I'm trying to create a new Capacity Provider
I deployed the following CloudFormation snippet:
myECSCapacityProvider:
Type: AWS::ECS::CapacityProvider
Properties:
Name: my-project-asg-cp
AutoScalingGroupProvider:
AutoScalingGroupArn: !Ref myAutoScalingGroup
ManagedScaling:
MaximumScalingStepSize: 10
MinimumScalingStepSize: 1
Status: ENABLED
TargetCapacity: 100
ManagedTerminationProtection: DISABLED
I have the resource ASG (myAutoScalingGroup) created.
When I go to the ECS console and then to the Capacity Providers tab it is blank, no CPs are listed.
If I try to create the same CP through the console, using the name my-project-asg-cp I see the following error:
There was an error creating the capacity provider.
Fix the following error and try again.
The specified Auto Scaling group ARN is already being used by another capacity provider.
Specify a unique Auto Scaling group ARN and try again.
So it seems somehow the CP was created but it is not listed.
And of course, I don't have any error in CloudFormation.
If I check the resources tab I can see the resource created:
myECSCapacityProvider my-project-asg-cp AWS::ECS::CapacityProvider CREATE_COMPLETE
Also, the cli doesn't show it either.
Does anyone has faced this error?
Associate the capacity provided with the cluster:
ECSCluster:
Type: 'AWS::ECS::Cluster'
Properties:
ClusterName: <your-ecs-cluster>
CapacityProviders:
- !Ref myECSCapacityProvider

AWS CDK ApplicationLoadBalancedFargateService in private (isolated) subnet

I'm trying to create a cdk stack containing an ApplicationLoadBalancedFargateService (docs). I want it placed in my VPC which exclusively contains private subnets.
When I try to deploy my stack I get an error message saying:
Error: There are no 'Public' subnet groups in this VPC. Available types: Isolated
Which well... in theory is correct, but why does it break my deployment?
Here an extract of my code my code:
// Get main VPC and subnet to use
const mainVpc = ec2.Vpc.fromLookup(this, 'MainVpc', {
vpcName: this.VPC_NAME
});
// Fargate configuration
const loadBalancedFargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this,
'CdkDocsFargateService', {
serviceName: 'docs-fargate-service',
memoryLimitMiB: 512,
desiredCount: 1,
cpu: 256,
vpc: mainVpc,
taskImageOptions: {
image: ecs.ContainerImage.fromRegistry(this.IMAGE_NAME),
containerPort: 80,
},
});
I was able to achieve the desired outcome manually from the management console. What am I doing wrong when using CDK?
I solved the problem by setting publicLoadBalancer: false in the properties of the ApplicationLoadBalancedFargateService.

AWS migrate ApplicationLoadBalancer from CFT to CDK without replacement

I'm currently migrating an AWS stack defined in Cloudformation (CFT) to CDK. The goal is not to trigger a replacement of viral resources, but I'm stuck with my Application Load Balancer.
In the old CFT stack the ALB is defined as:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
without the "Type" Property set which allows the following values: application | gateway | network
Anyways the resulting Resource in AWS Console has the Type set to "application".
In CDK I create the ALB like:
new ApplicationLoadBalancer(this, 'alb', {
vpc,
internetFacing: true,
vpcSubnets: {
subnets: vpc.publicSubnets,
},
securityGroup: this.securityGroup,
});
unfortunately this triggers a replacement because "Type": "application" is now set explicitly.
Is there any way around this? My next guess would be to try an Cfn Construct...
The most convenient solution I found was to just delete the property that is set implicitly in the L2 Construct.
const alb = new ApplicationLoadBalancer(this, 'alb', {
vpc,
internetFacing: true,
vpcSubnets: {
subnets: vpc.publicSubnets,
},
securityGroup: mySg
});
// First cast Construct to its underlying Cfn Construct
// Then delete property
(alb.node.defaultChild as CfnLoadBalancer).addDeletionOverride('Properties.Type');
More information can be found here: AWS Documentation: Escape hatches

How to create Elastic IP association with an EC2 instance using AWS CDK?

In AWS CDK, I have an EC2 instance and Elastic IP created as follows:
// EC2 Instance
let ec2Instance = new ec2.Instance(this, "EC2Instance", {
instanceType: ec2.InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
vpc: vpc,
securityGroup: securityGroupEc2,
keyName: Config.keyPairName,
machineImage: new ec2.GenericLinuxImage({"eu-west-1": Config.ec2ImageAmi}),
blockDevices: [{deviceName: "/dev/sda1", volume: ec2.BlockDeviceVolume.ebs(30)}]
});
// Elastic IP
let eip = new ec2.CfnEIP(this, "Ip");
I have difficulties to understand how I can declare an association between these, as I can not perceive using AWS CDK documentation how to declare that. Seems that I need AWS::EC2::EIPAssociation.EIP: string to supply and I am missing as to how to get it from the eip object.
It wasn't explained very well, but the solution is:
// EC2 Instance <> EIP
let ec2Assoc = new ec2.CfnEIPAssociation(this, "Ec2Association", {
eip: eip.ref,
instanceId: ec2Instance.instanceId
});
For Cfn* CDK resources, I find that the CloudFormation docs are much more informative than the CDK API.
The CloudFormation docs for AWS::EC2::EIP show that there is an instanceId property that can be used when creating the EIP, which I believe should avoid the need to create a CfnEIPAssociation separately.

AWS CloudFormation: CREATE_FAILED DBSecurityGroup is not supported in this region (London)

I am trying to reapply a cloudformer template from another account but in the same region, EU-West-2 (London). When I apply the template I get the following error:
10:05:10 UTC+0100 CREATE_FAILED AWS::RDS::DBSecurityGroup dbsgdefault DBSecurityGroup is not supported in this region
Client Request Token:Console-CreateStack-1bdd4259-7132-4d44-8ba9-c3e7af892413
The relevant part of the template is:
"dbsgdefault": {
"Type": "AWS::RDS::DBSecurityGroup",
"Properties": {
"GroupDescription": "default"
}
}
How come this can't be reapplied to the account?
I got same error when used eu-central-1 region. After examining awslabs example I assumed that in that (and probably also cn-north-1 region) you have to not use AWS::RDS::DBSecurityGroup and use AWS::EC2::SecurityGroup within VPCSecurityGroups property instead.