I am trying to figure out how to copy a cert file generated on a specific host (ca-server) to the list of hosts defined in the playbook. The scenario is something like this:
- using delegate_to go to the ca-server and generate the client cert (stored locally on the ca-server)
- copy the client cert to local
- push cert file to all targets in the play
using the “standard” modules, copy, fetch, synchronize etc. all seem to want to copy the file from local to the targets or fetch from the targets to local. I do not have direct ssh access from the ca-server to the targets so cannot use “delegate_to” to copy as this appears to execute on the ca-server and tries to connect from there to the targets.
copy: issue here is that it copies from local to the targets unless you define remote_sec as true in which case it is all on the target.
fetch: tries to pull from targets, if delegate_to is used it tries to pull from the targets directly to the delegate
synchronize: requires direct access from ca-server to the targets
The following is the short version of what I am trying to do…
command: “do stuff, execute custom script etc.”
delegate_to: ca-server
- name: copy the p12 file locally
this is where I am trying to figure out how to grab the file from the ca-server
fetch (or something like this): >
dest=ssl-certs
src=“/foo.p12”
- name: copy the cert file to the targets
copy: >
dest=/etc/ssl/certs/
src=“ssl-certs/foo.p12”
There may be an obvious answer here as I am pretty new to ansible but I havce bounced this off of a couple of people I know and it stumped them as well…
Thanks for any help.
Gordon
looks fine, if you want to avoid copying the cert to disk you might want to switch to slurp and template to generate the copy.
Are you trying to generate one cert that is then used on all servers or generate individual certs for each server?
It seems that you are saying that you want to...
1) generate a single cert on the ca server
2) copy that to the ansible server
3) copy that cert to all of the other servers
If that is correct wouldn't it be best to have one pair of tasks to do 1 and 2 only on the CA server and 3 on the other servers.
Note that the cert will be different every time this is run so it will never not change. Splitting into two separate sets would allow the cert creation to be run independently from copying it out, and keep the cert push to only changing when the cert changes. An alternative would be to use creates to ensure the cert isn't recreated every time.
If the goal is to have a different cert for every host you should be able to just delegate the cert creation task and the fetch task to the ca server.
Brian, the issue is that it does not work
let me map it out another way. there is a host that is the certificate authority and certs are generated and signed on this host using a script. this host is pretty locked down and has no direct access to the rest of the infrastructure via SSH. The controller (where the playbook is invoked from) will have access to both the cert server and the targets but the targets and the ca server have no direct access.
So the signed cert gets generated doing this:
- name: Generate the p12 cert
command: “do stuff, execute custom script etc.”
delegate_to: ca-server
and now I have a cert sitting on the ca server in a file I need to copy to the hosts defined in the playbook. Fetch will pull files from the targets and delegate_to just changes where the fetch gets invoked. What I need to do it copy from the ca-server to local to targets.
Make sense?
so, realistically you are saying that a delegated fetch does not do what is expected but a delegated command does.
My understanding is that delegate effectively changes the target, so fetch with delegate should involve the ansible host pulling the certificate from the ca server. If this is not the case then it seems to be a bug.
My under standing of delegate_to means “run the command you would have run locally on this particular host”, yes? Delegating the command says “run this particular command on this particular host” and a delegated fetch says “run this fetch but run it from this particular host”, I may be totally off here as I only started working with Ansible a few weeks ago but that is the behavior I am seeing.
I would disagree with your summary, but I think you are right...
We have three hosts in the equation. The machine we are running ansible on (ansibleServer) the machine we are performing tasks on (inventoryServer) and a delegate machine (delegateServer)
- task: blah blah blah
would cause ansibleServer to run a task on the inventoryServer
- task: blah blah blah
delegate_to: delegateServer
should cause ansibleServer to run the task on the delegateServer on behalf of the inventoryServer.
So
- fetch: ...
delegate_to: delegateServer
SHOULD fetch a file from delegateServer to ansibleServer rather than from inventoryServer.
If not then there is a bug in my opinion.
incorrect, its
: command i would have run on 'inventory_hostname' run on 'delegate_to'
host instead
I apologize for the delay in responding to this. I will revalidate this but the fetch+delegate_to appears to pull a file from the inventoryServer to the delegateServer. I will post output as soon as I have it.
So apparently I was doing something wrong. As Adam indicated it should be, it all just works now…
Running a simple case test:
- hosts: some_host
become_user: root
become_method: sudo
tasks:
- fetch: >
dest=/tmp/foo
fail_on_missing=yes
src=/tmp/foo.txt
delegate_to: delegateHost
it indeed pulls the right file from the right place.
Thanks for you help!