# HowtoPacker

Documenation: <https://www.packer.io/docs/index.html>

Packer est un outil permettant de créer des images identiques destinées à
différentes plateformes à partir d'une configuration unique.

# Terminologie

## Builder
Composant permettant de créer une image pour une plateforme donnée. Le résultat
d'un build est nommé un *artifact*.

(Amazon EC2, Azure, Docker, QEMU, VirtualBox, VMWare, DigitalOcean, etc.)

## Provisionner
Composant permettant de configurer une image suite au build.

(Ansible, Chef, Puppet, Salt, Shell, etc.)

## Post-processor
Composant prenant comme entrée le résultat d'un build ou d'un autre post-processor
pour créer un nouvel *artifact*.

**Examples**
- [Vagrant] Créer une box vagrant pour VirtualBox en utilisant l'*artifact* du
builder VirtualBox.
- [Atlas] Envoyer une box vagrant vers Atlas.
- [Docker Tag] Tagger l'image résultant d'un build Docker.
- [Docker Push] Envoyer une image Docker vers un registry (Docker Hub).

## Template
Fichier JSON définissant les paramètres de tous les composants énumérés
précedemment.

**Exemple**
```json
{
  "variables": {
    "atlas_token": "xxxxxxxx"
  },
  "builders": [
    {
      "type": "virtualbox-iso",
      "vm_name": "evolinux-debian-8.7.1-amd64",
      "guest_os_type": "Debian_64",
      "iso_url": "https://cdimage.debian.org/debian-cd/8.7.1/amd64/iso-cd/debian-8.7.1-amd64-netinst.iso",
      "iso_checksum": "453312bf56fc45669fec5ebc0f025ac7",
      "iso_checksum_type": "md5",
      "disk_size": 10240,
      "ssh_username": "vagrant",
      "ssh_password": "vagrant",
      "ssh_wait_timeout": "10000s",
      "headless": true,
      "boot_wait": "10s",
      "http_directory": "preseed",
      "boot_command": [
        "<esc><wait>",
        "auto url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/jessie.cfg <wait>",
        "<enter><wait>"
      ],
      "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now",
      "vboxmanage": [
        [ "modifyvm", "{{.Name}}", "--memory", "512" ],
        [ "modifyvm", "{{.Name}}", "--cpus", "1" ]
      ]
    },
    {
      "type": "docker",
      "image": "buildpack-deps:jessie",
      "commit": true
    }
  ],
  "provisioners": [
    {
      "only": ["docker"],
      "type": "ansible",
      "playbook_file": "./docker.yml",
      "groups": ["ansible-test"]
    },
    {
      "only": ["virtualbox-iso"],
      "type": "ansible",
      "playbook_file": "./playbook.yml",
      "groups": ["ansible-test"]
    }
  ],
  "post-processors": [
    [{
      "type": "vagrant",
      "compression_level": "9",
      "output": "debian-{{user `debian_version`}}-amd64_{{.Provider}}.box",
      "only": ["virtualbox-iso"]
    },
    {
      "type": "atlas",
      "token": "{{user `atlas_token`}}",
      "artifact": "evolix/evolinux",
      "artifact_type": "vagrant.box",
      "metadata": {
        "created_at": "{{timestamp}}",
        "provider": "virtualbox"
      }
    }],
    [
      {
        "type": "docker-import",
        "repository": "evolix/evolinux-base",
        "tag": "latest"
      },
      "docker-push"
    ]
  ]
}
```

## Utilisation

### Valider un template
`$ packer validate <template>`

### Afficher les composants d'un template
`$ packer inspect <template>`

### Lancer un build
`$ packer build <template>`


## Dépannage

## The "metadata.json" file for the box 'evolix/evolinux' was not found.
Afin de passer le résultat d'un *post-processor* à un autre, il est important
de les regrouper dans un array comme un seul *post-processor*.

