john mich
john mich

Reputation: 2873

CDKTF ec2 Recreation with specific private IP address

Problem - I have 3 ec2 vms created in a single stack of CDKTF the plan file looks like below-

resources {
  instances:[{instance 1},{instance 2},{instance 3}]
}

Now I want to delete the instance 3 as I want to change the flavour from amd64 to arm, but I want to preserve the IP.

ASK- How can I pass a count iterative private IP like [none, none, 10.xxx.xx.xxx] resulting in an IP address assignment to my instance 3 and not affecting the instance 1 and 2?

My current code is below-

private_ip = [None,None,'10.xxx.xx.xxx']

instance = ec2.Instance(self.scope_obj,
                        "%s-instance-%s" % (self.app, zone), ami=self.ami, instance_type=self.flavor_name,
                        subnet_id=data_subnet_obj.id, tags=vm_tags, volume_tags=vol_tags,
                        root_block_device=root_volume,
                        count=instance_count,
                        metadata_options=metadata_options,
                        availability_zone=zones,
                        disable_api_termination=disable_api_termination,
                        iam_instance_profile = iam_instance_profile,
                        vpc_security_group_ids = vpc_security_group_ids,
                        key_name = key_name,
                        private_ip = private_ip["${count.index}"]
                        )

Error: TypeError: list indices must be integers or slices, not str

Upvotes: 2

Views: 125

Answers (2)

Rishabh Jain
Rishabh Jain

Reputation: 206

As to what I understand, you already have an infrastructure and using a count.index you want to fetch the IP and attach it to the VM after delete the VM and changing the flavour type.

You can create a map instead of a list and then a terraform variable and do a lookup, check out the code below-

from cdktf import TerraformVariable

private_ip_map_variable = {0:'ip1',1:'10.xx.xxx.xx', 2:'10.90.xxx.xx'}

var = TerraformVariable(self.scope_obj,'varname',default=private_ip_map_variable, type="map(string)")

instance = ec2.Instance(self.scope_obj,
                        "%s-instance-%s" % (self.app, zone), ami=self.ami, instance_type=self.flavor_name,
                        subnet_id=data_subnet_obj.id, tags=vm_tags, volume_tags=vol_tags,
                        root_block_device=root_volume,
                        count=instance_count,
                        metadata_options=metadata_options,
                        availability_zone=zones,
                        disable_api_termination=disable_api_termination,
                        iam_instance_profile = iam_instance_profile,
                        vpc_security_group_ids = vpc_security_group_ids,
                        key_name = key_name,
                        private_ip = "${lookup(var.varname,count.index)}"
                        )

Note- Don't keep private_ip None, else it would not show up in the TerraformVariable object

Upvotes: 1

Daniel Schmidt
Daniel Schmidt

Reputation: 11921

You can either use a classic python for loop over your values or you can use an iterator to use the for_each property with. I would personally choose the for loop if you are not looping over hundreds of items, even though the terraform state gets a bit bigger it's easier to handle from my point of view.

Upvotes: 1

Related Questions