gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
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 README.md
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 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() | |
->findAll(); | |
$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.
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.
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!
Hey @Bartosz!
I agree with you in theory. In practice, it's a bit trickier. This tutorial, unfortunately, is showing its age. The problem with updating the dependences in the code download is that it makes the code diverge from what you see in the video. If the updates were minor, that would be no big deal. But as time goes by, to update the dependencies to have them fully functional would require big changes (upgrades across major versions of packages, possibly replacing some libraries with others, and maybe even changes to the project itself). This is a tricky issue. Our (not perfect) policy is to leave the dependencies as they were when we recorded the tutorial - but to add notes where it makes sense to let people know of changes. But, it definitely means that, eventually, the code downloads from the tutorials don't really work anymore (usually the problem is newer php versions).
Btw, the package you're referring to was an especially crazy situation. That organization simply deleted that repository entirely! Fortunately, it was "saved" and now lives at https://github.com/theofidry/AliceBundle
Cheers!
Hello, what is better use in 2022 Docker, Ansible or maybe anything else for production or test stage?
Hey Maxim,
Hm, it depends on your aims actually. Are you looking for a deploy tool? If so, then the best would be to use PAAS like Platform.sh that along with Symfony CLI allow you to deploy your project easily or create test/dev environments with a copy of prod DB. So, this approach is the best IMO.
Docker isn't a "deploy" tool actually, it's just virtualization tool. To actually deploy a dockerized app you would need to use other tools. But Ansible, in particular, Ansistrano IS a deploy tool, and it's still a good thing to use in 2022 IMO t deploy your projects, or actually, you can use custom Ansible playbooks to automate literally everything that you can do in your console. Because Ansible is an automatization tool.
About Docker as a virtualization tool - it's great, and it has big ecosystem that helps you to deploy your Docker containers easily to prod servers.
So, it's not quite correct to compare all those things because they're different and it depends on what you need.
Cheers!
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!
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: http://symfony.com/doc/curr... . 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: https://knpuniversity.com/s... - 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:
https://knpuniversity.com/s...
But shhh... nobody know about it ;)
Cheers!
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
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. there 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.
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: https://www.ansible.com/blo...
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 platform.sh, a PAAS. So, we're using containers... but indirectly (and we don't really care that we're using containers - we just care about platform.sh's features, and they accomplish these behind-the-scenes with containers).
I hope that helps! Cheers!
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.
Thanks for submitting the PR! I definitely appreciate it - typos are lame :p
https://github.com/knpunive...
Cheers!
Hey jean pasqualini!
> It might be nice to show us how to deploy the image on google cloud in addition to aws and also talk about packer.io
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.
Cheers!
// 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
}
}
Hello,
It would be good if the composer dependencies from
start
folder were updated. Today (2022-09-05) I was trying to recreate it but, seems like package hautelook/AliceBundle is no longer with us (GitHub responsed with 404).Thanks in advance!