Skip to content

Commit

Permalink
feat: manage AMIs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ric Featherstone authored and 06kellyjac committed Dec 21, 2023
1 parent cbaaa6b commit 07c076f
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 13 deletions.
2 changes: 1 addition & 1 deletion controlplane/cli/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var buildCmd = &cobra.Command{
defer stop()

cp := controlplane.New()
return cp.BuildImage(ctx, controlplane.PackerTemplate(template))
return cp.BuildImage(ctx, template)
},
}

Expand Down
9 changes: 2 additions & 7 deletions controlplane/simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ import (
"github.com/controlplaneio/simulator/controlplane/commands"
)

type PackerTemplate string

const (
BastionImage PackerTemplate = "bastion"
K8sImage PackerTemplate = "k8s"

SimulatorDir = "/simulator"
Home = "config"
Scenarios = "scenarios"
Expand Down Expand Up @@ -45,7 +40,7 @@ type Simulator interface {
// CreateBucket creates the S3 bucket used to store Simulator state.
CreateBucket(ctx context.Context, name string) error
// BuildImage runs Packer to create the specified AMI.
BuildImage(ctx context.Context, name PackerTemplate) error
BuildImage(ctx context.Context, name string) error
// CreateInfrastructure runs Terraform to create the Simulator infrastructure.
CreateInfrastructure(ctx context.Context, bucket string, key string, name string) error
// DestroyInfrastructure runs Terraform to destroy the Simulator infrastructure.
Expand All @@ -65,7 +60,7 @@ func (s simulator) CreateBucket(ctx context.Context, name string) error {
return aws.CreateBucket(ctx, name)
}

func (s simulator) BuildImage(ctx context.Context, name PackerTemplate) error {
func (s simulator) BuildImage(ctx context.Context, name string) error {
slog.Debug("simulator build", "image", name)

err := commands.PackerInitCommand(PackerTemplateDir, string(name)).Run(ctx)
Expand Down
11 changes: 11 additions & 0 deletions docs/simulator-amis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Simulator AMIs

Simulator uses two AMIs; one for the bastion, one for the Kubernetes instances.

These must be created in the target AWS account before launching the Simulator infrastructure by running the following
commands.

```shell
simulator image build bastion
simulator image build k8s
```
11 changes: 6 additions & 5 deletions internal/cli/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,25 @@ var imageCmd = &cobra.Command{
Use: "image",
}

var template string
// TODO: Add flags for containerd, runc, cni, and kubernetes version

var imageBuildCmd = &cobra.Command{
Use: "build",
Use: "build [name]",
Short: "Build the packer image",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
runner := container.New(cfg)

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

name := args[0]

command := []string{
"image",
"build",
"--template",
fmt.Sprintf("%s.pkr.hcl", template),
fmt.Sprintf("%s.pkr.hcl", name),
}

err := runner.Run(ctx, command)
Expand All @@ -40,8 +43,6 @@ var imageBuildCmd = &cobra.Command{
}

func init() {
imageBuildCmd.Flags().StringVar(&template, "template", "", "the packer template to build; bastion, or k8s")
imageCmd.AddCommand(imageBuildCmd)

simulatorCmd.AddCommand(imageCmd)
}
78 changes: 78 additions & 0 deletions packer/bastion.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
variable "name" {
type = string
default = "simulator-bastion"
}

variable "region" {
type = string
default = "eu-west-2"
}

variable "kube_version" {
type = string
default = "1.28"
}

locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

build {
name = "simulator-bastion"
sources = [
"source.amazon-ebs.ubuntu"
]

provisioner "shell" {
inline = [
"sudo apt update",
"sudo apt install -y apt-transport-https ca-certificates figlet curl jq python3-pip ansible socat",
"ansible-galaxy collection install kubernetes.core",
"pip install kubernetes",
]
}

provisioner "shell" {
script = "scripts/common"
}

provisioner "shell" {
environment_vars = [
"KUBE_VERSION=${var.kube_version}",
"PACKAGES=kubectl",
]
script = "scripts/kubernetes"
}


provisioner "shell" {
inline = [
"rm .ssh/authorized_keys",
]
}
}

source "amazon-ebs" "ubuntu" {
ami_name = "${var.name}-${var.kube_version}-${local.timestamp}"
instance_type = "t2.micro"
region = "${var.region}"
source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
ssh_username = "ubuntu"
}

packer {
required_plugins {
amazon = {
version = ">= 0.0.2"
source = "github.com/hashicorp/amazon"
}
}
}
100 changes: 100 additions & 0 deletions packer/k8s.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
variable "name" {
type = string
default = "simulator-k8s"
}

variable "region" {
type = string
default = "eu-west-2"
}

variable "containerd_version" {
type = string
default = "1.7.7"
}

variable "runc_version" {
type = string
default = "1.1.9"
}

variable "cni_version" {
type = string
default = "1.3.0"
}

variable "kube_version" {
type = string
default = "1.28"
}

locals {
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
}

build {
name = "simulator-k8s"
sources = [
"source.amazon-ebs.ubuntu"
]

provisioner "shell" {
inline = [
"sudo apt update",
"sudo apt install -y apt-transport-https ca-certificates figlet curl jq",
]
}

provisioner "shell" {
script = "scripts/common"
}

provisioner "shell" {
environment_vars = [
"CONTAINERD_VERSION=${var.containerd_version}",
"RUNC_VERSION=${var.runc_version}",
"CNI_VERSION=${var.cni_version}",
]
script = "scripts/containerd"
}

provisioner "shell" {
environment_vars = [
"KUBE_VERSION=${var.kube_version}",
"PACKAGES=kubelet kubeadm kubectl",
"PULL_IMAGES=true"
]
script = "scripts/kubernetes"
}

provisioner "shell" {
inline = [
"rm .ssh/authorized_keys",
]
}
}

source "amazon-ebs" "ubuntu" {
ami_name = "${var.name}-${var.kube_version}-${local.timestamp}"
instance_type = "t2.micro"
region = "${var.region}"
source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
ssh_username = "ubuntu"
}

packer {
required_plugins {
amazon = {
version = ">= 0.0.2"
source = "github.com/hashicorp/amazon"
}
}
}
28 changes: 28 additions & 0 deletions packer/scripts/common
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

# Disable dynamic motd news
sudo sed -i 's/ENABLED=1/ENABLED=0/' /etc/default/motd-news

# Remove dynamic motd
sudo sed -i 's/.*pam_motd.so.*//' /etc/pam.d/sshd

# Configure motd
sudo tee /etc/profile.d/motd.sh > /dev/null << 'EOF'
echo "$(tput setaf 3)$(figlet $(hostname))$(tput sgr0)
"
EOF
sudo chmod +x /etc/profile.d/motd.sh

# Configure sshd
sudo sed -i 's/#ClientAliveInterval.*/ClientAliveInterval 30/' /etc/ssh/sshd_config
sudo sed -i 's/#ClientAliveCountMax.*/ClientAliveCountMax 240/' /etc/ssh/sshd_config
sudo sed -i 's/X11Forwarding yes/X11Forwarding no/' /etc/ssh/sshd_config
# In simulator v1 hardening, but not required
#sudo sed -i 's/Subsystem.*sftp.*/Subsystem sftp \/bin\/false/' /etc/ssh/sshd_config
sudo systemctl restart sshd

## TODO: verify if this makes sense
sudo tee /etc/ssh/sshd_config.d/rsa.conf > /dev/null << EOF
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
EOF
47 changes: 47 additions & 0 deletions packer/scripts/containerd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash

# Prereqs

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF

sudo sysctl --system

# Install

# Create directories
sudo mkdir -m 0755 -p /usr/local/lib/systemd/system /opt/cni/bin /etc/containerd

# Setup containerd
curl -LSso containerd.tar.gz https://github.com/containerd/containerd/releases/download/v$CONTAINERD_VERSION/containerd-$CONTAINERD_VERSION-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd.tar.gz
rm containerd.tar.gz

sudo curl -Lo /usr/local/lib/systemd/system/containerd.service https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

# Setup runc
sudo curl -Lo /usr/local/sbin/runc https://github.com/opencontainers/runc/releases/download/v$RUNC_VERSION/runc.amd64
sudo chmod 0755 /usr/local/sbin/runc

# Setup cni plugins
curl -Lo cni-plugins.tgz https://github.com/containernetworking/plugins/releases/download/v$CNI_VERSION/cni-plugins-linux-amd64-v$CNI_VERSION.tgz
sudo tar Cxzvf /opt/cni/bin cni-plugins.tgz
rm cni-plugins.tgz

# Configure containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
15 changes: 15 additions & 0 deletions packer/scripts/kubernetes
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | \
sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v${KUBE_VERSION}/deb/ /" | \
sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt update
sudo apt install -y ${PACKAGES}
sudo apt-mark hold ${PACKAGES}

if [ $PULL_IMAGES == "true" ]; then
sudo kubeadm config images pull
fi

0 comments on commit 07c076f

Please sign in to comment.