Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

apt Package Upgrades & Requirements

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

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.

update_cache: Updating the Repositories Cache

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.

upgrade: Upgrading Packages

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!

Module Requirements: Installing Aptitude (if needed)

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.

Installing git

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!

Using state: latest

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!

Leave a comment!

13
Login or Register to join the conversation
Milan V. Avatar
Milan V. Avatar Milan V. | posted 4 years ago

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? :)

1 Reply

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!

Reply
Milan V. Avatar

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 :)

16 Reply

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!

1 Reply

I'm always getting "changed" status for the "update" task, and "ok" for the "upgrade".
Is it ok?

Reply

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!

Reply

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 only 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.

Reply

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!

Reply
Default user avatar
Default user avatar Karsten Frohwein | posted 4 years ago

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

Reply

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!

Reply
Default user avatar
Default user avatar jian su | posted 4 years ago

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

Reply

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!

Reply
Default user avatar

aaahh Yes it makes sense, I just forget I am basically doing the Linux commands in a ansible way. silly me

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
    }
}