Hello Ansible!

Welcome automation lovers!!! You've come to the right place, because this tutorial is all about Ansible! And boy, it's just a lot of fun. Imagine if we could take control of an army of tiny, but mighty robots... simply by writing a YAML file. Think of the servers we could launch! The infrastructure we could build! The code we could deploy! The laundry we could wash! Well, actually, these Ansible robots are sorta virtual robots, so yes to automating things like server setup... but probably not to automating your laundry. However, I do hope one of you proves me wrong!

To be the best robot overlord you can be, download the course code from this page and code along with me! After unzipping the file, you'll find a start/ directory, which will have the same code that you see here. Follow the file to get your project up and running. Well actually, setting up the project isn't that important, because we will ultimately use Ansible to do that! But if you want to see things working now follow that file. The last step will be to go into your terminal, move into the directory, and run

php bin/console server:run

to launch the built-in PHP web server. In your browser, open up http://localhost:8000. Introducing, our new side project here at KnpUniversity: MooTube! Yes, far too many cows are out of shape and need some serious exercise! So in case this whole tutorial business falls through, we'll turn to bovine fitness: a subscription-based service to keep cows in tip-top shape.

The App & Our Mission!

The first version of our app is done actually! But there are two problems. First, we'd love to have a way to easily boot up development servers complete with PHP, a web server and anything else we need to get our app working. And second, it would be bananas if we could have an automated way to deploy code to Amazon EC2 servers. Well, that's exactly what we're going to do.

Our project is a Symfony application... but if you're not used to Symfony, that's no problem. From a server-perspective, the app requires a few interesting things:

