If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
The apt
module is the key to getting so much stuff installed. But, it can do
more than that. When we first boot our server from the Ubuntu image, what guarantees
that our packages aren't completely out of date? Nothing! In fact, I bet a lot of
packages are old and need upgrading.
Check out the apt
module options. See update_cache
? That's equivalent to running
apt-get update
, which downloads the latest package lists from the Ubuntu repositories.
We definitely need that. Then after, to actually upgrade the packages, we can use
the upgrade
option.
Head back to your playbook and add a new task to update the APT package manager
repositories cache. Add become: true
, use the apt
module, and set update_cache
to yes
:
- hosts: vb | |
tasks: | |
- ping: ~ | |
- name: Update APT package manager repositories cache | |
become: true | |
apt: | |
update_cache: yes | |
... lines 11 - 21 |
Remember, yes
and true
mean the same thing.
Cool! Copy that task to create the next one: upgrade the existing packages. Now,
set upgrade
to dist
:
- hosts: vb | |
tasks: | |
- ping: ~ | |
- name: Update APT package manager repositories cache | |
become: true | |
apt: | |
update_cache: yes | |
- name: Upgrade installed packages | |
become: true | |
apt: | |
upgrade: dist | |
... lines 16 - 21 |
There are a few possible values for upgrade
- some upgrade more aggressively
than others.
Find your terminal and run that playbook!
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
The first time you do this... it might take awhile - like several minutes. So go get some coffee and bother your co-workers. And it makes sense that it's slow: our server probably is out of date, so this is doing a lot of work. Thanks to the power of TV, we'll fast-forward.
Yes! The "Upgrade installed packages" task says "changed". It did upgrade some stuff!
Head back to the docs: one of the other values for the upgrade
option is safe,
which I kind of like because it's a bit more conservative than dist
. When we use
safe
, it uses aptitude
, instead of apt-get
. That's important, because not all
Ubuntu images come with aptitude
installed out-of-the-box.
In fact, scroll up a bit. The apt
module has a "Requirements" section. Interesting...
It says that the host - meaning the virtual machine in our case - needs python-apt
,
which our VM has, and aptitude
to be installed for things to work. So far, we think
of modules as standalone workers that take care of everything for us... and that's
mostly true. But sometimes, modules have requirements. And it's up to us to make
sure those requirements are met before using the module.
Open a new terminal tab and SSH into the VM with:
vagrant ssh
Let's see if aptitude is installed:
aptitude
It opens! So it is installed. Hit "q" to quit.
In this case, the requirement is already met out-of-the-box. But in other situations,
in fact, in older versions of this Ubuntu image, you may need to add a task to install
aptitude
via the apt
module.
But now, just set upgrade
to safe
:
- hosts: vb | |
tasks: | |
... lines 5 - 11 | |
- name: Upgrade installed packages | |
become: true | |
apt: | |
upgrade: safe | |
... lines 16 - 21 |
Then, try the playbook again to make sure it's still happy!
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
It didn't make any changes... but it is still happy! We rock!
With repositories cache and packages upgraded, we can go crazy and install everything we need.
So let's add a task to install the Git version control system: we'll use it to "deploy"
our code. Like always, become: true
, use the apt
module, and use name: git
:
- hosts: vb | |
tasks: | |
... lines 5 - 21 | |
- name: Install Git VCS | |
become: true | |
apt: | |
name: git |
I'll move this below cowsay
- but the order between these doesn't matter.
Try this out:
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
It looks like it worked. How could we know? Move over to the terminal tab that's
already SSH'ed into the VM. Run git --version
. Yes!
Back on the apt
docs, there's an option called state
with values latest
,
absent
, present
or build-dep
. This shouldn't be surprising: this module is
a lot smarter than simply running apt-get install
: the module helps guarantee
that a package is in a specific state, like "present" or "absent"... if you wanted
to make sure that a package was not installed.
Add state
to our task, set to latest
:
- hosts: vb | |
tasks: | |
... lines 5 - 21 | |
- name: Install Git VCS | |
become: true | |
apt: | |
name: git | |
state: latest |
Now, instead of simply making sure that the package is present on the system, it will make sure that it's upgraded to the latest available version. This setting is a bit more aggressive - so do what's best for you.
Try the playbook again!
ansible-playbook ansible/playbook.yml -i ansible/hosts.ini
Ok, it didn't make any changes: git
is already at the latest version... which makes
sense... because we just installed it a minute ago. But in the future, when a new
version comes out, our playbook will grab it.
Ok, let's get PHP 7 installed!
Hey Milan,
Haha, probably so :) For sensitive data we'll use Ansible Vault: https://knpuniversity.com/s... - so any sensitive data will be encrypted and safe. But I haven't noticed any sensitive data in this chapter. Am I missing something? What should be behind security here on your opinion?
P.S. Actually, your repository should be private which is some level of security, but I agree, hold raw passwords in repository (even if it's a private repo) is not a good idea at all, but there's Ansible Vault for it which we'll present a bit further ;)
Cheers!
Yo Victor!
Nah, it's not about this chapter at all (at least those security reasons :)). I was kinda asking myself while watching this (so maybe someone could have the same question :)).
Ok, and what about those `playbook.yml` and `hosts.ini` stuff? Those are "project specific" configuration, so I guess those files should be commited and pushed into a repo, right?
Quick question (yes|no) for other guys - if you have specific configuration for project - let's say a connection into your database: `ip`, `port`, `username`, `password` AND some specific configuration for just THIS application (e.g.: installing google.com on your infrastacture with parameter "Chinese firewall"), does this situation can be handled using Ansible vault? :)
Thank you, mate :)
Hey Milan,
Ah, OK :) Anyway, it's a good question to ask yourself.
Yes, you're right, they are project specific, i.e. you "code" playbook tasks for your project, so you need to commit changes.
As far as I understand you I'd say yes. Well, you can save almost anything in the vault - all what you can store in Ansible variables, i.e. password, port, ip, etc, i.e. any scalar values or even arrays. Vault is just another YAML file which holds variables, but this file is encrypted and you need to know the password to decrypt it.
Cheers!
I'm always getting "changed" status for the "update" task, and "ok" for the "upgrade".
Is it ok?
Hey Ivan,
Hm, probably it's due to "update_cache: yes", not sure. Though, I think if nothing were changed - it should be "OK" instead of "Changed". Try to upgrade Ansible to the latest version. Btw, you can always try to execute this task directly, i.e. without Ansible. SSH to the host and run:
$ sudo apt-get update
Maybe the output will give you some tips why it happens.
Cheers!
This is the task:
- name: Update APT package manager repositories cache
become: true
apt:
update_cache: yes
cache_valid_time: 3600```
It's supposed to <em>only</em> run 'update'.
Here's the output when I run manually:
$ sudo apt-get update
Hit http://ppa.launchpad.net trusty InRelease
Ign http://archive.ubuntu.com trusty InRelease
Hit http://archive.ubuntu.com trusty-updates InRelease
Hit http://security.ubuntu.com trusty-security InRelease
Hit http://ppa.launchpad.net trusty/main amd64 Packages
Hit http://archive.ubuntu.com trusty-backports InRelease
Hit http://archive.ubuntu.com trusty Release.gpg
Hit http://security.ubuntu.com trusty-security/main Sources
Hit http://ppa.launchpad.net trusty/main Translation-en
Hit http://archive.ubuntu.com trusty-updates/main Sources
Hit http://security.ubuntu.com trusty-security/universe Sources
Hit http://archive.ubuntu.com trusty-updates/restricted Sources
Hit http://archive.ubuntu.com trusty-updates/universe Sources
Hit http://security.ubuntu.com trusty-security/main amd64 Packages
Hit http://archive.ubuntu.com trusty-updates/multiverse Sources
Hit http://archive.ubuntu.com trusty-updates/main amd64 Packages
Hit http://security.ubuntu.com trusty-security/universe amd64 Packages
Hit http://archive.ubuntu.com trusty-updates/restricted amd64 Packages
Hit http://security.ubuntu.com trusty-security/main Translation-en
Hit http://archive.ubuntu.com trusty-updates/universe amd64 Packages
Hit http://archive.ubuntu.com trusty-updates/multiverse amd64 Packages
Hit http://security.ubuntu.com trusty-security/universe Translation-en
Hit http://archive.ubuntu.com trusty-updates/main Translation-en
Hit http://archive.ubuntu.com trusty-updates/multiverse Translation-en
Hit http://archive.ubuntu.com trusty-updates/restricted Translation-en
Hit http://archive.ubuntu.com trusty-updates/universe Translation-en
Hit http://archive.ubuntu.com trusty-backports/main Sources
Hit http://archive.ubuntu.com trusty-backports/restricted Sources
Hit http://archive.ubuntu.com trusty-backports/universe Sources
Hit http://archive.ubuntu.com trusty-backports/multiverse Sources
Hit http://archive.ubuntu.com trusty-backports/main amd64 Packages
Hit http://archive.ubuntu.com trusty-backports/restricted amd64 Packages
Hit http://archive.ubuntu.com trusty-backports/universe amd64 Packages
Hit http://archive.ubuntu.com trusty-backports/multiverse amd64 Packages
Hit http://archive.ubuntu.com trusty-backports/main Translation-en
Hit http://archive.ubuntu.com trusty-backports/multiverse Translation-en
Hit http://archive.ubuntu.com trusty-backports/restricted Translation-en
Hit http://archive.ubuntu.com trusty-backports/universe Translation-en
Hit http://archive.ubuntu.com trusty Release
Hit http://archive.ubuntu.com trusty/main Sources
Hit http://archive.ubuntu.com trusty/restricted Sources
Hit http://archive.ubuntu.com trusty/universe Sources
Hit http://archive.ubuntu.com trusty/multiverse Sources
Hit http://archive.ubuntu.com trusty/main amd64 Packages
Hit http://archive.ubuntu.com trusty/restricted amd64 Packages
Hit http://archive.ubuntu.com trusty/universe amd64 Packages
Hit http://archive.ubuntu.com trusty/multiverse amd64 Packages
Hit http://archive.ubuntu.com trusty/main Translation-en
Hit http://archive.ubuntu.com trusty/multiverse Translation-en
Hit http://archive.ubuntu.com trusty/restricted Translation-en
Hit http://archive.ubuntu.com trusty/universe Translation-en
Ign http://archive.ubuntu.com trusty/main Translation-en_US
Ign http://archive.ubuntu.com trusty/multiverse Translation-en_US
Ign http://archive.ubuntu.com trusty/restricted Translation-en_US
Ign http://archive.ubuntu.com trusty/universe Translation-en_US
Reading package lists... Done`
On the other hand, the status is marked 'OK' when I run against EC2 instance with Ubuntu 18.04.
Here's a "normal" output from it:
$ sudo apt-get update
Hit:1 http://eu-central-1.ec2.archive.ubuntu.com/ubuntu bionic InRelease
Get:2 http://eu-central-1.ec2.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:3 http://eu-central-1.ec2.archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Hit:4 http://ppa.launchpad.net/ondrej/php/ubuntu bionic InRelease
Hit:5 https://deb.nodesource.com/node_8.x bionic InRelease
Hit:6 https://dl.yarnpkg.com/debian stable InRelease
Hit:7 http://security.ubuntu.com/ubuntu bionic-security InRelease
Fetched 163 kB in 1s (301 kB/s)
Reading package lists... Done```
Ansible already uptodate... so probably the issue is that 14.04 is outdated.
Hey Ivan,
Hm, interesting, probably so, though I see Ubuntu 14.04 LTS support ends on April 2019. So, not sure. Actually it might be a bug in Ansible apt module, because exactly modules are responsible for these "ok|changed|skipped" statuses. Unfortunately, my knowledges in Linux are limited, so not sure how to debug it properly. But I do remember I got "OK" status for the 2nd run of "Update APT package manager repositories cache" step.
Cheers!
I think in this or one of the other videos you say that the order of the items in the playbook is not important? Of course I have to add the PPA first, update apt and than install stuff. So if I am correct order matters and that sentence is miss leading.
Cheers Karsten
Hey Karsten,
Fair point. Well, yes, order matters for related tasks, but if you need to install Nginx, Git, MySQL packages - no matter what would be first, i.e. order does not important between them. But, of course, order is important when you need to upgrade repositories' cache first, and only then install those packages. So it depends... and btw, we haven't added any PPA tasks yet. What about this chapter - we say:
> ... the order between these doesn't matter
i.e. *between* installing Git and "cowsay" packages. So it's fine for me and in this case order really doesn't matter. What about other chapters - I'm not sure, if you will find an example where it misleads you - let us know and we'll add a note.
Cheers!
How Do i know name of the package? I mean how i know it is call name:git not name:git-github
Where can I find those information
Hey again jian su!
Ah, good question! Since the task effectively runs sudo apt-get install git
, the question is really: "When I use Ubuntu, how do I know what the names of the packages are". Honestly, I usually google this to find out quickly. But you can also run apt-cache search git
to search for all packages that have "git" somewhere in the name. That doesn't tell you exactly which one to install, but if you see git
in that list, you probably know that's what you want!
Cheers!
aaahh Yes it makes sense, I just forget I am basically doing the Linux commands in a ansible way. silly me
// 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
}
}
Hey guys,
I am kinda curious about this. I am not 100% sure if it is a good idea to store the deployment information inside your GIT repository (security reasons).
Why am I saying this? Well, let's say you wanna deploy using gitlab-ci environment. I mean - those are sensitive stuff which should not be visible to anyone, right? Am I asking too soon in this course; are you going to talk about this? :)