Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Vagrant <3's Ansible

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Our first big goal is to see if we can use Ansible to setup, or provision, an entire server that can run our MooTube app. To setup an empty VM, we'll use Vagrant with VirtualBox.

So before we start, make sure that you have VirtualBox installed: it's different for each OS, but should - hopefully - be pretty easy. Next, make sure you have Vagrant: it has a nice installer for every OS. On my Mac, surprise! I installed Vagrant via brew.

As long as you can type:

vagrant -v

you're good to go.

Vagrantfile Setup!

If you're new to Vagrant, it's a tool that helps create and boot different virtual machines, usually via VirtualBox behind the scenes. It works by reading a configuration file... which we don't have yet. Let's generate it!

vagrant init ubuntu/trusty64

That just created a file - Vagrantfile - at the root of our project that will boot a VM using an ubuntu/trusty64 image. That's not the newest version of Ubuntu, but it works really well. You're free to use a different one, but a few commands or usernames and passwords might be different!

Tip

If you want to use the latest Ubuntu 18.04 LTS release, you'll need a few tweaks:

1) Change the VM box in Vagrantfile to:

# Vagrantfile
Vagrant.configure("2") do |config|
  # ...
  config.vm.box = "ubuntu/bionic64"
  # ...

Or ubuntu/xenial64 in case you're interested in Ubuntu 16.04 LTS release.

2) Ubuntu 18.04/16.04 requires a private SSH key to be specified instead of a simple password to login via SSH - Ansible can't log in into the server using just a username and password pair. Also, the Ansible user should be set to vagrant. You can specify all this information in the hosts.ini file for the VirtualBox host:

# ...
[vb]
192.168.33.10 ansible_user=vagrant ansible_ssh_private_key_file=./.vagrant/machines/default/virtualbox/private_key
# ...

Make sure to uncomment private_network configuration as we did below in this code block to be able to connect to the 192.168.33.10 IP.

3) Notice, that Ubuntu 18.04/16.04 has the new pre-installed Python 3. In case you have an error related to Python interpreter, specify the path to its binary explicitly as:

# ...
[vb]
192.168.33.10 ansible_user=vagrant ansible_ssh_private_key_file=./.vagrant/machines/default/virtualbox/private_key ansible_python_interpreter=/usr/bin/python3
# ...

4) Ubuntu 18.04/16.04 doesn't come with aptitude pre-installed, so you will need to install it first if you want to use the safe upgrade option for installed packages - we will talk about it later in this course. Just add one new task to your playbook before upgrading:

# ansible/playbook.yml
---
- hosts: vb
  # ...
  tasks:
    # ...
    - name: Install aptitude
      become: true
      apt:
        name: aptitude

    - name: Upgrade installed packages
      become: true
      apt:
        upgrade: safe
    # ...

Boot that VM!

With that file in place, let's boot the VM!

vagrant up

Then... go make a sandwich! Or run around outside! Unless you've run this command before, it'll need to download the Ubuntu image... which is pretty huge. So go freshen up your cup of coffee and come back.

Thanks to the power of video, we'll zoom to the end! Zooooom!

When it finishes, make sure you can SSH into it:

vagrant ssh

With any luck, you'll step right into your brand new, basically empty, but totally awesome, Ubuntu virtual machine.

By the way, Vagrant stores some info in a .vagrant directory. In a real project, you'll probably want to add this to your .gitignore file:

19 lines .gitignore
... lines 1 - 17
/.vagrant/

Setup an External IP Address

Our goal is to have Ansible talk to this new VM. For that, we need a dependable IP address for the VM. Check out the Vagrantfile that was generated automatically for us: it has a section about a "private network". Uncomment that!

72 lines Vagrantfile
... lines 1 - 7
Vagrant.configure("2") do |config|
... lines 9 - 26
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.10"
... lines 30 - 72

This will let us talk to the VM via 192.168.33.10.

For that to take effect, run:

vagrant reload

Tip

If you're inside the VM, for stepping out of it simply run:

exit

That should take just a minute or two. Perfect! And now we can ping that IP!

ping 192.168.33.10

Configuring the new Ansible Host

The VM represents a new host. And that means we need to add it to our hosts file! In hosts.ini, let's keep the local group and add another called vb, for VirtualBox. Under there, add the IP: 192.168.33.10:

