Packer: Ansible remote provisioner: support -R port forwards

Created on 8 Nov 2018  ยท  8Comments  ยท  Source: hashicorp/packer

I can't use packer's ansible remote provisioner for AMI images because the -R port forwards are not passed through to the target.

My private yum repository is only accessible from my local network. When creating servers, I typically do the equivalent of ssh -R 3128:myproxy.example.com:3128 [email protected] yum install mypackage after setting proxy=http://127.0.0.1:312 in /etc/yum.conf.

For my ansible playbooks, I usually set ansible_ssh_common_args: '-o "RemoteForward 3128 myproxy.example.com:3128"'. Here is my provisioner setup:

  "provisioners": [
    {
      "type": "ansible",
      "playbook_file": "./playbook.yml",
      "user": "centos",
      "ansible_env_vars": [ "ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes'",
         "ANSIBLE_HOST_KEY_CHECKING=False",
         "ANSIBLE_NOCOLOR=True"
      ],
      "extra_arguments": [ "-vvvv", "--ssh-extra-args", "-R 3128:myproxy.example.com:3128" ]
    }
  ]

I can see that the -R is passed to SSH on the command line, but I don't see how this would work unless packer/provisioner/ansible/adapter.go is modified to support port forwarding.

amazon-ebs: <127.0.0.1> ESTABLISH SSH CONNECTION FOR USER: centos
    amazon-ebs: <127.0.0.1> SSH: EXEC ssh -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o Port=50029 -o 'IdentityFile="/var/elided/ansible-key684742160"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no
-o User=centos -o ConnectTimeout=10 
-R 3128:myproxy.example.com:3128 127.0.0.1 
'/bin/sh -c '"'"'rm -f -r /home/centos/.ansible/tmp/ansible-tmp-1541697992.3238761-84874170372345/ > /dev/null 2>&1 && sleep 0'"'"''
community-supported plugin enhancement help wanted provisioneansible-remote

Most helpful comment

Actually, builds of that PR can be found at https://circleci.com/gh/hashicorp/packer/8168#artifacts/containers/0 for you to download :) . No need to compile yourselves if you want to test this out.

All 8 comments

Thanks for this suggestion! The Ansible provisioner is one of our community-supported provisioners, which means that the HashiCorp maintainers don't spend much engineering time on it; this means that the best way to see your suggestion make it into Packer is to open a PR. We'll gladly give support and pointers if you're interested in taking a shot at it.

Hello,
You can workaround that with qemu args:
"-netdev",
"user,id=mynet0,",
"hostfwd=tcp:127.0.0.1:3128-127.0.0.1:3128,hostfwd=tcp::{{ .SSHHostPort }}-:22",
""
],

@SwampDragons thanks for the response. I'd love to take a shot at it! I'm pretty green so pointers on where to get started are appreciated. Would you recommend adding a Provisioner Config element RemotePortForwards []string `mapstructure:"ssh_remote_forwards"`? Is the magic io.Copy going to happen in the communicator? Should I add support for the "forwarded-tcpip" channel type to adapter.go? RFC 4254 and I are going to become friends.

Thanks for the note, @pmontanari! @rgm3 is using the Amazon builder, not qemu, so that solution won't work for them, but it's always good to have records of workarounds.

@rgm3 That config element seems good.

Is the magic io.Copy going to happen in the communicator

Where? I'm not following which io.Copy you're looking at.

the forwarded-tcpip approach seems right but I'll admit this is a bit outside of my wheelhouse.

So I'd like to change the conversation a bit. I don't believe this is an Ansible specific issue. Ansible is just hitting the localhost and getting bounced to the instance via the go/ssh communicator in packer. The OP just reported it using Ansible but as far as I can tell, there is no mechanism in the ssh communicator to configure port forwarding. This issue would also happen if one was trying to forward any port using just a shell provisioner.

I think the feature request should be changed to reflect it's a core issue, not a plugin. Adapter simply does not support RFC 4254 forwarding channels (as previously mentioned by @rgm3). I for one would like to see this capability added as it would significantly ease provisioning (in AWS for instance) for Enterprise environments where internal repositories (git, yum, etc) are unavailable for direct access.

It would also enable accessing the instance's services with local tooling which would likely have greater capabilities. For instance local-exec of python3 program that hits some localhost:8080 on the centos6 instance for manipulating an API.

Perhaps something akin to this:

  1. Forward a port on my build host to a daemon on the instance (Consul for instance).
  2. Forward's the instance's localhost:8888 to a daemon running on my machine. (tinyproxy in my case).
{
  "builders": [{
    "type": "amazon-ebs",
    "communicator": "ssh",
    "ssh_username": "centos",
    "ssh_local_forwards": ["9000:localhost:8500"],
    "ssh_remote_forwards": ["8000:localhost:8888"]
   }],
   "provisoners": [{
      "type": "shell":
      "inline": ["yum pretend-install consul", "systemctl start consul.service"],
    }, {
      "type": "shell-local"
      "inline": ["./magic-script-to-initialize-consul.py --consul=http://localhost:9000/"]
    }]
}

Edit: I updated the example to be even more contrived. But I think it makes it clear this is not an issue specific to Ansible.

The mentioned pull request I think addresses this issue (which applies to all SSH communicator based provisioners). Give it a try, I'd be interested in seeing feedback. Though you'll need to compile packer yourself. See below for URL to download

Here's a modified version of the OP's sample template:

  "builders": [{
        "ssh_remote_tunnels": ["3128:myproxy.example.com:3128"],
  }],
  "provisioners": [
    {
      "type": "ansible",
      "playbook_file": "./playbook.yml",
      "user": "centos",
      "ansible_env_vars": [ "ANSIBLE_SSH_ARGS='-o IdentitiesOnly=yes'",
         "ANSIBLE_HOST_KEY_CHECKING=False",
         "ANSIBLE_NOCOLOR=True"
      ]
    }
  ]

Actually, builds of that PR can be found at https://circleci.com/gh/hashicorp/packer/8168#artifacts/containers/0 for you to download :) . No need to compile yourselves if you want to test this out.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings