Upgrading to Composer 2 using Ansible
Tags: ansible, devops
Published: 2020-11-20 13:44:07

A week ago I looked at [upgrading to Composer 2](https://www.garybell.co.uk/upgrading-to-composer-2/) on a couple of machines. The process wasn't as simple as I was hoping, or as what was documented. After that, I was worried about updating it for my Ansible configuration. Afterall, if something doesn't quite work, I lose the ability to deploy my application to the relevant environments.

My Ansible role prior to Composer version 2 was as follows:
```yaml
---
- name: Check if composer exists
  stat:
    path: /usr/local/bin/composer
  register: composer_file
- name: Download Composer
  get_url:
    url: https://getcomposer.org/installer
    dest: /root/composer-setup.php
  when: composer_file.stat.isreg is not defined or not composer_file.stat.isreg
- name: Add composer
  command: php /root/composer-setup.php --install-dir=/usr/local/bin --filename=composer
  when: composer_file.stat.isreg is not defined or not composer_file.stat.isreg
```

Basically, that's check if Composer exists. If it doesn't, download it an install it. Anyone familiar with Ansible and Composer will realise that this won't ensure that all versions of Composer are the same. That could lead to some interesting behaviour (and is hugely bad practice).

The same role can be easily modified to ensure the same version of Composer is used on each server

```yaml
---
- name: Check if composer exists
  stat:
    path: /usr/local/bin/composer
    checksum_algorithm: sha256
  register: composer_file
- name: Download Composer
  get_url:
    url: https://getcomposer.org/installer
    dest: /root/composer-setup.php
  when: >
    composer_file.stat.isreg is not defined or
    not composer_file.stat.isreg or
    composer_file.stat.checksum != 'c3b2bc477429c923c69f7f9b137e06b2a93c6a1e192d40ffad1741ee5d54760d'
- name: Add composer
  command: php /root/composer-setup.php --version=2.0.4 --install-dir=/usr/local/bin --filename=composer
  when: >
    composer_file.stat.isreg is not defined or
    not composer_file.stat.isreg or
    composer_file.stat.checksum != 'c3b2bc477429c923c69f7f9b137e06b2a93c6a1e192d40ffad1741ee5d54760d'
```

Because the Composer project provides the checksum for the version on the [download page](https://getcomposer.org/download/), it's a simple case of specifying the version to install, and checking the version being used matches the expected checksum. If it doesn't, install specified version.

## Deployment Time
With the servers updated with the latest version of Composer, it was time to test the deployment task. It's all well and good having the latest release of a product there, but if it doesn't work when you need it to, it's no good. Set the task running, loads of success and then...

```bash
TASK [Install/update requirements from composer.json] *************************
```

Nothing beyond that. Maybe there's lots going on. A few minutes later...still nothing. Eventually the process timed out. It worked fine before, it's not now. Composer is there (I checked). It's the right version (I checked again). Will it run manually? No!

![Once it was just advice. Not it waits for you to confirm you are an idiot](https://www.garybell.co.uk/content/images/2020/11/composer-warning.png)

**Disclaimer: Bad practice alert!** The servers are within DigitalOcean, and by default the user account is root. Ansible therefore connects as root, and doesn't do any sudo work to get escalated privileges. It's always been bad practice to run Composer as root. But Composer 2.0 waits for an explicit input to confirm you want to run as root.

Fortunately, there's a way around this. Actually, two if you count creating a new user and not running as `root`. Composer nicely provides a `--no-interaction` flag which can be passed. The task for the install is now:

## Conclusion
Upgrading Composer on Ansible was actually easier than when I did it on my local machine. Any issues I came across were simply down to my bad practices rather than an issue with Composer itself. Even then, there's ways around it.

I'll be rolling the change to Composer 2 out to all my servers, but also adding a technical debt issue to stop using root.