Skip to content

Commit

Permalink
chore: add test infra for dummy cluster (#157)
Browse files Browse the repository at this point in the history
Co-authored-by: UncleGedd <42304551+UncleGedd@users.noreply.github.com>
Co-authored-by: Billy Figueroa <billy@defenseunicorns.com>
Co-authored-by: decleaver <85503726+decleaver@users.noreply.github.com>
  • Loading branch information
4 people authored Aug 16, 2024
1 parent f50bd77 commit 2ba9e26
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 2 deletions.
51 changes: 51 additions & 0 deletions .github/test-infra/packer/install-tools.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash

set -e

# renovate: datasource=github-tags depName=k3d-io/k3d versioning=semver
export K3D_VERSION="v5.5.1"

# Install docker
sudo apt-get update -y
sudo apt-get -y install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update -y
sudo apt-get install -y docker-ce containerd.io

sudo usermod -aG docker ubuntu

# install k3d
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG="$K3D_VERSION" bash

# intall kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# install helm
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

# install uds-cli
curl -LO "https://github.com/defenseunicorns/uds-cli/releases/download/v0.14.0/uds-cli_v0.14.0_Linux_amd64"
sudo mv uds-cli_v0.14.0_Linux_amd64 /usr/local/bin/uds
sudo chmod +x /usr/local/bin/uds

# install unzip for aws-cli
sudo apt-get install unzip -y

# install aws-cli
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
45 changes: 45 additions & 0 deletions .github/test-infra/packer/runtime.pkr.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
packer {
required_version = ">= 1.8.7"

required_plugins {
amazon = {
version = ">= 1.1.6"
source = "github.com/hashicorp/amazon"
}
}
}

locals {
ami_name = "runtime-ephemeral-${formatdate("YYYYMMDDhhmm", timestamp())}"
}

source "amazon-ebs" "ubuntu" {
ami_name = local.ami_name
ami_description = "For testing uds-runtime releases"
instance_type = "t3a.medium"
region = "us-west-2"
ssh_username = "ubuntu"
# ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-20230608
source_ami = "ami-008fe2fc65df48dac"
}

build {
name = local.ami_name
sources = ["source.amazon-ebs.ubuntu"]

# wait for cloud-init to finish before running the install script
provisioner "shell" {
inline = [
"/usr/bin/cloud-init status --wait",
"echo set debconf to Noninteractive",
"echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections"
]
timeout = "5m"
}

# install tools
provisioner "shell" {
script = "./install-tools.sh"
timeout = "15m"
}
}
32 changes: 32 additions & 0 deletions .github/test-infra/tasks/infra.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
variables:
- name: REGION
- name: STATE_BUCKET
- name: STATE_DYNAMO_TABLE
- name: STATE_KEY

tasks:
- name: init
description: "initialize runtime test infra"
actions:
- dir: .github/test-infra/terraform
cmd: |
tofu init -force-copy \
-backend-config="bucket=${STATE_BUCKET}" \
-backend-config="key=${STATE_KEY}" \
-backend-config="region=${REGION}" \
-backend-config="dynamodb_table=${DYNAMODB_TABLE}"
- name: create-iac
description: "spinup runtime test infra"
actions:
- task: init
- cmd: tofu apply -auto-approve
dir: .github/test-infra/terraform

- name: destroy-iac
description: "destroy runtime test infra"
actions:
- task: init
description: "initialize to get state from s3 in order to destroy from previous run"
- cmd: tofu destroy -auto-approve
dir: .github/test-infra/terraform
176 changes: 176 additions & 0 deletions .github/test-infra/terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
provider "aws" {
region = var.region
}

resource "random_id" "unique_id" {
byte_length = 4
}

data "aws_caller_identity" "current" {}

data "aws_ami" "latest_runtime_ephemeral_ami" {
most_recent = true

filter {
name = "name"
values = ["runtime-ephemeral-*"]
}

owners = ["${data.aws_caller_identity.current.account_id}"]
}

locals {
suffix = random_id.unique_id.hex
tags = tomap({
"Name" = "runtime-ephemeral-${local.suffix}"
"ManagedBy" = "Terraform"
"CreationDate" = time_static.creation_time.rfc3339
"nuke" : "DO-NOT-DELETE"
"PermissionsBoundary" = "${var.permissions_boundary_name}"
})
}

resource "time_static" "creation_time" {}

resource "aws_instance" "runtime" {
ami = data.aws_ami.latest_runtime_ephemeral_ami.image_id
instance_type = "m5.2xlarge"
iam_instance_profile = aws_iam_instance_profile.runtime_profile.name
key_name = var.enable_ssh ? aws_key_pair.ssh[0].key_name : null
tags = local.tags

vpc_security_group_ids = [aws_security_group.security_group.id]
user_data = file("setup.sh")
root_block_device {
volume_size = 32
volume_type = "gp2"
delete_on_termination = true
}
}

// Get EIP ID
data "aws_eip" "runtime_eip" {
filter {
name = "tag:Name"
values = ["runtime-ephemeral"]
}
}

// Attach EIP to Instance
resource "aws_eip_association" "runtime" {
instance_id = aws_instance.runtime.id
allocation_id = data.aws_eip.runtime_eip.id
}

resource "aws_iam_instance_profile" "runtime_profile" {
name = "runtime-ephemeral-EC2InstanceProfile"
role = aws_iam_role.runtime_role.name
tags = local.tags
}

resource "aws_iam_policy" "secrets_manager_policy" {
name = "runtime-ephemeral-SecretsManagerPolicy"
description = "Allows access to specific secrets"

# Define the policy JSON
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecrets",
"secretsmanager:DescribeSecret"
]
Resource = "arn:aws:secretsmanager:${var.region}:${data.aws_caller_identity.current.account_id}:secret:runtime-tls-*"
}
]
})
}