... lines 1 - 9
class DefaultController extends Controller
... lines 12 - 14
public function indexAction()
$videos = $this->getVideoRepository()
$tags = $this->getUniqueOrderedTags($videos);
// Redis cache
try {
if ($this->getRedisClient()->exists('total_video_uploads_count')) {
$totalVideoUploadsCount = $this->getRedisClient()->get('total_video_uploads_count');
} else {
$totalVideoUploadsCount = $this->countTotalVideoUploads();
$this->getRedisClient()->set('total_video_uploads_count', $totalVideoUploadsCount, 'ex', 60); // 60s
... lines 29 - 35
} catch (ConnectionException $e) {
$totalVideoUploadsCount = $this->countTotalVideoUploads();
$totalVideoViewsCount = $this->countTotalVideoViews();
return $this->render('default/index.html.twig', [
'videos' => $videos,
'tags' => $tags,
'totalVideoUploadsCount' => $totalVideoUploadsCount,
'totalVideoViewsCount' => $totalVideoViewsCount,
... lines 48 - 109

First, it needs a database connection to load the video info. And second, it uses Redis to cache a few things. So when we boot up our servers, that stuff needs to be there.

Introducing Ansible

There's a good chance you've setup a server before. I know I've setup a ton, and it's always the same, manual, error-prone, confusing process: SSH into the server, manually run a bunch of commands, have errors, Google things, run more commands, and edit a bunch of files.

Ansible... kinda does the same thing. When you execute something with Ansible, it ultimately SSH's onto the server and runs some commands. Ansible is said to be "agentless", which just means that you don't need to install anything on the target server. As long as you can SSH to a server, you can unleash your Ansible robot army onto it. That's pretty cool.

But Ansible is even more interesting than that. When you execute an Ansible task - that's what they're called - it is idempotent... well, usually it is. Idempotency is an obscure - but cool - word to mean that Ansible tasks don't just dumbly run a command. What they really do is guarantee that the server finishes in a specific state. For example, if we tell Ansible to create a directory, it doesn't necessarily mean that it will run a mkdir command. Instead, it means that Ansible will just make sure that the directory exists - only creating it if necessary.

This idea of guranteeing a "state" - like "this directory must exist" - is much more powerful than randomly running commands over SSH. These tasks also send back JSON info about what happened, which we can use to tweak and influence what happens next.

Installing Ansible

Ok, let's start playing already! First, we need to install Ansible of course! Since I'm on a Mac, I've already installed it with: brew install robotarmy. I mean,

brew install ansible

If you're on different system, check out the Ansible docs for your install instructions. Unfortunately, if you're using Windows, you can't use Ansible. Well, you can't natively. If you're virtualizing a Linux machine or are using Windows 10 with the Linux subsystem, then you can install Ansible there.

Once you've got it, run

ansible --version

to make sure you have at least version 2.0.

Ok team, let's boot up our robot army!

Leave a comment!

  • 2017-07-03 Jacobo Quiles Reina

    Hi Victor! Thanks for the explanations.
    I really can't wait for the Ansistrano top secret shhhh tutorial hahaha

    Meanwhile I will learn more about Behat

  • 2017-07-03 Victor Bocharsky

    Hey Jacobo,

    Thanks for the kind words about this tutorial, we glad you really love it!

    Yea, good question! Actually, you need to test your application with some tools and there're the most popular one: PHPUnit. You probably know that this tool mostly is used for unit testing, but you can also use it to do some functional testing, i.e. do requests and validate responses in your tests. Actually, take a look at Symfony docs how to do it for Symfony applications: . But this requests are headless, i.e. requests are performed programmatically, not in a real web browser.

    And we love Behat! This is amazing tool and we actually use both PHPUnit and Behat tools on KnpU for testing. The awesomeness of Behat is that it tests your application in a real browser like Google Chrome or Firefox thanks to the Selenium Server! And what is a really nice, with Behat you even can tests JS features on your website like the popup is open, DropDown JS menu is expanded, etc. There's so much to tell about Behat, so probably you better to see our screencasts about it: - I bet you'll love this tool.

    So, if any of your tests: PHPUnit or Behat tests - are failed, you just do not need to deploy this code at all. But if they are all passed - cool! Deploy the code which works! So probably you even do not need rollbacks for this workflow :)

    P.S. We're going to release a new top-secret tutorial about Ansistrano (Deploy and rollbacks) very soon:

    But shhh... nobody know about it ;)


  • 2017-06-30 Jacobo Quiles Reina

    Amazing tutorial! I am really fascinated about all these CI approaches.

    I am wondering, how would it be possible to use Ansible along with some kind of system that would check that the PHP code runs as expected? I was thinking about maybe Behat, but is there any better option?

    What I would like to achieve is, before I deploy my code in prod server, have something in the middle that would check that different code flows are not returning an error code, or contains an expected text..., if there is an error, automatically rolls back to previous state (I think Ansistrano can do that).

    For example, test that homepage.php is showing the Welcome text, or check that the login.php actually logs the user in...

    Please any guidance on what tools/approaches would be really appreciated.

    Thank you!

  • 2017-06-26 weaverryan

    Hey jian su!

    > It might be nice to show us how to deploy the image on google cloud in addition to aws and also talk about

    That's an awesome idea! I've added it to our idea list! I can't promise we'll get to it (there are a lot of things to talk about), but it sounds really neat and useful! I like the idea of building your machine once, and then creating an image that can be easily re-used and booted.


  • 2017-06-25 jean pasqualini

    il pourrais être sympa de nous montrer comment déployer l'image sur google cloud en plus de aws et également de parler de :)

  • 2017-05-18 jian su

    Thank you for clarifying and the good article too! Cheer!

  • 2017-05-17 weaverryan

    Hey jian su!

    This is a *great* question. First, I do think containers are the future. But, I'm not sure what that's going to mean for most users. You of course can already today use Docker with Swarm or Kubernetes and get a great setup. But from personal experience (we tried to switch our entire architecture to Docker and failed), it's still technically very challenging. If you have the will, time and expertise, going to a Docker setup might be a great idea. Also, I haven't played with it specifically, but Ansible is currently pushing the idea that it can be used to provision your Docker containers, instead of a docker-compose. Here's an interesting article about that:

    So I think Ansible is great - and even with the rise of containers, I'm not sure it's going away (and certainly not any time soon). But, containers are the future. But for us at KnpU, "containers are the future" means something different: we deploy via, a PAAS. So, we're using containers... but indirectly (and we don't really care that we're using containers - we just care about's features, and they accomplish these behind-the-scenes with containers).

    I hope that helps! Cheers!

  • 2017-05-16 jian su

    If my goal is to deploy my app to AWS, What are differences between ansible and docker? People are using docker a lot more than ansible recently. I know with an Ansible Playbook, you can then reproduce your environment in Docker, in Vagrant, on a cloud instance of your choice. with docker you ll need a lot less if any ansible. Especially with swarm and infakit. weaverryan you are creating a great courses this is for sure. I just want to know if docker is the future, I want to spend most of my time focus on one tools, especially there are lots tools and noise out there and do the same thing.

  • 2017-05-01 weaverryan

    Thanks for submitting the PR! I definitely appreciate it - typos are lame :p


  • 2017-05-01 J.R. Jenkins

    I realize you are still deploying this, but I believe you have a broken link in the Installing Ansible section where you are trying to refer people to the Installation instructions. I am not entirely sure how you are integrating GitHub into these scripts so while I submitted a PR I wanted to mention that it looks like you just have an extra set of [] around the installation key in your markdown in case that isn't the correct method.