Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build sacrificial VM image with Packer #7

Merged
merged 8 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gcp.key.json

20 changes: 20 additions & 0 deletions packer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Packer

We use Packer to create a VM image with latest software, so that Terraform can use the image to create VM instances.

## Set up GCP credentials for Packer

1. Set up GCP service account for Packer following [Packer - Running outside of Google Cloud](https://www.packer.io/plugins/builders/googlecompute#running-outside-of-google-cloud)

2. Move the downloaded service account key file to `./gcp.key.json`.
Note: if you want to use a different file name or location, change `account_file` accordingly.

## Init and Build

This command builds an image to GCP

```bash
packer init . && packer build -force .
```

Note: `-force` to overwrite previously built image.
36 changes: 36 additions & 0 deletions packer/scripts/install_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash

# solves apt lock issue
# https://github.com/geerlingguy/packer-boxes/issues/7#issuecomment-425641793
function apt-get() {
while fuser -s /var/lib/apt/lists/lock;
do echo 'apt-get is waiting for the lock release ...';
sleep 1;
done;
/usr/bin/apt-get "$@";
}
paseaf marked this conversation as resolved.
Show resolved Hide resolved

export DEBIAN_FRONTEND=noninteractive

set -euxo pipefail
paseaf marked this conversation as resolved.
Show resolved Hide resolved

apt-get update
apt-get upgrade -y
apt-get install -y \
ca-certificates \
curl \
gnupg \
lsb-release

# add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# set up a stable repo
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# install docker engine
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

48 changes: 48 additions & 0 deletions packer/scripts/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash -eux
# This script is adapted from
# https://github.com/chef/bento/blob/main/packer_templates/ubuntu/scripts/update.sh

# solves apt lock issue
function apt-get() {
paseaf marked this conversation as resolved.
Show resolved Hide resolved
while fuser -s /var/lib/apt/lists/lock;
do echo 'apt-get is waiting for the lock release ...';
sleep 1;
done;
/usr/bin/apt-get "$@";
}

export DEBIAN_FRONTEND=noninteractive

echo "disable release-upgrades"
sed -i.bak 's/^Prompt=.*$/Prompt=never/' /etc/update-manager/release-upgrades;

echo "disable systemd apt timers/services"
systemctl stop apt-daily.timer;
systemctl stop apt-daily-upgrade.timer;
systemctl disable apt-daily.timer;
systemctl disable apt-daily-upgrade.timer;
systemctl mask apt-daily.service;
systemctl mask apt-daily-upgrade.service;
systemctl daemon-reload;

# Disable periodic activities of apt to be safe
cat <<EOF >/etc/apt/apt.conf.d/10periodic;
APT::Periodic::Enable "0";
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "0";
EOF

echo "remove the unattended-upgrades and ubuntu-release-upgrader-core packages"
rm -rf /var/log/unattended-upgrades;
apt-get -y purge unattended-upgrades ubuntu-release-upgrader-core;

echo "update the package list"
apt-get -y update;

echo "upgrade all installed packages incl. kernel and kernel headers"
apt-get -y dist-upgrade -o Dpkg::Options::="--force-confnew";

reboot

28 changes: 28 additions & 0 deletions packer/ubuntu-2204.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
packer {
required_plugins {
googlecompute = {
version = ">= 1.0.0"
source = "github.com/hashicorp/googlecompute"
}
}
}

source "googlecompute" "ubuntu-2204" {
project_id = "containerssh"
source_image_family = "ubuntu-pro-2204-lts"
ssh_username = "root"
zone = "europe-west3-c"
account_file = "./gcp.key.json"
image_name = "sacrificial-vm-image"
}

build {
name = "ubuntu-2204-with-docker"
sources = [
"source.googlecompute.ubuntu-2204"
]
provisioner "shell" {
scripts = ["./scripts/update.sh", "./scripts/install_docker.sh"]
}
}

10 changes: 6 additions & 4 deletions terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ Install it as follows:

2. Install [Terraform CLI](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/gcp-get-started)

3. Create and download a GCP _service account key_ (in JSON) following [_Set up GCP_ in this guide](https://learn.hashicorp.com/tutorials/terraform/google-cloud-platform-build?in=terraform/gcp-get-started).\
Terraform will use it to manage your GCP resources. Move the key file to `./.gcp-key.json`
3. Create and download a GCP _service account key_ (in JSON) following [Terraform - Set Up GCP](https://learn.hashicorp.com/tutorials/terraform/google-cloud-platform-build?in=terraform/gcp-get-started).\
Terraform will use it to manage your GCP resources. Move the key file to current folder as `./gcp-key.json`

4. Update `terraform/terraform.tfvars` file with the following content

```bash
project = "<GCP_project_ID>"
credentials_file = "<path_to_GCP_key_file>"
project = "<your_GCP_project_ID>"
credentials_file = "gcp-key.json"
paseaf marked this conversation as resolved.
Show resolved Hide resolved
```

5. Verify if your Terraform is successfully set up.

```bash
cd terraform
terraform init # initialize the working directory
terraform plan # preview the changes
```

You should not see any error message in the output.

20 changes: 18 additions & 2 deletions terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@ resource "google_compute_network" "main" {
auto_create_subnetworks = false
}

resource "google_compute_firewall" "benchmark_vpc_rules" {
name = "benchmark-vpc-rules"
network = google_compute_network.main.self_link

allow {
protocol = "icmp"
}

allow {
protocol = "tcp"
ports = ["22"]
}

source_ranges = ["0.0.0.0/0"]
}

resource "google_compute_subnetwork" "gateway_subnet" {
name = "gateway-subnet"
ip_cidr_range = "10.0.0.0/24"
Expand Down Expand Up @@ -43,12 +59,12 @@ resource "google_compute_instance" "gateway_vm" {
}

resource "google_compute_instance" "sacrificial_vm" {
name = "sacrificial"
name = "sacrificial-vm"
machine_type = "e2-micro"

boot_disk {
initialize_params {
image = "ubuntu-os-pro-cloud/ubuntu-pro-2204-lts"
image = "sacrificial-vm-image"
}
}

Expand Down