0

I am using Ansible to provision a Vagrant environment. As part of the provisioning process, I need to connect from the currently-provisioning VM to a private external repository using an ssh key in order to use composer to pull in modules for an application. I've done a lot of reading on this before asking this question, but still can't seem to comprehend what's going on.

What I want to happen is:

  1. As part of the playbook, on the Vagrant VM, I add the ssh key to the private repo to the ssh-agent
  2. Using that private key, I am then able to use composer to require modules from the external source

I've read articles which highlight specifying the key in playbook execution. (E.g. ansible-play -u username --private-key play.yml) As far as I understand, this isn't for me, as I'm calling the playbook via Vagrant file. I've also read articles which mention ssh forwarding. (SSH Agent Forwarding with Ansible). Based on what I have read, this is what I've done:

  1. On the VM being provisioned, I insert a known_hosts file which consists of the host entries of the machines which house the repos I need:

  2. On the VM being provisioned, I have the following in ~/.ssh/config:

    Host <VM IP>
      ForwardAgent yes
    
  3. I have the following entries in my ansible.cfg to support ssh forwarding:

    [defaults]
    transport = ssh
    
    [ssh_connection]
    ssh_args=-o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=/tmp/ansible-ssh-%h-%p-%r
    
    [privilege_escalation]
    pipelining = False
    
  4. I have also added the following task to the playbook which tries to use composer:

    - name: Add ssh agent line to sudoers
      become: true
      lineinfile:
        dest: /etc/sudoers
        state: present
        regexp: SSH_AUTH_SOCK
        line: Defaults env_keep += "SSH_AUTH_SOCK"
    
  5. I exit the ansible provisioner and add the private key on the provisioned VM to the agent via a shell provisioner (This is where I suspect I'm going wrong)

  6. Then, I attempt to use composer, or call git via the command module. Like this, for example, to test:

    - name: Test connection
      command: ssh -T git@github.com
    
  7. Finally, just in case I wasn't understanding ssh connection forwarding correctly, I assumed that what was supposed to happen was that I needed to first add the key to my local machine's agent, then forward that through to the provisioned VM to use to grab the repositories via composer. So I used ssh-add on my local machine before executing vagrant up and running the provisioner.

No matter what, though, I always get permission denied when I do this. I'd greatly appreciate some understanding as to what I may be missing in my understanding of how ssh forwarding should be working here, as well as any guidance for making this connection happen.

Steve K
  • 387
  • 1
  • 8
  • 22
  • Are you using the `insecure_key` file that Vagrant provides? – OneCricketeer Aug 24 '17 at 02:52
  • No, I've replaced Vagrant's key with my own key. That key is different than the one I need to connect to the external repository, however. – Steve K Aug 24 '17 at 02:54
  • Got it. So, could you send the other key via a template or ansible file module? – OneCricketeer Aug 24 '17 at 02:56
  • So, that's the thing. The key is on the server already. (I do it via a template.) I couldn't figure out how to add the key to the ssh-agent using ansible, so I thought I could add it via a shell provisioner, and then go back to Ansible. But, I think ansible does stuff in its own shell, so it doesn't know about the key. If I run composer from the same shell script provisioner, it works fine. – Steve K Aug 24 '17 at 03:52

1 Answers1

3

I'm not certain I understand your question correctly, but I often setup machines that connect to a private bitbucket repository in order to clone it. You don't need to (and shouldn't) use agent forwarding for that ("ssh forwarding" is unclear; there's "authentication agent forwarding" and "port forwarding", but you need neither in this case).

Just to be clear with terminology, you are running Ansible in your local machine, you are provisioning the controlled machine, and you want to ssh from the controlled machine to a third-party server.

What I do is I upload the ssh key to the controlled machine, in /root/.ssh (more generally $HOME/.ssh where $HOME is the home directory of the controlled machine user who will connect to the third-party server—in my case that's root). I don't use the names id_rsa and id_rsa.pub, because I don't want to touch the default keys of that user (these might have a different purpose; for example, I use them to backup the controlled machine). So this is the code:

- name: Install bitbucket aptiko_ro ssh key
  copy:
    dest: /root/.ssh/aptiko_ro_id_rsa
    mode: 0600
    content: "{{ aptiko_ro_ssh_key }}"

- name: Install bitbucket aptiko_ro ssh public key
  copy:
    dest: /root/.ssh/aptiko_ro_id_rsa.pub
    content: "{{ aptiko_ro_ssh_pub_key }}"

Next, you need to tell the controlled machine ssh this: "When you connect to the third-party server, use key X instead of the default key, and logon as user Y". You tell it in this way:

- name: Install ssh config that uses aptiko_ro keys on bitbucket
  copy:
    dest: /root/.ssh/config
    content: |
      Host bitbucket.org
      IdentityFile ~/.ssh/aptiko_ro_id_rsa
      User aptiko_ro
Antonis Christofides
  • 6,990
  • 2
  • 39
  • 57
  • Thanks for this! I think you've got my intention spot on. I'm doing the same thing you are with the ssh key, the piece I was missing was your second step (which you explained beautifully, by the way). I'll give this a try, report back, and hopefully accept the answer. – Steve K Aug 24 '17 at 10:09