8. Amazon Machine Image
Let's use Packer to create an Amazon Machine Image that will contain an application's code, Node.js, and required dependencies installed.
app/index.js
const express = require("express");
const { SecretsManager } = require("@aws-sdk/client-secrets-manager");
const { Pool } = require("pg");
const port = process.env.PORT;
const region = process.env.AWS_REGION || "eu-central-1";
const secretId = process.env.SECRET_ID;
const dbEndpoint = process.env.DB_ENDPOINT;
const app = express();
const secretsManager = new SecretsManager({
region,
});
(async () => {
try {
const secret = await secretsManager.getSecretValue({ SecretId: secretId });
const { name, username, password } = JSON.parse(secret.SecretString);
const connectionString = `postgresql://${username}:${password}@${dbEndpoint}/${name}`;
const pool = new Pool({
connectionString,
});
app.get("/", async (req, res) => {
try {
const client = await pool.connect();
const { rows } = await client.query("SELECT NOW()");
client.release();
res.send(`<h1>${rows[0].now}</h1>`);
} catch (error) {
client.release();
}
});
app.listen(port, () => {
console.log(`Listening on port ${port}`);
});
} catch (error) {
process.exit(1);
}
})();
app/.nvmrc
16.3.0
app/package.json
{
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@aws-sdk/client-secrets-manager": "^3.24.0",
"express": "^4.17.1",
"pg": "^8.7.1"
}
}
packer/ami.pkr.hcl
packer {
required_plugins {
amazon = {
version = ">= 0.0.2"
source = "github.com/hashicorp/amazon"
}
}
}
variable "ami_prefix" {
type = string
default = "node-app"
}
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}
source "amazon-ebs" "ubuntu" {
ami_name = "${var.ami_prefix}-${local.timestamp}"
instance_type = "t2.micro"
region = "eu-central-1"
source_ami_filter {
filters = {
name = "ubuntu/images/*ubuntu-focal-20.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
ssh_username = "ubuntu"
}
build {
sources = [
"source.amazon-ebs.ubuntu"
]
provisioner "file" {
source = "../app"
destination = "~/app"
}
provisioner "shell" {
script = "script.sh"
}
}
packer/script.sh
#!/bin/bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
command -v nvm
cd ~/app
nvm install
nvm use
nvm install-latest-npm
npm install
$ packer init ami.pkr.hcl
$ packer fmt ami.pkr.hcl
$ packer validate ami.pkr.hcl
$ packer build ami.pkr.hcl
amazon-ebs.ubuntu: output will be in this color.
==> amazon-ebs.ubuntu: Prevalidating any provided VPC information
==> amazon-ebs.ubuntu: Prevalidating AMI Name: node-app-20210927190235
amazon-ebs.ubuntu: Found Image ID: ami-091f21ecba031b39a
==> amazon-ebs.ubuntu: Creating temporary keypair: packer_6152154c-f5ac-2af8-0381-c8dc39e2416f
==> amazon-ebs.ubuntu: Creating temporary security group for this instance: packer_6152154e-e22e-936d-fd26-b8d003f57cc3
==> amazon-ebs.ubuntu: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs.ubuntu: Launching a source AWS instance...
==> amazon-ebs.ubuntu: Adding tags to source instance
amazon-ebs.ubuntu: Adding tag: "Name": "Packer Builder"
amazon-ebs.ubuntu: Instance ID: i-00b36d26d99b514df
==> amazon-ebs.ubuntu: Waiting for instance (i-00b36d26d99b514df) to become ready...
==> amazon-ebs.ubuntu: Using SSH communicator to connect: 18.159.195.4
==> amazon-ebs.ubuntu: Waiting for SSH to become available...
==> amazon-ebs.ubuntu: Connected to SSH!
==> amazon-ebs.ubuntu: Uploading ../app => ~/app
==> amazon-ebs.ubuntu: Provisioning with shell script: script.sh
==> amazon-ebs.ubuntu: % Total % Received % Xferd Average Speed Time Time Time Current
==> amazon-ebs.ubuntu: Dload Upload Total Spent Left Speed
==> amazon-ebs.ubuntu: 100 14926 100 14926 0 0 485k 0 --:--:-- --:--:-- --:--:-- 502k
amazon-ebs.ubuntu: => Downloading nvm from git to '/home/ubuntu/.nvm'
==> amazon-ebs.ubuntu: Cloning into '/home/ubuntu/.nvm'...
amazon-ebs.ubuntu: => * (HEAD detached at FETCH_HEAD)
amazon-ebs.ubuntu: master
amazon-ebs.ubuntu: => Compressing and cleaning up git repository
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: => Appending nvm source string to /home/ubuntu/.bashrc
amazon-ebs.ubuntu: => Appending bash_completion source string to /home/ubuntu/.bashrc
amazon-ebs.ubuntu: => Close and reopen your terminal to start using nvm or run the following to use it now:
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: export NVM_DIR="$HOME/.nvm"
amazon-ebs.ubuntu: [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
amazon-ebs.ubuntu: [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
amazon-ebs.ubuntu: nvm
amazon-ebs.ubuntu: Found '/home/ubuntu/app/.nvmrc' with version <16.3.0>
amazon-ebs.ubuntu: Downloading and installing node v16.3.0...
==> amazon-ebs.ubuntu: Downloading https://nodejs.org/dist/v16.3.0/node-v16.3.0-linux-x64.tar.xz...
==> amazon-ebs.ubuntu: ######################################################################## 100.0%
==> amazon-ebs.ubuntu: Computing checksum with sha256sum
==> amazon-ebs.ubuntu: Checksums matched!
amazon-ebs.ubuntu: Now using node v16.3.0 (npm v7.15.1)
amazon-ebs.ubuntu: Creating default alias: default -> 16.3.0 (-> v16.3.0 *)
amazon-ebs.ubuntu: Found '/home/ubuntu/app/.nvmrc' with version <16.3.0>
amazon-ebs.ubuntu: Now using node v16.3.0 (npm v7.15.1)
amazon-ebs.ubuntu: Attempting to upgrade to the latest working version of npm...
amazon-ebs.ubuntu: * Installing latest `npm`; if this does not work on your node version, please report a bug!
amazon-ebs.ubuntu:
==> amazon-ebs.ubuntu: npm notice
amazon-ebs.ubuntu: removed 10 packages, changed 55 packages, and audited 258 packages in 3s
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: 11 packages are looking for funding
amazon-ebs.ubuntu: run `npm fund` for details
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: found 0 vulnerabilities
==> amazon-ebs.ubuntu: npm notice New minor version of npm available! 7.15.1 -> 7.24.1
==> amazon-ebs.ubuntu: npm notice Changelog: <https://github.com/npm/cli/releases/tag/v7.24.1>
==> amazon-ebs.ubuntu: npm notice Run `npm install -g npm@7.24.1` to update!
==> amazon-ebs.ubuntu: npm notice
amazon-ebs.ubuntu: * npm upgraded to: v7.24.1
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: added 132 packages, and audited 133 packages in 6s
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: 3 packages are looking for funding
amazon-ebs.ubuntu: run `npm fund` for details
amazon-ebs.ubuntu:
amazon-ebs.ubuntu: found 0 vulnerabilities
==> amazon-ebs.ubuntu: Stopping the source instance...
amazon-ebs.ubuntu: Stopping instance
==> amazon-ebs.ubuntu: Waiting for the instance to stop...
==> amazon-ebs.ubuntu: Creating AMI node-app-20210927190235 from instance i-00b36d26d99b514df
amazon-ebs.ubuntu: AMI: ami-0cca38f651b773594
==> amazon-ebs.ubuntu: Waiting for AMI to become ready...
==> amazon-ebs.ubuntu: Terminating the source AWS instance...
==> amazon-ebs.ubuntu: Cleaning up any extra volumes...
==> amazon-ebs.ubuntu: No volumes to clean up, skipping
==> amazon-ebs.ubuntu: Deleting temporary security group...
==> amazon-ebs.ubuntu: Deleting temporary keypair...
Build 'amazon-ebs.ubuntu' finished after 5 minutes 4 seconds.
==> Wait completed after 5 minutes 4 seconds
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs.ubuntu: AMIs were created:
eu-central-1: ami-0cca38f651b773594
Last updated
Was this helpful?