... lines 1 - 3
[vb]
192.168.33.10
... lines 6 - 7

We know that as soon as we make this change, we should be able to use the vb host:

ansible vb -m ping -i ansible/hosts.ini

That should work, right? It fails! The ping module does a bit more than just a ping, and in this case, it's detecting that Ansible can't SSH into the machine. The reason is that we haven't specified a username and password or key to use for SSH.

Configuring SSH Properly

To see what I mean, try SSH'ing manually - the machine is setup with a vagrant user:

ssh vagrant@192.168.33.10

Woh! Our first error looks awesome!

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

You may or may not get this error. Since I've used Vagrant in this same way in the past, it's telling me that last time I SSH'ed to this IP address, it was a different machine! We know that's ok - there's nothing nefarious happening. To fix it, I just need to find line 210 of my known_hosts file and remove the old fingerprint. I'll do that and save. Try it again:

ssh vagrant@192.168.33.10

It saves the fingerprint and then asks for a password. The password for the image that we're using is vagrant. That's pretty standard, but it might be different if you're using a different image.

Tip

If you still see an error like:

vagrant@192.168.33.10: Permission denied (publickey).

It seems like the server requires a private SSH key file to be specified. Try to specify it as an identity file:

ssh vagrant@192.168.33.10 -i ./.vagrant/machines/default/virtualbox/private_key

We're inside! So, how can we tell Ansible to SSH with username vagrant and password vagrant? The answer is... not surprising! These are two more variables in your hosts inventory file: ansible_user set to vagrant and ansible_ssh_pass=vagrant:

... lines 1 - 3
[vb]
192.168.33.10 ansible_user=vagrant ansible_ssh_pass=vagrant
... lines 6 - 7

Try the ping again:

ansible vb -m ping -i ansible/hosts.ini

Tip

If you still can't SSH into the Vagrant box with Ansible using a simple username/password pair and continue getting an error like:

192.168.33.10 | FAILED! => {
    "msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"
}

Try to specify the SSH private key instead of password. For this, change the line to:

# ...
[vb]
192.168.33.10 ansible_user=vagrant ansible_ssh_private_key_file=./.vagrant/machines/default/virtualbox/private_key
# ...

Eureka! But, quick note about the SSH password. If this weren't just a local VM, we might not want to store the password in plain text. Instead, you can use a private key for authentication, or use the Ansible "vault" - a cool feature that lets us encrypt secret things, like passwords. More on that later.

But for now, our setup is done! We have a VM, and Ansible can talk to it. Next, we need to create a playbook that's capable of setting up the VM.

Leave a comment!

19
Login or Register to join the conversation
JuanLuisGarciaBorrego Avatar
JuanLuisGarciaBorrego Avatar JuanLuisGarciaBorrego | posted 5 years ago | edited

Hi!
Is possible that you have a error like this when you exec $ ansible vb -m ping -i ansible/hosts.ini:


192.168.33.10 | FAILED! => {
    "failed": true,
    "msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"
}

[Solution]
brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb

2 Reply

Hey Juan,

Hm, that's interesting. As I understand, you are on Mac as me, but I do not have the problem you mentioned. Moreover, I do not have sshpass program installed, but "$ ansible vb -m ping -i ansible/hosts.ini" works well for me without any errors :/ The only ssh-related package I installed with Brew is "ssh-copy-id" - probably that's the key in my case.

Anyway, thanks for sharing your solution with others!

Cheers!

Reply
JuanLuisGarciaBorrego Avatar
JuanLuisGarciaBorrego Avatar JuanLuisGarciaBorrego | Victor | posted 5 years ago | edited

Hello victor , I've published a comment in https://knpuniversity.com/s... but Disqus says that is a SPAM comment!
I don't put any link external or strange thing....

Reply

Hey Juan,

Woops, looks like your message was considered as possible spam by Disqus, probably because it's pretty long ;) No problem, we look over our spam Disqus comments from time to time. I just approved your message.

Cheers!

Reply
JuanLuisGarciaBorrego Avatar
JuanLuisGarciaBorrego Avatar JuanLuisGarciaBorrego | Victor | posted 5 years ago

Oh Thanks!
Yes, a petty long! jeje

Reply
JuanLuisGarciaBorrego Avatar
JuanLuisGarciaBorrego Avatar JuanLuisGarciaBorrego | Victor | posted 5 years ago

