How to Deploy Apps Effortlessly with Packer and Terraform

Posted on 9 August 2018 by Alberto Roura.
alibaba cloudalicloudaliyuntech share

Alibaba Cloud published a very neat white paper about DevOps that is very interesting to read. It shows how “DevOps is a model that goes beyond simple implementation of agile principles to manage the infrastructure. John Willis and Damon Edwards defined DevOps using the term CAMS: Culture, Automation, Measurement, and Sharing. DevOps seeks to promote collaboration between the development and operations teams”.

This means, roughly, that there is a new role or mindset in a team that aims to connect both software development and infrastructure management. This role requires knowledge of both worlds and takes advantage of the cloud paradigm that nowadays grows in importance. But DevOps practices are not limited to large enterprises. As developers, we can easily incorporate DevOps in our daily tasks. With this tutorial you will see how easy is to orchestrate a whole deployment with just a couple of config files. We will be running our application on an Alibaba Cloud Elastic Compute Service (ECS) instance.

What Is Packer?

Packer is an open source DevOps tool made by Hashicorp to create images from a single JSON config file, which helps in keeping track of its changes in the long run. This software it’s cross-platform compatible and can create multiple images in parallel.

If you have Homebrew, just type brew install packer to install it.

It basically creates ready-to-use images with the Operating System and some extra software ready to use for your applications, like creating your own distribution. Imagine you want Debian but with some custom PHP Application you made built-in by default. Well, with Packer this is very easy to do, and in this how-to, we will create one.

What Is Terraform?

When deploying we have two big tasks to complete. One is to pack the actual application in a suitable environment, creating an image. The other big task is to create the underlying infrastructure in where the application is going to live, this is, the actual server to host it.

For this, Terraform, made by the same company as Packer, Hashicorp, came to existence as a very interesting and powerful tool. Based in the same principles as Packer, Terraform lets you build infrastructure in Alibaba Cloud by just using a single config file, in the TF format this time, also helping with versioning and clear understanding of how all the bits are working beneath your application.

To install Terraform and the Alibaba Cloud Official provider, please follow the instructions in this other article.

What We Want to Achieve

As mentioned at the top of the article, we are going to create and deploy a simple PHP application in a pure DevOps way, this is, taking care of every part of the deployment, from the software running it to the subjacent infrastructure supporting it.


For the sake of “Keeping It Simple Stu_*_” principle (KISS), we will create a docker-compose based application to retrieve the METAR weather data from airports, using its ICAO airport code and pulling the data from the National US Weather Service. Then we will create the image with Packer using Ubuntu and deploy the infrastructure using the image with Terraform.

PHP Application

Same here, for the sake of simplicity I created the application ready to use. You can find the source code in to have a look, which includes an index.php, 2 javascript files to decode the METAR data and a bit of CSS and a PNG image to make it less boring. It even indicates the direction of wind! But don’t worry, you won’t need to clone the repository at this point.

The application is based in docker-compose and is something we will install as dependency with Packer later.

Building the Image with Packer

Let’s get our hands dirty! For this, we need to create a folder somewhere in our computer, lets say ~/metar-app. Then lets cd in and create a file named metar-build.json with the following contents:

      "variables": {
        "access_key": "{{env `ALICLOUD_ACCESS_KEY`}}",
        "region": "{{env `ALICLOUD_REGION`}}",
        "secret_key": "{{env `ALICLOUD_SECRET_KEY`}}"
      "builders": [
          "type": "alicloud-ecs",
          "access_key": "{{user `access_key`}}",
          "secret_key": "{{user `secret_key`}}",
          "region":"{{user `region`}}",
          "image_name": "metar_app",
          "source_image": "ubuntu_16_0402_64_20G_alibase_20180409.vhd",
          "ssh_username": "root",
          "instance_type": "ecs.t5-lc1m1.small",
          "internet_charge_type": "PayByTraffic",
          "io_optimized": "true"
      "provisioners": [
          "type": "shell",
          "script": "base-setup"

And right next to it, a file named base-setup with the following:

#!/usr/bin/env bash

apt-get update && apt-get install -y apt-transport-https ca-certificates curl git-core software-properties-common
curl -fsSL | apt-key add -
add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable"
apt-get update && apt-get install -y docker-ce docker-compose
curl -L`uname -s`-`uname -m` -o /usr/bin/docker-compose

mkdir /var/docker
git clone /var/docker/metar

Once you have that 2 files, you can run packer build metar-build.json and wait for it to finish. Please note that, for this to work, you need to have 3 environment variables in your machine with the relevant values for you, ALICLOUD_REGION, ALICLOUD_ACCESS_KEY and ALICLOUD_SECRET_KEY. This step will take a while, as it creates an ECS, installs all the software in it, then stops the instance, creates a snapshot of it, and finally creates the image of the whole system.

After the image is completed, packer will output ==> Builds finished. Good, we have an image ready to use! We are ready to continue to the next step.

Deploying the Infrastructure with Terraform

It’s time to create the ECS Instance. For this, in the same folder, we will create a file named with the following content:

provider "alicloud" {}

data "alicloud_images" "search" {
  name_regex = "metar_app"

data "alicloud_instance_types" "search" {
  instance_type_family = "ecs.xn4"
  cpu_core_count       = 1
  memory_size          = 1

data "alicloud_security_groups" "search" {}

data "alicloud_vswitches" "search" {}

resource "alicloud_instance" "app" {
  instance_name = "metar_app"
  image_id      = "${}"
  instance_type = "${}"

  vswitch_id      = "${}"
  security_groups = [
  internet_max_bandwidth_out = 100

  password = "Test1234!"

  user_data = "${file("user-data")}"

output "ip" {
  value = "${}"

And, right next to it, create a file named user-data with the following:

#!/usr/bin/env bash

cd /var/docker/metar && docker-compose up -d

To be clear, at this moment we should have a file structure like this:

    ├── metar-build.json
    ├── base-setup
    └── user-data

Ready to deploy. Run terraform init, then terraform plan to check that everything is fine, and terraform apply to launch the process.

When the infrastructure is built, Terraform will output the IP of the newly created ECS instance. Let’s say,


If everything went well, you will be able to go to and visualise, in this case, the latest weather report from the San Sebastián airport, an airport with one of the most beautiful approaches in the world, located in the north of Spain.

Wrapping Up

See, with almost no effort you just created a full DevOps deployment for your application. This means that will be so much easier for you and your team to maintain anything related to its release cycles, infrastructure updates and will improve its uptime. No need to fiddle anymore directly with hosts and Linux commands in the normal day-to-day.

Original article: How to Deploy Apps Effortlessly with Packer and Terraform.

✉️ Contact

Ready to take the next step? Don't wait any longer! If you're interested in learning more about Guztia products and services, or if you have any questions or concerns, book a meeting today.

Book a Meeting

Our team of experts is standing by, ready to assist you with anything you need. Book a Meeting, and Guztia will take care of the rest.