{"id":25,"date":"2018-07-07T07:21:00","date_gmt":"2018-07-07T07:21:00","guid":{"rendered":""},"modified":"2019-04-25T13:36:11","modified_gmt":"2019-04-25T13:36:11","slug":"use-ansible-to-clone-update-private-git-repositories-via-ssh","status":"publish","type":"post","link":"https:\/\/ntlx.org\/de\/2018\/07\/use-ansible-to-clone-update-private-git-repositories-via-ssh.html","title":{"rendered":"Use Ansible to clone &#038; update private git repositories via ssh"},"content":{"rendered":"<p>One of the first things I wanted to do when I started using&nbsp;<a href=\"https:\/\/www.ansible.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Ansible<\/a>&nbsp;was to clone a git repository on a remote machine as I keep configuration, scripts, and source code in github or&nbsp;<a href=\"https:\/\/about.gitlab.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">gitlab<\/a>&nbsp;repositories. Things that are not meant for the public, I store in private repositories that I want to clone via ssh. Cloning and updating them I now want to automate with Ansible.<\/p>\n<p>There are different ways to go for this task:<\/p>\n<ul>\n<li>Checkout the repo locally and copy it to the server via a Ansible&nbsp;<a href=\"https:\/\/docs.ansible.com\/ansible\/latest\/modules\/synchronize_module.html\" target=\"_blank\" rel=\"noopener noreferrer\">synchronize<\/a>&nbsp;task<\/li>\n<li>Generate an ssh key on the server and allow cloning the repo with that key manually<\/li>\n<li>Copy a local ssh key to the server and allow cloning the repo with that key<\/li>\n<li>use ssh-agent to load the local key and forward the agent to the server<\/li>\n<\/ul>\n<div>While it might be tempting to just copy an ssh key via Ansible to the remote server, I find this quite risky,&nbsp; as it means you copy a secret to a persistent storage on a remote server. Also, if you version your Ansible playbooks in a git repository as well to be able to&nbsp;execute the playbook from somewhere else, the private key has to be versioned along with it.<\/p>\n<\/div>\n<div>Using ssh-agent, you can easily load your ssh key prior to provisioning the git repo on the remote server without copying it over, and without allowing access to your repo for a different key than the one you have granted access for development.<\/div>\n<div><\/div>\n<div>Let&#8217;s go through this via a simple example. Let&#8217;s say you want to run the following playbook, which includes ensuring the git repository <i>github.com\/ntlx\/my-private-repo<\/i> is up-to-date.<\/div>\n<div><\/div>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\">1\n2\n3\n4\n5\n6\n7<\/pre>\n<\/td>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\"><span style=\"color: #0e84b5; font-weight: bold;\">---<\/span>\n- hosts: webserver\n  tasks:\n      - name: Ensure repo is up-to-date\n        git:\n            repo: git@github.com\/ntlx\/my-private-repo.git\n            dest: repos\/my-private-repo\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>I assume you added your public ssh key to your github.com repository so you are able to clone and work on the repository locally. To clone the repository on the remote machine, you need to load your ssh-key to ssh-agent with the following command.<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\">\n<pre style=\"line-height: 125%; margin: 0;\">ssh-add ~\/.ssh\/id_rsa\n<\/pre>\n<\/div>\n<\/div>\n<p>Now we need to enable the forwarding of the ssh agent to the remote machine so we can access the loaded key remotely. There are different ways to do so, but I find it most useful to do it in your <i>ansible.cfg<\/i> like this:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\">1\n2<\/pre>\n<\/td>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\"><span style=\"color: #008800; font-weight: bold;\">[ssh_connection]<\/span>\n<span style=\"color: #0000cc;\">ssh_args<\/span><span style=\"color: #333333;\">=<\/span><span style=\"background-color: #fff0f0;\">-o ForwardAgent=yes<\/span>\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>That way, you allow the forwarding for all your Ansible-managed hosts at once.<\/p>\n<p>Now you can go on executing your playbook and should be able to clone the repository on the remote host.<\/p>\n<p>To make it even easier, we can add a task to load the ssh-key before executing the other tasks in the playbook. For this, add the local host to your Ansible inventory:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\">1\n2<\/pre>\n<\/td>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\"><span style=\"color: #008800; font-weight: bold;\">[local]<\/span>\n<span style=\"color: #0000cc;\">local_machine ansible_connection<\/span><span style=\"color: #333333;\">=<\/span><span style=\"background-color: #fff0f0;\">local ansible_host=localhost<\/span>\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Now we can add a small shell task to load the ssh-key:<br \/>\n<!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\"> 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n10\n11\n12<\/pre>\n<\/td>\n<td>\n<pre style=\"line-height: 125%; margin: 0;\"><span style=\"color: #0e84b5; font-weight: bold;\">---<\/span>\n- hosts: local\n- name: load ssh key\n  shell: |\n      <span style=\"color: #003366; font-weight: bold;\">ssh-add ~\/.ssh\/id_rsa<\/span>\n\n- hosts: webserver\n  tasks:\n      - name: Ensure repo is up-to-date\n        git:\n            repo: git@github.com\/ntlx\/my-private-repo.git\n            dest: repos\/my-private-repo\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>When you now execute the playbook, you shouldn&#8217;t need to load the ssh-key before.<\/p>\n","protected":false},"excerpt":{"rendered":"One of the first things I wanted to do when I started using&nbsp;Ansible&nbsp;was to clone a git repository on a remote machine as I keep configuration, scripts, and source code in github or&nbsp;gitlab&nbsp;repositories. Things that are not meant for the public, I store in private repositories that I want to clone via ssh. Cloning and&#8230; <a class=\"view-article\" href=\"https:\/\/ntlx.org\/de\/2018\/07\/use-ansible-to-clone-update-private-git-repositories-via-ssh.html\">Artikel ansehen<\/a>","protected":false},"author":1,"featured_media":138,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[16,15,7,13,11,9,5],"_links":{"self":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/25"}],"collection":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/comments?post=25"}],"version-history":[{"count":2,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/25\/revisions"}],"predecessor-version":[{"id":140,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/posts\/25\/revisions\/140"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/media\/138"}],"wp:attachment":[{"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/media?parent=25"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/categories?post=25"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ntlx.org\/de\/wp-json\/wp\/v2\/tags?post=25"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}