diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e7b8817..04ca613 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,10 @@ "features": { "ghcr.io/devcontainers/features/azure-cli:1": {}, "ghcr.io/devcontainers-extra/features/devcontainers-cli:1": {} - } + }, + + // Run script after container is created + "postCreateCommand": "chmod +x ./scripts/install-packer.sh && ./scripts/install-packer.sh" // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d7a0217 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "hashicorp.hcl" + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..d4bfc0a --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,23 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Install Packer", + "type": "shell", + "command": "./scripts/install-packer.sh", + "args": [], + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "shared", + "close": false + }, + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 624a4e3..e8c54d1 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The key elements in this repo are: - **Bicep Modules:** These bicep modules provide "lego bricks" for assembling your infrastructure-as-code" deployments and are built to meet the specification of Government customers and impact levels. - **Developer Scripts:** These scripts are designed to include common operations that are designed to provide "easy-buttons" to prevent having to lookup what each of these steps is, and how they work. - **Github Composite Actions:** These are composite actions designed specifically to be atomic and reusable in a variety of situations. The intention being that these are common steps to prevent technical debt, improve quality, and increase stability by leveraging a single code instance. +- **Packer VM Configuration:** These are packer images for specific virtual machines that are designed to support specific use-cases. ## Bicep Modules @@ -80,7 +81,6 @@ DEFAULT_TAG_VALUE="" # The value of the tag. az deployment group create --resource-group $RESOURCE_GROUP_NAME --template-file ./modules/virtual-machine.bicep --parameters vm_name=$VM_NAME subnet_id=$SUBNET_ID data_science_vm_type=$MACHINE_TYPE admin_user_name=$ADMIN_USER_NAME default_tag_name=$DEFAULT_TAG_NAME default_tag_value=$DEFAULT_TAG_VALUE ``` - ## Developer Scripts For this repo there are several developer scripts designed to provide support for common operations. They are outlined below: @@ -129,4 +129,46 @@ When identifying the "@" value at the end of the line, you have 2 options: 1. You can use "@main" which will always pull the "main" branch version that is available. That does mean that you will always being using the latest, and if the parameter signature changes, it wil fail. 2. You can pin to the "latest" of that action file, by using "@__ACTION_NAME__-latest" (for example: get-agent-details-latest). This is predominantly used for testing. -3. You can pin to a specific version number, by using "@__ACTION_NAME__-__VERSION_NUMBER__" (for example: get-agent-details-1.0.0), this will pin you to a specific release. \ No newline at end of file +3. You can pin to a specific version number, by using "@__ACTION_NAME__-__VERSION_NUMBER__" (for example: get-agent-details-1.0.0), this will pin you to a specific release. + +## Packer Virtual Machine Configuration: + +This repo contains virtual machine configurations to support new environments that are created. The following are the key virtual machine configuration files in this repo: + +- **[kubernetes-linux-jumpbox.pkr.hcl](./vm-images/kubernetes-linux-jumpbox.pkr.hcl): This machine provides a jumpbox for accessing and working with kubernetes clusters. + +### Build packer vm images: + +To build a VM image in your Azure subscription using the `./vm-images/kubernetes-linux-jumpbox.pkr.hcl` file, follow these steps: + +1. **Install Packer** + Make sure you have [Packer](https://developer.hashicorp.com/packer/install) installed on your machine. You can run this script to install it or use the repo task by hitting F1. + + ```bash + bash ./scripts/install-packer.sh + ``` + +2. **Authenticate with Azure** + Ensure you are logged in to Azure CLI and have the necessary permissions: + ```bash + az cloud set --name AzureUSGovernment + az login --use-device-code + az account set --subscription "" + ``` + +3. **Validate the Packer Template** + Run the following command to validate your Packer template: + ```bash + packer validate ./vm-images/kubernetes-linux-jumpbox.pkr.hcl + ``` + +4. **Build the Image** + Execute the build command: + ```bash + packer build -var "subscription_id=" -var "location=" ./vm-images/kubernetes-linux-jumpbox.pkr.hcl + ``` + +5. **Locate the Image in Azure** + After the build completes, the image will be available in the resource group and location specified in your Packer template. + +> For more details, see the [Packer Azure Builder documentation](https://developer.hashicorp.com/packer/plugins/builders/azure). diff --git a/bicep-sample/sample-app-service.bicep b/bicep-sample/sample-app-service.bicep new file mode 100644 index 0000000..949883d --- /dev/null +++ b/bicep-sample/sample-app-service.bicep @@ -0,0 +1,21 @@ +param prefix string +param location string = 'usgovvirginia' +param appServicePlanSku string = 'P1v2' + +resource appService 'Microsoft.Web/sites@2022-03-01' = { + name: '${prefix}-app' + location: location + properties: { + serverFarmId: appServicePlan.id + } +} + +resource appServicePlan 'Microsoft.Web/serverfarms@2022-03-01' = { + name: '${prefix}-app-plan' + location: location + sku: { + name: appServicePlanSku + tier: 'PremiumV2' + } + kind: 'app' +} diff --git a/bicep-sample/sample-deployment.bicep b/bicep-sample/sample-deployment.bicep new file mode 100644 index 0000000..2bc92e6 --- /dev/null +++ b/bicep-sample/sample-deployment.bicep @@ -0,0 +1,40 @@ +targetScope = 'subscription' +@description('Prefix for the resource names') +param prefix string + +@description('Location for the resource group') +param location string = 'usgovvirginia' + +@description('SKU for the App Service Plan') +param appServicePlanSku string = 'P1v2' + +@description('SKU for the Storage Account') +param storageSku string = 'Standard_LRS' + +// Resource Group +resource resourceGroup 'Microsoft.Resources/resourceGroups@2024-11-01' = { + name: '${prefix}-rg' + location: location +} + +module appServiceModule 'sample-app-service.bicep' = { + name: 'appServiceModule' + scope: resourceGroup + params: { + prefix: prefix + location: location + appServicePlanSku: appServicePlanSku + } +} +module storageModule 'sample-storage.bicep' = { + name: 'storageModule' + scope: resourceGroup + params: { + prefix: prefix + location: location + storageSku: storageSku + } +} + +// Output resource IDs +output resourceGroupId string = resourceGroup.id diff --git a/bicep-sample/sample-storage.bicep b/bicep-sample/sample-storage.bicep new file mode 100644 index 0000000..bf0356e --- /dev/null +++ b/bicep-sample/sample-storage.bicep @@ -0,0 +1,12 @@ +param prefix string +param location string = 'usgovvirginia' +param storageSku string = 'Standard_LRS' + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { + name: '${prefix}stg' + location: location + sku: { + name: storageSku + } + kind: 'StorageV2' +} diff --git a/scripts/install-packer.sh b/scripts/install-packer.sh new file mode 100755 index 0000000..b0c8509 --- /dev/null +++ b/scripts/install-packer.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e + +# Download and add HashiCorp GPG key to the keyring +curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg + +# Add HashiCorp repository with proper keyring reference +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + +# Update package list and install Packer +sudo apt-get update && sudo apt-get install -y packer \ No newline at end of file diff --git a/vm-images/kubernetes-linux-jumpbox.pkr.hcl b/vm-images/kubernetes-linux-jumpbox.pkr.hcl new file mode 100644 index 0000000..8c4d203 --- /dev/null +++ b/vm-images/kubernetes-linux-jumpbox.pkr.hcl @@ -0,0 +1,138 @@ +variable "subscription_id" { + type = string + default = "" + description = "Azure Subscription ID" +} + +variable "location" { + type = string + default = "usgovvirginia" + description = "Azure region for the image" +} + +variable "managed_images_rg_name" { + type = string + default = "packer-vm-images" + description = "Resource group name for the Packer VM images" +} + +variable "managed_image_name" { + type = string + default = "ubuntu2404-aks-linux-jumpbox-image" + description = "Name of the managed image to be created by Packer" +} + +packer { + required_plugins { + azure = { + version = ">= 1.0.0" + source = "github.com/hashicorp/azure" + } + } +} + +source "azure-arm" "ubuntu2404" { + subscription_id = var.subscription_id + cloud_environment_name = "AzureUSGovernmentCloud" + location = var.location + + managed_image_resource_group_name = var.managed_images_rg_name + managed_image_name = var.managed_image_name + + vm_size = "Standard_DS1_v2" + os_type = "Linux" + image_publisher = "Canonical" + image_offer = "ubuntu-24_04-lts" + image_sku = "server" + image_version = "latest" + + azure_tags = { + environment = "image-library" + } + + use_azure_cli_auth = true +} + +build { + sources = ["source.azure-arm.ubuntu2404"] + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Running the initial setup upgrade...'", + "sudo apt-get update", + "sudo apt-get upgrade -y" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing 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", + "kubectl version --client" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Install Azure CLI...'", + "curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing Helm...'", + "curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3", + "chmod 700 get_helm.sh", + "./get_helm.sh" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing k9s...'", + "wget https://github.com/derailed/k9s/releases/download/v0.50.6/k9s_linux_amd64.deb", + "sudo apt install ./k9s_linux_amd64.deb", + "k9s version", + "rm k9s_linux_amd64.deb" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing Terraform...'", + "wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg", + "echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main\" | sudo tee /etc/apt/sources.list.d/hashicorp.list", + "sudo apt update && sudo apt install terraform" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing RegClient...'", + "curl -L https://github.com/regclient/regclient/releases/latest/download/regctl-linux-amd64 >regctl", + "chmod 755 regctl" + ] + } + + provisioner "shell" { + environment_vars = ["DEBIAN_FRONTEND=noninteractive"] + inline = [ + "echo 'Installing Docker...'", + "sudo apt-get install ca-certificates curl", + "sudo install -m 0755 -d /etc/apt/keyrings", + "sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc", + "sudo chmod a+r /etc/apt/keyrings/docker.asc", + "echo \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] 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" + ] + } +} \ No newline at end of file