Should rax_clb_nodes exist independently?

The ‘rax’ module was designed initially with the potential of supporting additional Rackspace public cloud products and supports a parameter ‘service’ that would be used to make this selection.

It does however appear as though many of the other modules have independent files for each product, so I am unsure if that should be considered the standard or not.

Regardless, I might also like to see it renamed rax_clb for consistency, and for flexibility of additions to the code base.

Thoughts?

I generally do not think a module should model more than one resource. This simplifies code in most cases and also makes playbooks more self documenting and auditable.

However, the idea of that one module being named “_nodes” did strike me a little odd, so +1 to that for sure.

Yes, let’s definitely have each cloud service split out. Makes it much easier to see what featuers are there, and the automated doc system will generate better docs.

As ec2 has somewhat set precedent, I’m ok with the VM provisioning one still being called ‘rax’.

Ok, that works for me. Should the 1 to 1 ratio of module to model be documented some place? Maybe under ‘Conventions/Recommendations’ for ‘Module Development’? I took a read over this doc, and didn’t immediately see anything about this.

We are performing some other updates to the ‘rax’ module, so we will look into deprecating the ‘service’ attribute. Do you have any recommendations for deprecating an attribute, other than a soft deprecation by way of mentioning that it is deprecated in the documentation?

I won’t have time immediately to send a pull request for renaming rax_clb_nodes, but if it isn’t done before I have the opportunity, I will send one.

ultimately it’s something we enforce by having all the modules work the same way :slight_smile:

I prefer in many cases people to get the feel for things rather than being super verbose.

In this particular case I would suggest

(A) not including the param in the module doc
(B) raising a module.fail_json if the parameter is set telling the user how to do it

Jumping in on this thread since I’ve PRed the rax_network module to create/delete isolated networks.

Last night I hacked together a rax_lb because I needed to create load balancers. Given the presence of rax (service=cloud_loadbalancers), I chose to do a separate module because the amount of options you can pass into the load balancers endpoint via pyrax are sorta crazy and there was no way that was going to go through rax in a sane manner as it is. And of course, also because rax_clb is for adding/removing hosts from an lb, but not for creating them. But I digress.

What I would like to nail down is what our goals for the rax refactor and modules per resource look like in the future.

Let’s run with the lb example. create/delete is easy. adding/removing hosts form it is also easy. But combining the two into a module presents some larger questions.
What if I call state=present to create an lb with an empty set of nodes, but later, I make that call with a list of nodes? Should it ignore it, or update the list? Is that still state=present, or is that state=updated/latest? Same for removing hosts.

In some modules, like rax, when we do state=present, we check to see of the resource by that name/id exists. If it doesn’t, we create it. But we don’t ever update the resource if it already exists. For servers, this is more or less correct since there’s not much to edit/update after a create.

For load balancers on the other hand, many settings can be changed after creation. Port, Protocol, Algorithm, Logging, Error Page, etc.
Is this where a state=latest is appropriate?

More or less, I’d like to throw my hat in the ring and commit some things as I’m working on spinning up some new clients from scratch with servers, lbs, dns, etc. But I’d like to get a good clear direction and where we thing we should be going with 1 module per resource, and creation va updating, etc so I’m not PRing things that will never be accepted.

Thanks!
-=Chris

I am slowly re-thinking this. This morning I was questioning my decision that both functionalities could be part of a single module.

Now, I am back on board with my initial decision.

I think we need to look at rax_clb differently than rax. I think with rax_clb, we should ensure configuration of a single LB instance. If the configuration matches, we do nothing, if it doesn’t we update it to match the configuration.

It still seems viable that a single rax_clb can handle both situations. If you create without nodes, and then add nodes, that should work. If you change protocols, that should work too.

Keep in mind that rax_clb is new in 1.4, and we have time to do what we need to it, within the limits of the release timeframe. But I think rax_clb is probably going to need a rewrite to match our requirements.

What I like about rax_clb is that it can add an ip one at a time to an lb instance, where sometimes it's not practical to know or add them all up front into on nodes: property.

So in my current playbook, I'm creating a private network and register: ing that.
Then I drop servers using that networks cidr and registering those. Then I drop a rax_lb to create it, and register it. Finally I with_items all the servers and drop the servicenet ip into the lb on at a time using rax_clb

With an all in one rax_clb, I can no longer do this since without some other acrobatics to loop the servers to get them into on nodes: property for the rax_clb call.

Updating config makes sense with top level resources (protocol, port, etc) where a change is a change. But for collection type resources (nodes, virtual ups, etc), just because something is missing from the collection doesn't necessary mean I want to removed. Sometimes it does. :-/

I'm not sure what the requirements are. For some people, adding all the data into and creating an lb in one shot is ok for them. Sometimes, it's better suited as an additive process.

Let's compare something like a rax_files, where you have parent and children resources (containers and files). I would expect the container create to not have to also have a files: during create, and add/remove files based upon that one call. Instead I would expect separate modules.

I don't know. I'm also afraid that the more complexity of modules trying to do both parent and child maintenance will lead us to pretty much having a mirror of the pyrax codes complexity.

Chris,

Thanks for the explanation and use case.

Here is what I think we need to do:

  1. Open a new pull to rename rax_clb back to rax_clb_nodes
  2. Open a pull request to add a new module rax_clb that can create LBs. This module should also allow you to add nodes during creation.

How does this sound? This way have both of our bases covered.

That works for me. I’ve got most of that going locally, so I’ll take a crack at a PR this week.

What’s the 1.4 release timeframe?

From what I have heard, we are looking at mid to late November. But I should not be trusted as a reputable source for this information. Someone from AnsibleWorks would obviously be in a better position than myself to answer this question.

Yes, we’re targeting 1.4 for the middle-end of November (before the US Thanksgiving holiday hopefully).

Also, how do you feel about exposing the [credentials] username in the output of the module actions?

I’m currently spinning up entire staging/production stacks in my account (vs. our company account) in a project, and I’d like to name various resources appropriately. For example. when they send out emails from monit, I’d like to tag things with both the environment name (staging, production), machine name (db-master), and the user (claco, my company, etc). Probably also altering host names base on the machine name + the username doing the spinning.

-=Chris