Hey Victor,
Yes I'm using a mac.
Cheers!

Reply

In case the`
ssh vagrant@192.168.33.10`
command fails with

Received disconnect from 192.168.33.10 port 22:2: Too many authentication failures for vagrant
Disconnected from 192.168.33.10 port 22```

It means you have too many private keys. Just run the command like this instead:

ssh vagrant@192.168.33.10 -o PubkeyAuthentication=no`

And to overcome the same error with ansible - append this to your ~/.ssh/config:

Host 192.168.33.10
  PubkeyAuthentication no```

I have not found an option to pass this to ansible...
Reply

Hey Ivan,

Thank you for sharing this solution with others!

Cheers!

Reply
Default user avatar

After running into a few issues like getting the error "ValueError: insecure string pickle" using the ansible 2.4.2.0 discovered that it needs the sshpass library installed, you can use homebrew to install it but needed some extra googling to make it work on OS X, https://gist.github.com/aru...

Reply

Hey Vadim,

Thanks for sharing your solution! I'm on Mac, and looks like I don't have sshpass lib installed, but I have never seen the error you mentioned. I have Ansible 2.4.1.0 installed, not sure it's due to patch version difference with your version, so I wonder what did you do to see that error? Thanks!

Cheers!

Reply
Victor Avatar Victor | SFCASTS | posted 5 years ago | edited

Hey @diego82 ,

You share awesome examples with us, thanks a lot! Yeah, "[vb:vars]" is nice solution, I like this way because we don't need to write all the parameters in a one line, so it increases readability! But keep in mind that all those variables apply to the all hosts listed in [vb], which is not a problem for now though.

What about "ansible_python_interpreter" parameter - interesting idea! I haven't tested it yet, does it mean that we don't need to install "python-apt" package at all, right? If so - it's very sweet!

P.S. Nice trick with "host_key_checking = False" ;)

Cheers!

Reply

Haha, don't worry about spamming, we always welcome good comments! ;)

That's great, we'll add a note with a few steps about how to use Ubuntu 16.04 box instead of 14.04 one - thanks to your comments.

Cheers!

Reply
weaverryan Avatar weaverryan | SFCASTS | posted 5 years ago | edited

Yo there!

Thanks for the notes! I have a few questions:

1) On Ubuntu 16.4, was python-apt not already installed (is that why you installed it)? If not, we can add that as one of the first tasks in our playbook :).

2) You're right about there being a slightly better to use this :). We can set the private key in our hosts file:


192.168.33.10 ansible_user=ubuntu ansible_ssh_private_key_file=./.vagrant/machines/default/virtualbox/private_key

Try this out - let me know if it works! And based on your answers, I can add some notes to the tutorial! It would be nice to mention some of the important differences on other versions of Ubuntu.

Cheers!

Reply
Agnes Avatar

This works great! The other way I was getting an error about sshpass not being installed. I'm doing this from the Unix subsystem in Windows 10.

Reply

Awesome, thank you for letting us know this was the right way! :)

Reply
Victor Avatar Victor | SFCASTS | posted 5 years ago | edited

Hey @diego82 ,

Thank you for the kind words! Really, Ansible is much easier than Chef and quite fun )

And yes, we'll do some interaction with AWS like creating EC2 instance with Ansible and deploy app to it at the end of this course, so stay tuned with us ;)

Cheers!

Reply
Default user avatar
Default user avatar Roberto Briones Argüelles | posted 5 years ago

It makes sense to use ansible with Docker, or the dockerfile is the same thing that ansible does?

Reply

Hey Roberto Briones Argüelles!

Good question :). And other people have had the same question - check out my answer here: https://knpuniversity.com/s...

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial is built using an older version of Symfony, but the core concepts of Ansible are still valid. New versions of Ansible may contain some features that we don't use here.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.12
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.0
        "snc/redis-bundle": "^2.0", // 2.0.0
        "predis/predis": "^1.1", // v1.1.1
        "composer/package-versions-deprecated": "^1.11" // 1.11.99
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.8
        "symfony/phpunit-bridge": "^3.0", // v3.1.4
        "doctrine/data-fixtures": "^1.1", // 1.3.3
        "hautelook/alice-bundle": "^1.3" // v1.4.1
    }
}
userVoice