Ansible approach suggestions: multiple app server deployment with centralized database server

Replies inline…

Thanks for your response, Michael. My responses inline as well.

Replies inline…

I’m writing Ansible configurations to deploy our company’s relatively silo’d web application on a new endpoint - all that is working fine. Part of the deployment, however, is restoring a database to a centralized database server housing one database per web app instance. So basically two commands on the database server (one template module call to modify the restore script, another to actually run it).

Couldn’t the restore script just be made to take parameters? That seems better than templating a script.

Then the ‘script’ module would just work too.

I could probably do that. The database endpoint in this case is Windows running SQL Server. I installed openssh through Cygwin to allow it to be managed by Ansible, if even just a bit. It’s working great for that. So the template I’m using is actually a windows batch file modified and pushed down via Ansible’s template module, then executed via a “command” module call. I haven’t tried another approach to that, so what you’re suggesting here might take those two calls and make them a single call, and easier to manage. I’ll give that a try.

So I have a playbook with two plays - one for the app server deployment (actually three - two for the app server as one or two commands run using sudo and the rest directly as the user) and one for the database server actions.

I’m at a point where the playbook I’ve written will run for a single app server deployment at a time because the “hosts” list for the playbook is always the same - the database server. The hosts setting for the other plays is the group or set of hosts running the app servers, and iterates fine as that set of commands runs per endpoint.

I tried the delegate_to setting and moved the database actions into the plays for the app servers, but that requires SSH authorized_keys on the database server for each app server - which is definitely a pain to maintain. That’s not something I want to do if I can avoid it.

delegate_to runs from the control machine, not the host in the host loop. It is just passed the name of the other machine.

That’s good to know. I’m getting “authentication failed” messages that suggested it was running from the endpoints instead, since I don’t have their SSH keys stored on the database server. I’m not getting enough output from the verbose setting to see what the actual module is seeing, so I can’t verify what the actual problem is beyond that.

However, now that I’m thinking about it, I realize that the message is coming from the fact that my user login is different on the windows machine vs the other endpoints. So I need to match up the usernames, most likely, as I don’t see a way to specify an action to run as a user different than the one specified as part of the play.

If you need to specify a different user, start a new play. There is no limit to how many you start.

Good point. Thanks for the guidance. I knew my head just wasn’t thinking about it in the right way.

Looking at this again. This is basically the approach I was taking in the beginning - a specific play for the database restore. However, using the list of hosts as for the individual app servers (in order to have the play run once per app server deployment) there’s no way to differentiate the user between the play itself and the delegated task.

In my case, I specify user A (valid on app servers, not valid on db server) as part of the play. The play authenticates properly on the app server endpoints but the delegation itself fails - as it’s using the same user A (I’m suspecting) as specified in the play which isn’t valid on the db server. If I reverse that and use user B (valid on db server but not app servers) the play itself fails auth on the app server endpoints, so the tasks never run. I didn’t see an option to specify a user for a delegated task.

Unless you can think of a better way to handle it, I’m still thinking the only way I can really solve this is to keep the database restores as a separate play (to have multiple iterations of the database restore) and create a matching user on the database server such that the same username can log in to both app server and database server endpoints…

Thanks again for the guidance. Helps me make sure I’m not putting myself in a bad spot down the road… :slight_smile:

In my case, I specify user A (valid on app servers, not valid on db server)

as part of the play. The play authenticates properly on the app server
endpoints but the delegation itself fails - as it's using the same user A
(I'm suspecting) as specified in the play which isn't valid on the db
server. If I reverse that and use user B (valid on db server but not app
servers) the play itself fails auth on the app server endpoints, so the
tasks never run. I didn't see an option to specify a user for a delegated
task.

Yep, you should start a new play for the delegation step. It can still
target the same host specs as before.

A playbook can include multiple plays, it's just a list of them, even if it
only has one.

Unless you can think of a better way to handle it, I'm still thinking the
only way I can really solve this is to keep the database restores as a
separate play (to have multiple iterations of the database restore) and
create a matching user on the database server such that the same username
can log in to both app server and database server endpoints...

Yep, there is no problem in doing this.