resource "aws_iam_role" "runtime_role" {
name = "runtime-ephemeral-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
permissions_boundary = var.permissions_boundary_arn
tags = local.tags
}

resource "aws_iam_role_policy_attachment" "secrets_manager_policy_attachment" {
role = aws_iam_role.runtime_role.name
policy_arn = aws_iam_policy.secrets_manager_policy.arn
}

resource "aws_security_group" "security_group" {
name = "runtime-ephemeral-sg-${random_id.unique_id.hex}"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

// Allow HTTP traffic but istio will redirect to HTTPS
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

# for local testing
dynamic "ingress" {
for_each = var.enable_ssh ? [1] : []
content {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["${var.ssh_ip}/32"]
}
}

tags = local.tags
}

#
# SSH Config for Testing
#
resource "tls_private_key" "ssh" {
count = var.enable_ssh ? 1 : 0

algorithm = "RSA"
rsa_bits = 4096
}

resource "local_file" "ssh_pem" {
count = var.enable_ssh ? 1 : 0

filename = "runtime-dev.pem"
content = tls_private_key.ssh[0].private_key_pem
file_permission = "0400"
}

resource "aws_key_pair" "ssh" {
count = var.enable_ssh ? 1 : 0

key_name = "runtime-dev-key"
public_key = tls_private_key.ssh[0].public_key_openssh
}
32 changes: 32 additions & 0 deletions .github/test-infra/terraform/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/sh

# clone and alter uds-k3d with new domain
git clone https://github.com/defenseunicorns/uds-k3d.git

# Define the file path
file_path="uds-k3d/chart/templates/nginx.yaml"

# # Replace 'uds.dev' with 'exploding.boats'
sed -i 's/uds\.dev/burning.boats/g' "$file_path"

# # Deploy cluster
cd uds-k3d && uds run

# Get kubeconfig
mkdir -p /home/ubuntu/.kube
k3d kubeconfig get uds > /home/ubuntu/.kube/config

# CD to home directory or uds can't find the kubeconfig
cd /home/ubuntu

# Get TLS cert and key
TLS_CERT=$(aws secretsmanager get-secret-value --secret-id "runtime-tls-cert" --query "SecretString" --output text --region us-west-2 | uds zarf tools yq --input-format json '."runtime-tls-cert"')
TLS_KEY=$(aws secretsmanager get-secret-value --secret-id "runtime-tls-key" --query "SecretString" --output text --region us-west-2 | uds zarf tools yq --input-format json '."runtime-tls-key"')

export UDS_ADMIN_TLS_CERT=$TLS_CERT
export UDS_ADMIN_TLS_KEY=$TLS_KEY
export UDS_TENANT_TLS_CERT=$TLS_CERT
export UDS_TENANT_TLS_KEY=$TLS_KEY

uds deploy ghcr.io/defenseunicorns/packages/uds/bundles/k3d-core-demo:0.25.2 --packages=init,core --set DOMAIN=burning.boats --confirm
uds zarf package deploy oci://ghcr.io/defenseunicorns/packages/uds/uds-runtime:nightly-unstable --confirm
27 changes: 27 additions & 0 deletions .github/test-infra/terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
variable "region" {
description = "The AWS region to deploy the EC2 instance"
type = string
default = "us-west-2"
}

variable "permissions_boundary_name" {
description = "The name of the permissions boundary to attach to the IAM role"
type = string
}

variable "permissions_boundary_arn" {
description = "The ARN of the permissions boundary to attach to the IAM role"
type = string
}

variable "enable_ssh" {
description = "Enable SSH access to the EC2 instance"
type = bool
default = false
}

variable "ssh_ip" {
description = "The IP address to allow SSH access from"
type = string
default = ""
}
18 changes: 18 additions & 0 deletions .github/test-infra/terraform/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
terraform {
backend "s3" {}
required_version = ">= 1.6.0, <= 1.8.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.62.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.1.0"
}
time = {
source = "hashicorp/time"
version = ">= 0.9.1"
}
}
}
Loading

0 comments on commit 2ba9e26

Please sign in to comment.