This message was deleted.
s
This message was deleted.
b
I use conceptual names referring to the purpose of the resource. If I have an s3 bucket that is for shared files than I will call it
shared-files-bucket
. If that bucket is a child resource of a
ComponentResource
that I implemented than I prefix it with the name provided to that component resource. So then it would be
{name}-shared-files-bucket
. This would remain unique as long as the name of the component resource is unique, which is already a constraint. If you are creating servers, presumably each server has a purpose. Presumably each security group is created for a reason. Presumably each rule has a specific function. I don't think you should be "generating" names because you know what you are using the resource for at the time that you are writing the IaC
i
I know what the servers are for. I know what the security groups are for. But, say, you create 5 loadbalancers
lb-{1..5}
and 20 app servers
app-{1..20}
. You create security groups, to allow access to say port 80 on each of
app
servers. Then you create security rules, one per each IP of loadbalancer. And each of those rules needs to have a unique name.
(yes, I know in this scenario you could just allow members of a security group. But that doesn't work for machines in other availability zone or region, at which point you need to use IPs)
And I don't think lovingly handcrafting a name for each SecurityGroupRule in every SecurityGroup for each of the source IPs is the way to go. Especially since you'll need to lovingly handcraft them again when you change the number of sources.
b
I think maybe you need to consider making encapsulated grouping of resources via a component resource implementation so you can constrain the scope of your resources more easily, thus scoping the naming of your resource more easily
so you have
app-1
and
app-1-sec-grp
and
app-1-sec-grp-rule-lb-1
etc
i
Do you have a link handy for a starting point for that?
that anchor tag kind of sucks but was trying to link you to the "Component Resources" section
i
Yeah, thank you 👍
Or a description closer to the actual scenario: I have a set of 3 servers:
api
,
clientA
and
clientB
, in two regions, and I need all 6 IPs to be able to reach the API port on both
api.region1
and
api.region2
b
do you have this functioning yet? do you have like a chicken-and-egg scenario where
api.region1
needs to know the IP address for
api.region2
but
api.region2
hasn't been deployed yet so you don't know the IP?
or do you have it functioning and you're just trying to organize your pulumi?
a
For the chicken and egg problem I always create the security groups beforehand so that they can reference each other.
b
that works of course unless he needs the actual IP addresses for config, in which case I was going to suggest using some kind of service discovery instead of inputting the IP addresses - and then order wouldn't matter at all. But that's why I asked
And I don't think lovingly handcrafting a name for each SecurityGroupRule in every SecurityGroup for each of the source IPs is the way to go. Especially since you'll need to lovingly handcraft them again when you change the number of sources.
I missed this bit but you wouldn't need to change the names if you are declaring your resources in a loop. You would just need to change how many times the loop should iterate Like your component resource doesn't need 5 load balancer IP inputs, it could iterate on a list of them and when the number of sources changes the pulumi resources (and their names) will reflect that
i
The issue is that
.apply
does manage to get the IPs out at execution time, so that part is working. But it requires unique names for each of the SecurityGroupRules, and for those you cannot use properties of defined objects (since using names was the obvious thing to try)
And security groups referencing each other doesn't work across regions, so I do need IPs
But as I said above, I am able to get the IPs, that's not the issue - providing unique names to the resources is the issue.
b
You know how many IPs you have in that collection though. So you can do this:
Copy code
for (int i =0; i < 6; i++) // the number of IPs
{
    var ipAddress = ipAddresses.GetAt(i);
    var securityGroup = new SecurityGroup("{name}-sec-grp-{i}", {...});
    var securityGroupRule = new Rule("{name}-sec-grp-rule-{i}", {...});
}
now obviously it sucks that you can't do
ipAddresses.Length
in order to limit the loop to how many IP addresses you have programmatically, since
OutputList<T>.Length()
can't be used there - but when the number of IP addresses you have changes it is still better to have to simply change that number than to mess with large blocks of duplicate code.
i
I worked about it differently, though in a similar way: I set a variable
COUNTER=0
before I create everything, increment it after creating each resource, and use it in the names. But then when more machines appear, suddenly the numbers in names don't match, and pulumi is convinced it needs to change the IPs in the rules for stuff to match. And for example OpenStack really doesn't like you trying to create two exactly same rules as it adjusts things, throwing an error and thus erroring out pulumi run.
b
Interesting. Can you clarify what you mean by this: "But then when more machines appear, suddenly the numbers in names don't match, and pulumi is convinced it needs to change the IPs in the rules for stuff to match."
like it is a function of your application that more machines are "appearing" and the stack needs to recognize them, or something? Or some property is changing that pulumi is unaware of so it is seeing it as something it needs to update?
i
I mean when I create more machines. Because recently I only had
api
and
clientA
, but now turned out I also need
clientB
in each region.
b
ah so you added a new machine, and more IP addresses were needed, and since ordering wasn't preserved and those IP addresses weren't appended to the end of the collection - now the numbers don't match the IPs that they used to be, and pulumi is thinking it needs to update those other resources?
i
Yeah
b
what if before doing your loop you did
var sortedIpAddresses = ipAddresses.Apply(x => x.Sort());
that way ordering was preserved?
hmmm that wouldn't work either
i
Let me see how much work it would be to sanitize the project so I can share it
b
It might be that in this case you need to allow those rules to be recreated/updated. I mean presumably it's not like you are adding a new machine on every up call right, this is you going in and modifying the pulumi stack. So it may just be the cost of having pulumi manage this infrastructure. Is there other resources outside of the stack that also depend on those resources? Like referencing them directly?
i
I have no problem with those rules being recreated/updated. It's OpenStack that does, because Pulumi is trying to create a rule "10.20.30.40 is allowed to access port 8443" because of this reordering stuff when there already exists a rule "10.20.30.40 is allowed to access port 8443" - which OpenStack doesn't allow to do.
b
hmmm does the pulumi resource option to
DeleteBeforeReplace
help with that?
i
It helped with some, but not with all cases of that
b
probably when there is the mismatch it is still an issue
what if you put the rules into a component resource, and you name the component resource
{name}-{number-of-ips}
and then when the number of IPs changes, That component can be destroyed in it's entirety (all rules) before it is created again
that might not work either if pulumi in parallel decides to create the new one. hmm sorry dude just spitballing lol
i
That's more than I had ;) I'll try to look at the component resources, though I'm not sure I'll have a chance to work much more with this particular project