hello. I am having difficulty with how resource i...
# getting-started
s
hello. I am having difficulty with how resource in-place updates work. I am using getVirtualNetwork which has an output of subnets. I proceed to add a new subnet to that virtual network. however the VirtuakNetworkResult subnets do not contain the new subnet. is there a way to reload a resource?
s
It sounds like you’re using Azure. Are all your subnet definitions in-line with the virtual network, or separate? Both ways are supported, but you can’t mix them (you can’t do some in-line and some separate).
s
@salmon-account-74572 yes I am using Azure. sorry I didn't understand what you mean by inline or separate. when I try to output the input output parameters nothing is being outputted. why is that?
subnet = network.Subnet(
subnet_name,
subnet_name=subnet_name,
resource_group_name=resource_group_name,
virtual_network_name=existing_vnet.name,
address_prefix=subnet_prefix
)
subnet.virtual_network_name.apply(lambda v: <http://log.info|log.info>("Subnet virtual network is " + v))
subnet.resource_group_name.apply(lambda v: <http://log.info|log.info>("Subnet esource group name is " + v))
subnet.subnet_name.apply(lambda v: <http://log.info|log.info>("Subnet subnet_name is " + v))
I am getting the virtual network like
if existing_vnet_id not in self.existing_vnets:
self.existing_vnets[existing_vnet_id] = network.VirtualNetwork.get(
f"vnet-{existing_vnet_id}",
id=existing_vnet_id
)
so what I am trying to do is get the VNet, add the first subnet with the next avaialble prefix and then loop again. however on the 2nd iteration of the loop, the VNet subnets are the same as before I created the new subnet.
s
Ah, so this isn’t a virtual network you’re creating in the same Pulumi program?
(With regard to “in-line versus separate”: when you’re defining a virtual network, you have the option of specifying the subnets as part of the virtual network itself, or as separate resources that reference the virtual network.)
s
this is all within one script. let me paste it in it's entirety 🙂 I am trying to configure multiple subnets and have it create the subnet addresses dynamically. the issue with how this works now is that the VNet subnet counts is the same on all iterations so they are all getting the same subnet prefix rather than it getting the next available each time
def _get_available_subnet_prefix(self, subnets, vnet_address_space):
used_ranges = [(ipaddress.ip_network(subnet.address_prefix).network_address,
ipaddress.ip_network(subnet.address_prefix).broadcast_address)
for subnet in subnets]
vnet_cidr = ipaddress.ip_network(vnet_address_space)
for prefix in vnet_cidr.subnets(new_prefix=24):
if all(prefix.network_address < used_range[0] or prefix.broadcast_address > used_range[1]
for used_range in used_ranges):
return str(prefix)
raise Exception(f"No available subnet found in {vnet_address_space}")
for cluster_config in environment['aks_clusters']:
existing_vnet_id = cluster_config.get('existing_vnet_id')
resource_group_name = cluster_config['resource_group_name']
vnet_address_space =  cluster_config['vnet_address_space']
if existing_vnet_id is not None:
if existing_vnet_id not in self.existing_vnets:
self.existing_vnets[existing_vnet_id] = network.VirtualNetwork.get(
f"vnet-{existing_vnet_id}",
id=existing_vnet_id
)
existing_vnet = self.existing_vnets[existing_vnet_id]
existing_vnet.subnets.apply(lambda s: <http://log.info|log.info>("Length of subnets is " + str(len(s))))
existing_vnet.name.apply(lambda n: <http://log.info|log.info>("Virtual network name is " + n))
subnet_prefix = existing_vnet.subnets.apply(lambda subnets: self._get_available_subnet_prefix(subnets, vnet_address_space))
if subnet_prefix is None:
raise ValueError("No available subnet prefix found within the VNet")
subnet_name = f"{team['name']}-{service['name']}-{environment['name']}-subnet"
subnet = network.Subnet(
subnet_name,
subnet_name=subnet_name,
resource_group_name=resource_group_name,
virtual_network_name=existing_vnet.name,
address_prefix=subnet_prefix
)
oh ok, no I am not doing this inline. instead I am trying to add new Subnet resoruces to an existing VNet resource that already exists
so where I am struggling is with how to get the subnets output in VNets to include the newly created one on subsequent iterations.
Subnet address prefix is 10.200.1.0/24 Subnet address prefix is 10.200.1.0/24 the subnet prefix for both subnets is the same. I'd like it so that it is Subnet address prefix is 10.200.1.0/24 Subnet address prefix is 10.200.2.0/24
s
Python is not my forté, but if I am interpreting your program correctly you are looping through to see if a prefix is used and then incrementing it if it is used, is that right?
s
that's correct. the issue is the the VirtualNetwork subnets are always of length 2. so on first iteration it is 2, then on the 2nd iteration I expect it to be 3 (including the newly added Subnet resource we created and assigned to
that's why I was wondering in my initial question how to update the Virtual Network subnets output (do I need to do a refreh?). from what I read it should do an in-place replacement but that doesn't seem to be happening
s
Right, gotcha. What is the desired end-result? Three subnets with address prefixes of 10.100.X.0/24?
s
you got it
if it helps, I can attach the scripts somewhere as well if you'd like
s
No need (for now, anyway). 🙂 First, I’m not 100% sure why you’re seeing the behavior you’re seeing but I suspect it may be related to https://github.com/pulumi/pulumi-azure-native/issues/611 (which reflects a limitation in how the Azure API works). AFAIK the only workaround is to define your subnets in-line (i.e., embedded in the virtual network definition). If your program is creating the virtual network---and I thought you indicated that your program was---then this is pretty straightforward. Does this make sense? Let me know if I’m missing some crucial detail.
s
the virtual network is not being created by the script. it already exists so I am unable to define the subnets inline
so if the virtual network is already created, I want to create multiple subnets on that virtual network with subnet address prefixes of 10.100.X.0/24 which would be based off what's available. to determine that availability I need to know all the subnets for that vnet. after adding the new subnet, the VNet subnets output does not have the new subnet so it continually assigns the same subnet address prefix to all subnets.
so I have an existing vnet ID which I use to get the vnet I want to add subnets to:
self.existing_vnets[existing_vnet_id] = network.VirtualNetwork.get(
f"vnet-{existing_vnet_id}",
id=existing_vnet_id
)
so unfortunaltey I can create them inline. I have to do it by setting the virtual network name when creating the subnet virtual_network_name=existing_vnet.name, from the docs.......
Copy code
subnet = azure_native.network.Subnet("subnet",
    address_prefix="10.0.0.0/16",
    resource_group_name="subnet-test",
    subnet_name="subnet1",
    virtual_network_name="vnetname")
and I am bit more confused as:
Copy code
subnet.virtual_network_name.apply(lambda v: <http://log.info|log.info>("Subnet virtual network is " + v))
                subnet.resource_group_name.apply(lambda v: <http://log.info|log.info>("Subnet esource group name is " + v))
                subnet.subnet_name.apply(lambda v: <http://log.info|log.info>("Subnet subnet_name is " + v)
s
OK, I see (sorry, I must have misunderstood something earlier regarding the Vnet creation).
s
no worries. I am new to all this so I am sure my explanations aren't great lol
Copy code
aks_clusters:
              - name: aks-cluster1
                location: eastus
                organization: cdx
                resource_group_name: Internal-aks-Services-2
                existing_vnet_id: /subscriptions/XXXX-XXXX-XXXXX-XXXXX-b0862310b2cc/resourceGroups/InternalServices/providers/Microsoft.Network/virtualNetworks/InternalServices-vnet
                vnet_address_space: 10.200.0.0/16
                subnet_prefix: 10.200.2.0/24
if I specify the subnet_prefix address in the config and read it in, it works as expected. however, the devops eng asked if we could do it dynamically which is where I am stuck as you can see 🙂
s
Gotcha. Let me ping some folks internally and see if we can brainstorm on some ideas to help get you unstuck.
s
awesome! let me know if you need anything else from me.
@salmon-account-74572 any luck? just wanted to followup before the weekend. thanks for everything.
s
@sparse-iron-45589 Hey John, sorry for the delayed response. I don’t have any additional information yet, but I’ll ping the team again.
@sparse-iron-45589 Hi John, I got a response from one of our engineers. He suggested switching over to the Azure Classic provider to see if that helps. Give that a try and let me know how you get on.