MyLab - itnett/FTD02H-N GitHub Wiki
To create a fully automated CI/CD environment on Windows 11 that sets up and tears down lab environments, follow these steps:
Step 1: Create a PowerShell Script for Environment Setup
setup-environment.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log-Message
To create a comprehensive CI/CD environment on Windows 11 that sets up and tears down various lab environments automatically, we'll follow these steps:
### Step 1: Prepare the Environment
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log-Message "Terraform applied
To create a comprehensive CI/CD environment on Windows 11 that sets up and tears down various lab environments, we will develop scripts to automate the installation, configuration, and management of software components such as VirtualBox, Docker, Minikube, WSL, and Terraform. The environment should be capable of deploying multiple lab configurations (e.g., `mylab1`, `mylab2`, etc.), ensuring that the system remains clean and well-managed.
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to
To create a comprehensive CI/CD environment on Windows 11 that automates the setup, configuration, and teardown of various lab environments, follow these steps:
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log
To create a comprehensive CI/CD environment on Windows 11 that automates the setup, configuration, and teardown of various lab environments, follow these steps:
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log
To create a fully automated CI/CD environment on Windows 11 that sets up and tears down lab environments, follow these steps:
### Step 1: Create a PowerShell Script for Environment Setup
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log-Message
To create a comprehensive CI/CD environment on Windows 11 that sets up and tears down various lab environments automatically, we'll follow these steps:
### Step 1: Prepare the Environment
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log-Message "Terraform applied
To create a comprehensive CI/CD environment on Windows 11 that sets up and tears down various lab environments, we will develop scripts to automate the installation, configuration, and management of software components such as VirtualBox, Docker, Minikube, WSL, and Terraform. The environment should be capable of deploying multiple lab configurations (e.g., `mylab1`, `mylab2`, etc.), ensuring that the system remains clean and well-managed.
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to
To create a comprehensive CI/CD environment on Windows 11 that automates the setup, configuration, and teardown of various lab environments, follow these steps:
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log
To create a comprehensive CI/CD environment on Windows 11 that automates the setup, configuration, and teardown of various lab environments, follow these steps:
### Step 1: Prepare the Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip = terraform output -raw vm_ip
Log
To set up a clean CI/CD environment on Windows 11 that automates the creation and management of multiple lab environments, follow these detailed steps:
### Step 1: Prepare Environment Setup Script
Create a PowerShell script to set up the directory structure and initiate the installation of necessary software.
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
Create a PowerShell script to install necessary software using Chocolatey.
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
Create a bash script to configure Ansible within the WSL environment.
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
Create a Terraform configuration to set up a VirtualBox VM.
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
Create an Ansible playbook to configure the VM.
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
Create a PowerShell script to automate the entire setup process.
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1
To set up a clean CI/CD environment on Windows 11, follow these steps to automate the creation and management of multiple lab environments using PowerShell, Terraform, Ansible, and other necessary tools:
### Step 1: Prepare Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
# Step 3: Apply Terraform configuration
Log-Message "Applying Terraform configuration..."
try {
cd $basePath\terraform
terraform init
terraform apply -auto-approve
$vm_ip =
To set up a clean CI/CD environment on Windows 11, follow these steps to automate the creation and management of multiple lab environments using PowerShell, Terraform, Ansible, and other necessary tools. The setup ensures the environment is clean and well-managed, with the ability to create, destroy, and manage various lab environments.
### Step 1: Prepare Environment Setup Script
Create a PowerShell script to set up the directory structure and initiate the installation of necessary software.
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
Create a PowerShell script to install necessary software using Chocolatey.
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
Create a bash script to configure Ansible within the WSL environment.
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
Create a Terraform configuration to set up a VirtualBox VM.
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
Create an Ansible playbook to configure the VM.
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
Create a PowerShell script to automate the entire setup process.
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Clean existing environment
To create a CI/CD environment on Windows 11 that automatically sets up, configures, and manages multiple lab environments using VirtualBox, Docker, Minikube, WSL, and Terraform, follow these steps:
### Step 1: Prepare Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1
# Path to download installers
$downloadPath = "C:\temp"
# Log file path
$logFile = "C:\lab\mylab\logs\install-software.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "C:\lab\mylab\logs")) {
New-Item -ItemType Directory -Path "C:\lab\mylab\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Create the download directory if it does not exist
if (-Not (Test-Path -Path $downloadPath)) {
try {
New-Item -ItemType Directory -Path $downloadPath -Force
Log-Message "Download directory created: $downloadPath"
} catch {
Log-Message "Failed to create download directory: $downloadPath - $_"
}
}
# Install Chocolatey if not installed
if (-Not (Get-Command choco -ErrorAction SilentlyContinue)) {
try {
Set-ExecutionPolicy Bypass -Scope Process -Force;
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Log-Message "Chocolatey installed."
} catch {
Log-Message "Failed to install Chocolatey: $_"
}
}
# Install software
$software = @("virtualbox", "docker-desktop", "terraform", "git", "minikube")
foreach ($app in $software) {
try {
choco install $app -y
Log-Message "$app installed."
} catch {
Log-Message "Failed to install $app: $_"
}
}
# Install WSL and Ubuntu
try {
wsl --install -d Ubuntu
Log-Message "WSL and Ubuntu installed."
} catch {
Log-Message "Failed to install WSL and Ubuntu: $_"
}
Write-Output "All software installed. Please restart your computer to complete the installation."
Log-Message "All software installed. Please restart your computer to complete the installation."
Step 3: Configure Ansible in WSL
configure-ansible.sh
#!/bin/bash
LOGFILE="/mnt/c/lab/mylab/logs/configure-ansible.log"
# Function to log messages
log_message() {
local MESSAGE=$1
echo "$(date +'%Y-%m-%d %H:%M:%S') - $MESSAGE" | tee -a $LOGFILE
}
log_message "Starting Ansible configuration..."
# Update and upgrade the system
log_message "Updating and upgrading the system..."
sudo apt update && sudo apt upgrade -y
if [ $? -ne 0 ]; then
log_message "Failed to update and upgrade the system."
exit 1
else
log_message "System updated and upgraded successfully."
fi
# Install Ansible
log_message "Installing Ansible..."
sudo apt install ansible -y
if [ $? -ne 0 ]; then
log_message "Failed to install Ansible."
exit 1
else
log_message "Ansible installed successfully."
fi
# Verify Ansible installation
ANSIBLE_VERSION=$(ansible --version)
log_message "Ansible version: $ANSIBLE_VERSION"
Step 4: Create Terraform File
main.tf
provider "virtualbox" {}
resource "virtualbox_vm" "ubuntu_vm" {
name = "ubuntu-lab-vm"
image = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64-vagrant.box"
cpus = 2
memory = "2048 mib"
network_adapter {
type = "hostonly"
host_interface = "vboxnet0"
}
disk {
image = "${path.module}/../vbox/vms/ubuntu-lab-vm-disk.vdi"
size = "20 gib"
}
}
output "vm_ip" {
value = virtualbox_vm.ubuntu_vm.network_adapter.0.ipv4_address
}
Step 5: Create Ansible Playbook
playbook.yml
- name: Configure Ubuntu VM
hosts: all
become: yes
tasks:
- name: Update and upgrade apt packages
apt:
update_cache: yes
upgrade: dist
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
- name: Install Docker
apt:
name: docker.io
state: present
notify:
- Start Docker
register: result
ignore_errors: yes
- name: Log result
debug:
var: result
handlers:
- name: Start Docker
service:
name: docker
state: started
Step 6: Create Script to Automate Entire Setup
deploy-lab.ps1
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\deploy-lab.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Clean existing environment
Log-Message "Cleaning existing environment..."
if (Test-Path -Path $basePath) {
Remove-Item -Recurse -Force -Path $basePath
}
Log-Message "Existing environment cleaned."
# Step 2: Run setup-environment script
Log-Message "Running setup-environment script..."
try {
.\scripts\setup-environment.ps1 -LabName $LabName
} catch {
Handle-Error "Failed to run setup-environment script: $_"
}
To create a comprehensive CI/CD environment on Windows 11 that automates the creation, configuration, and management of lab environments, follow these steps. This setup involves using PowerShell, Chocolatey, WSL, Ansible, Terraform, and VirtualBox.
### Step 1: Environment Setup Script
**`setup-environment.ps1`**
```powershell
param (
[string]$LabName = "mylab1"
)
# Define base path
$basePath = "C:\lab\$LabName"
# Log file path
$logFile = "$basePath\logs\setup-environment.log"
# Create log directory if it does not exist
if (-Not (Test-Path -Path "$basePath\logs")) {
New-Item -ItemType Directory -Path "$basePath\logs" -Force
}
# Function to log messages
function Log-Message {
param (
[string]$message
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "$timestamp - $message"
Write-Output $logMessage
Add-Content -Path $logFile -Value $logMessage
}
# Function to handle errors
function Handle-Error {
param (
[string]$errorMessage
)
Log-Message "ERROR: $errorMessage"
exit 1
}
# Step 1: Create Directory Structure
Log-Message "Creating directory structure..."
try {
$dirs = @(
"$basePath\ansible",
"$basePath\docker",
"$basePath\terraform",
"$basePath\vbox\vms",
"$basePath\vbox\iso",
"$basePath\wsl",
"$basePath\scripts",
"$basePath\git"
)
foreach ($dir in $dirs) {
if (-Not (Test-Path -Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force
}
}
Log-Message "Directory structure created."
} catch {
Handle-Error "Failed to create directory structure: $_"
}
# Step 2: Install Necessary Software
Log-Message "Installing necessary software..."
try {
.\scripts\install-software.ps1
} catch {
Handle-Error "Failed to install necessary software: $_"
}
# Step 3: Restart the computer to complete installations
Log-Message "Please restart your computer to complete the installation. After restart, run this script again."
Start-Sleep -Seconds 5
exit
Step 2: Install Necessary Software
install-software.ps1