Reputation: 303
I am attempting to create an EKS Cluster with the Cluster object in Python using the AWS CDK.
I have a Stack that constructs networking objects such as VPCs and Subnets. That Stack is defining three "types" of subnets:
The code defining that information is below. This is coming from my Networking Stack:
# Define the number of subnets to create in a for loop later on. This will be a shared value between the worker, control, and public subnets.
subnet_count = range(1,3)
# Create empty lists for each of our subnet types. These will hold our SubnetConfigurations that are passed to VPC creation
self.public_subnets = []
self.worker_subnets = []
self.control_subnets = []
# Loop through our defined range above, creating the appropriate control, worker, and public subnets, aligning to CIDRs above
for x in subnet_count:
x = str(x)
self.control_subnets.append(ec2.SubnetConfiguration(
name = 'Control-0{}'.format(x),
cidr_mask=28,
subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
reserved = False
))
self.worker_subnets.append(ec2.SubnetConfiguration(
name = 'Worker-0{}'.format(x),
cidr_mask=24,
subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
reserved = False
))
self.public_subnets.append(ec2.SubnetConfiguration(
name = 'Public-0{}'.format(x),
cidr_mask=27,
map_public_ip_on_launch=True,
subnet_type = ec2.SubnetType.PUBLIC,
reserved = False
))
and then I create a VPC for use with EKS, by unpacking those SubnetConfiguration lists:
self.kubernetes_vpc = ec2.Vpc(self,
"Kubernetes",
cidr=my_cidr,
default_instance_tenancy=ec2.DefaultInstanceTenancy.DEFAULT,
enable_dns_hostnames=True,
enable_dns_support=True,
flow_logs=None,
gateway_endpoints=None,
max_azs=2,
nat_gateway_provider=ec2.NatProvider.gateway(),
nat_gateways=1, # this is 1 PER AZ
subnet_configuration=[*self.public_subnets,*self.control_subnets,*self.worker_subnets],
vpc_name="Kubernetes",
vpn_connections=None
)
I pass this stack to the EKS Cluster Stack, referenced as my_network_stack
So what I'm trying to do now is specifically call out, using subnet_group_name
parameter of ec2.SubnetSelection
the names of the Control Subnets that are created in the other Stack, and hand those over to the Cluster
's vpc_subnets
parameter in the EKS Stack.
self.control_subnets = []
for subnet_config in my_network_stack.control_subnets:
self.selected_subnets = my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=subnet_config.name).subnets
The my_network_stack.control_subnets
is the self.control_subnets
defined earlier in the Networking Stack.
This should be giving me a list of ISubnet objects that were selected properly based on the Control Subnet group names, I set up a simple test here:
for item in self.selected_subnets:
logging.debug(type(item))
which returns
DEBUG:root:<class 'aws_cdk.aws_ec2.PrivateSubnet'>
DEBUG:root:<class 'aws_cdk.aws_ec2.PrivateSubnet'>
Those are ISubnet objects, correct?
My first attempt to try to get this to work is to provide an unpacker for the specific list, which should be a group of ISubnet objects (truncated Cluster parameters):
self.Cluster = eks.Cluster(
vpc_subnets = [
ec2.SubnetSelection(subnets=[*self.selected_subnets])
]
which gives me the error:
jsii.errors.JSIIError: Expected object reference, got "latest"
Not entirely sure what I'm doing wrong. I've tried some variations on passing in the correct list of ISubnet objects, even when I specifically call out the array index:
vpc_subnets = [
ec2.SubnetSelection(subnets=[self.selected_subnets[0], self.selected_subnets[1]])
]
but the same error occurs.
Use the actual SubnetSelection
function to get a list of ISubnet Objects:
vpc_subnets = [
ec2.SubnetSelection(subnets=
[my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=self.control_subnet_names[0]).subnets, my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=self.control_subnet_names[1])])
]
which gives me the error:
jsii.errors.JSIIError: Expected object reference, got [{"$jsii.byref":"aws-cdk-lib.aws_ec2.PrivateSubnet@10011"},{"$jsii.byref":"aws-cdk-lib.aws_ec2.PrivateSubnet@10012"}]
This looks like it could potentially be list of dictionary references with the actual ISubnet Object, in that case, not sure how it's better than Method 1, where the actual object is referenced.
Output of pip freeze
:
$ pip freeze
attrs==21.4.0
aws-cdk-lib==2.8.0
cattrs==1.10.0
constructs==10.0.37
jsii==1.52.1
publication==0.0.3
python-dateutil==2.8.2
six==1.16.0
typing-extensions==4.0.1
As the answerer pointed out, this error expected object, got 'latest'
was related to the ALB version in the cluster creation statement, not the subnets being passed in. That was the problem all along. I've included that (broken) code below:
self.cluster = eks.Cluster(
self,
"InfrastructureCluster",
default_capacity_type=eks.DefaultCapacityType.NODEGROUP,
alb_controller=eks.AlbControllerOptions(version='latest'),
endpoint_access=eks.EndpointAccess.PUBLIC_AND_PRIVATE,
version=eks.KubernetesVersion.V1_21,
cluster_name="InfrastructureCluster",
security_group=my_network_stack.controlplane_security_group,
vpc=my_network_stack.kubernetes_vpc,
vpc_subnets=
[
ec2.SubnetSelection(subnets=self.selected_subnets)
],
)
Additionally, this doesn't fix the problem with passing in the subnets, but I was able to finally get this code to work. The key here is that select_subnets(subnet_group_name=subnet_config
returns a list of ISubnet objects, so you have separate that into objects, then unpack that into the cluster's vpc_subnets
:
for subnet_config in my_network_stack.control_subnets:
for item in my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=subnet_config.name).subnets:
self.selected_subnets.append(item)
# Later, during cluster creation:
vpc_subnets=
[
ec2.SubnetSelection(subnets=[*self.selected_subnets])
]
I was only able to get the above to work, combinations of passing in the list object (SubnetSelection(subnets=[]) requires a list) would lead to syntax errors.
Upvotes: 1
Views: 2344
Reputation: 11588
The following woks fine and is not the cause of the issue:
self.Cluster = eks.Cluster(
vpc_subnets = [SubnetSelection(subnets=selected_subnets)]
The cause of the issue is the following line in the initialization of the Cluster
, which you provided in chat:
alb_controller=eks.AlbControllerOptions(version="latest")
The version
parameter of the AlbControllerOptions
expects an instance of AlbControllerVersion
, not a string.
The correct code would be:
alb_controller=eks.AlbControllerOptions(version=eks.AlbControllerVersion.V2_3_1),
Upvotes: 2