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

Use separate EBS Volumes for /var, /home folders #2

Draft
wants to merge 2 commits into
base: updated-amazon-ebs-builder-settings-01
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
98 changes: 72 additions & 26 deletions amazon-eks-al2.pkr.hcl
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")

target_ami_name = "${var.ami_name_prefix}-${var.eks_version}-${local.timestamp}"
}

data "amazon-ami" "this" {
filters = {
architecture = var.source_ami_arch
Expand All @@ -21,43 +15,95 @@ data "amazon-ami" "this" {
region = var.aws_region
}

source "amazon-ebs" "this" {
ami_block_device_mappings {
delete_on_termination = true
device_name = "/dev/sdb"
volume_size = var.data_volume_size
volume_type = "gp2"
locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")

target_ami_name = "${var.ami_name_prefix}-${var.eks_version}-v${local.timestamp}"

block_device_mappings = {
"/" = {
device_name = "/dev/xvda"
volume_size = var.root_volume_size
}
"/home" = {
device_name = "/dev/sdf"
volume_size = var.home_volume_size
}
"/var" = {
device_name = "/dev/sdg"
volume_size = var.var_volume_size
}
"/var/log" = {
device_name = "/dev/sdh"
volume_size = var.varlog_volume_size
}
"/var/log/audit" = {
device_name = "/dev/sdi"
volume_size = var.varlogaudit_volume_size
}
"/var/lib/docker" = {
device_name = "/dev/sdj"
volume_size = var.varlibdocker_volume_size
}
}
}

source "amazon-ebs" "this" {
ami_description = "EKS Kubernetes Worker AMI with AmazonLinux2 image"
ami_name = local.target_ami_name
ami_virtualization_type = "hvm"
instance_type = var.instance_type

launch_block_device_mappings {
delete_on_termination = true
device_name = "/dev/sda1"
volume_size = var.root_volume_size
volume_type = "gp2"
dynamic "ami_block_device_mappings" {
for_each = local.block_device_mappings

content {
device_name = ami_block_device_mappings.value.device_name
volume_size = ami_block_device_mappings.value.volume_size
delete_on_termination = true
volume_type = "gp3"
encrypted = true
}
}

launch_block_device_mappings {
delete_on_termination = true
device_name = "/dev/sdb"
volume_size = var.data_volume_size
volume_type = "gp2"
dynamic "launch_block_device_mappings" {
for_each = local.block_device_mappings

content {
device_name = launch_block_device_mappings.value.device_name
volume_size = launch_block_device_mappings.value.volume_size
delete_on_termination = true
volume_type = "gp3"
encrypted = true
kms_key_id = var.kms_key_id
}
}

encrypt_boot = var.encrypt_boot
kms_key_id = var.kms_key_id

region = var.aws_region

run_tags = {
Name = local.target_ami_name
}

source_ami = data.amazon-ami.this.id
ssh_pty = true
ssh_username = var.source_ami_ssh_user
subnet_id = var.subnet_id
source_ami = data.amazon-ami.this.id

subnet_id = var.subnet_id
ssh_pty = true
ssh_interface = var.ssh_interface
ssh_username = var.source_ami_ssh_user

associate_public_ip_address = var.associate_public_ip_address
temporary_security_group_source_cidrs = var.temporary_security_group_source_cidrs
temporary_security_group_source_public_ip = var.temporary_security_group_source_public_ip

ami_regions = var.ami_regions
region_kms_key_ids = var.region_kms_key_ids
ami_org_arns = var.ami_org_arns
ami_users = var.ami_users
snapshot_users = var.snapshot_users

tags = {
os_version = "Amazon Linux 2"
Expand Down
70 changes: 41 additions & 29 deletions scripts/partition-disks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,32 @@ set -o errexit
# None
################################################################
migrate_and_mount_disk() {
local disk_name=$1
local device_name=$1
local folder_path=$2
local mount_options=$3
local temp_path="/mnt${folder_path}"
local old_path="${folder_path}-old"

# install an ext4 filesystem to the disk
mkfs -t ext4 ${disk_name}
# AWS EC2 API Block Device Mapping name to Linux NVME device name
disk_name="/dev/$(readlink "$device_name")"

# partition the disk (single data partition)
parted -a optimal -s $disk_name \
mklabel gpt \
mkpart data xfs 0% 90%

# wait for the disk to settle
sleep 5

# install an xfs filesystem to the disk
mkfs -t xfs "${disk_name}p1"

# check if the folder already exists
if [ -d "${folder_path}" ]; then
FILE=$(ls -A ${folder_path})
>&2 echo $FILE
mkdir -p ${temp_path}
mount ${disk_name} ${temp_path}
mount "${disk_name}p1" ${temp_path}
# Empty folder give error on /*
if [ ! -z "$FILE" ]; then
cp -Rax ${folder_path}/* ${temp_path}
Expand All @@ -42,7 +53,7 @@ migrate_and_mount_disk() {
mkdir -p ${folder_path}

# add the mount point to fstab and mount the disk
echo "UUID=$(blkid -s UUID -o value ${disk_name}) ${folder_path} ext4 ${mount_options} 0 1" >> /etc/fstab
echo "UUID=$(blkid -s UUID -o value "${disk_name}p1") ${folder_path} xfs ${mount_options} 0 1" >> /etc/fstab
mount -a

# if selinux is enabled restore the objects on it
Expand All @@ -51,27 +62,28 @@ migrate_and_mount_disk() {
fi
}

disk_name='/dev/nvme2n1'

# partition the disk
parted -a optimal -s $disk_name \
mklabel gpt \
mkpart var ext4 0% 20% \
mkpart varlog ext4 20% 40% \
mkpart varlogaudit ext4 40% 60% \
mkpart home ext4 60% 70% \
mkpart varlibdocker ext4 70% 90%

# wait for the disks to settle
sleep 5

# migrate and mount the existing
migrate_and_mount_disk "${disk_name}p1" /var defaults,nofail,nodev
migrate_and_mount_disk "${disk_name}p2" /var/log defaults,nofail,nodev,nosuid
migrate_and_mount_disk "${disk_name}p3" /var/log/audit defaults,nofail,nodev,nosuid
migrate_and_mount_disk "${disk_name}p4" /home defaults,nofail,nodev,nosuid

# Create folder instead of starting/stopping docker daemon
mkdir -p /var/lib/docker
chown -R root:docker /var/lib/docker
migrate_and_mount_disk "${disk_name}p5" /var/lib/docker defaults,nofail
# migrate and mount the existing folders to dedicated EBS Volumes
migrate_and_mount_disk "/dev/sdf" "/home" defaults,nofail,nodev,nosuid
migrate_and_mount_disk "/dev/sdg" "/var" defaults,nofail,nodev
migrate_and_mount_disk "/dev/sdh" "/var/log" defaults,nofail,nodev,nosuid
migrate_and_mount_disk "/dev/sdi" "/var/log/audit" defaults,nofail,nodev,nosuid
migrate_and_mount_disk "/dev/sdj" "/var/lib/docker" defaults,nofail

# Resize on instance launch
cloud_init_script="/var/lib/cloud/scripts/per-boot/resize-disks.sh"
cat > "$cloud_init_script" <<EOF
#!/usr/bin/env bash

set -x

lsblk

growpart "/dev/\$(readlink "/dev/sdf")" 1; xfs_growfs '/home'
growpart "/dev/\$(readlink "/dev/sdg")" 1; xfs_growfs '/var'
growpart "/dev/\$(readlink "/dev/sdh")" 1; xfs_growfs '/var/log'
growpart "/dev/\$(readlink "/dev/sdi")" 1; xfs_growfs '/var/log/audit'
growpart "/dev/\$(readlink "/dev/sdj")" 1; xfs_growfs '/var/lib/docker'

df -Th | grep -E 'Filesystem|xfs'
EOF
chmod +x "$cloud_init_script"
105 changes: 98 additions & 7 deletions variables.pkr.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,64 @@ variable "aws_region" {
default = "us-west-2"
}

variable "data_volume_size" {
description = "Size of the AMI data EBS volume"
type = number
default = 50
variable "eks_version" {
description = "The EKS cluster version associated with the AMI created"
type = string
default = "1.22"
}

variable "root_volume_size" {
description = "Size of the AMI root EBS volume"
type = number
default = 4
}

variable "home_volume_size" {
description = "Size of the AMI /home EBS volume"
type = number
default = 1
}

variable "var_volume_size" {
description = "Size of the AMI /var EBS volume"
type = number
default = 4
}

variable "varlog_volume_size" {
description = "Size of the AMI /var/log EBS volume"
type = number
default = 1
}

variable "varlogaudit_volume_size" {
description = "Size of the AMI /var/log/audit EBS volume"
type = number
default = 1
}

variable "varlibdocker_volume_size" {
description = "Size of the AMI /var/lib/docker EBS volume"
type = number
default = 10
}

variable "eks_version" {
description = "The EKS cluster version associated with the AMI created"
variable "encrypt_boot" {
description = "Whether or not to encrypt the resulting AMI when copying a provisioned instance to an AMI."
type = bool
default = false
}

variable "kms_key_id" {
description = "ID, alias or ARN of the KMS key to use for AMI encryption. This only applies to the main."
type = string
default = "1.22"
default = null
}

variable "region_kms_key_ids" {
description = "Regions to copy the ami to, along with the custom kms key id (alias or arn) to use for encryption for that region."
type = map(string)
default = null
}

variable "http_proxy" {
Expand Down Expand Up @@ -81,3 +123,52 @@ variable "ami_name_prefix" {
type = string
default = "amazon-eks-node"
}

variable "associate_public_ip_address" {
description = "If using a non-default VPC, public IP addresses are not provided by default. If this is true, your new instance will get a Public IP."
type = bool
default = false
}


variable "temporary_security_group_source_cidrs" {
description = "A list of IPv4 CIDR blocks to be authorized access to the instance, when packer is creating a temporary security group."
type = list(string)
default = []
}

variable "temporary_security_group_source_public_ip" {
description = "When enabled, use public IP of the host (obtained from https://checkip.amazonaws.com) as IPv4 CIDR block to be authorized access to the instance, when packer is creating a temporary security group"
type = bool
default = false
}

variable "ssh_interface" {
description = "If set, either the public IP address, private IP address, public DNS name or private DNS name will be used as the host for SSH. The default behaviour if inside a VPC is to use the public IP address if available, otherwise the private IP address will be used. If not in a VPC the public DNS name will be used."
type = string
default = "private_ip"
}

variable "ami_regions" {
description = "A list of regions to copy the AMI to. Tags and attributes are copied along with the AMI. AMI copying takes time depending on the size of the AMI, but will generally take many minutes."
type = list(string)
default = []
}

variable "ami_org_arns" {
description = "A list of Amazon Resource Names (ARN) of AWS Organizations that have access to launch the resulting AMI(s)."
type = list(string)
default = []
}

variable "ami_users" {
description = "A list of account IDs that have access to launch the resulting AMI(s). By default no additional users other than the user creating the AMI has permissions to launch it."
type = list(string)
default = []
}

variable "snapshot_users" {
description = "A list of account IDs that have access to create volumes from the snapshot(s)."
type = list(string)
default = []
}