Prerequisites:
Now we want to deploy an application from a git repository. This should be simple but it's not.
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
githost is an entry in our .ssh/config
This above task works. But the repository is (of course) cloned as the user who executed the playbook. What we need instead is:
zaphod
zaphod
is allowed to read the files. We're talking about 0600/0700 permissions.The following task will not work, because by using become
we will lose the forwarded ssh key and therefore git authentication will fail:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
become: yes
become_user: zaphod
The following variation would first call a handler which changes ownership of the checkout before (re)starting the application:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Fix ownership
- Restart app
This works once. But if you run the playbook a 2nd time the git task fails because the user who runs the play does not have permissions to modify the clone.
We have a very ugly solution:
rm -rf /some/location
mv /tmp/foo /some/location
The problem with this is that this would:
I'm a bit picky here, but I do only want to have changed states if something really changed, so in a perfect world not even the git task would have a changed state. And for this I do not see a solution. Because we require that the cloned files are only accessible by zaphod
- but zaphod
himself is not able to clone the repo. So there has to be some manipulation is some form resulting in changes.
Any suggestions how this can be improved in a clean way? I don't want to add another 20 tasks shuffling around with temporary copies, temporarily changing permissions, comparing files manually and so forth...
Of course a custom written module would be able to deal with all this - but I'm more interested in something that does not take 2 days in development and battle testing. ;-)
It looks like you're trying to deploy an application/webpage by simply cloning the repo containing the stuff you need rather than needing to be able to then push any changes back to the repo from that server.
If that's the case then you could get away with a local task to git archive
the repo into a tarball or something and then use unarchive
to copy the resulting archive to the target machine and unpack it. unarchive
will allow you to set the permissions and ownership.
So your play could look something like:
- name: locally clone repo
git:
repo: githost:org/repo.git
dest: /some/tmp/location
version: HEAD
force: yes
delegate_to: localhost
changed_when: false #
- name: archive app repo
command: git archive --format zip --output /path/to/archive master
chdir: /some/tmp/location
delegate_to: localhost
changed_when: false
- name: unarchive app repo
unarchive:
src: /path/to/archive
dest: /some/location
owner: zaphod
mode: 0700
creates: /some/location
notify:
- Restart app