Convert Exchange to a Terraform module
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -8,9 +8,10 @@ Boxes/*
|
|||||||
*.tfstate
|
*.tfstate
|
||||||
*.tfstate.*
|
*.tfstate.*
|
||||||
*.tfvars
|
*.tfvars
|
||||||
inventory.yml
|
ESXi/Ansible/inventory.yml
|
||||||
|
Azure/Ansible/inventory.yml
|
||||||
inventory.yml.bak
|
inventory.yml.bak
|
||||||
**/inventory.yml
|
inventory.yml
|
||||||
*.box
|
*.box
|
||||||
manifest.xml
|
manifest.xml
|
||||||
HyperV/.vagrant/*
|
HyperV/.vagrant/*
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
[defaults]
|
|
||||||
inventory = inventory.yml
|
|
||||||
host_key_checking = False
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
- hosts: exchange
|
|
||||||
roles:
|
|
||||||
- exchange
|
|
||||||
- common
|
|
||||||
tags: exchange
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../Azure/Ansible/group_vars/all.yml
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../Azure/Ansible/roles/common
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[defaults]
|
|
||||||
inventory = inventory.yml
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
- hosts: exchange
|
|
||||||
roles:
|
|
||||||
- exchange
|
|
||||||
- common
|
|
||||||
tags: exchange
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../ESXi/Ansible/group_vars/all.yml
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../ESXi/Ansible/roles/common
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#########################################
|
|
||||||
# ESXI Provider host/login details
|
|
||||||
#########################################
|
|
||||||
#
|
|
||||||
# Use of variables here to hide/move the variables to a separate file
|
|
||||||
#
|
|
||||||
provider "esxi" {
|
|
||||||
esxi_hostname = var.esxi_hostname
|
|
||||||
esxi_hostport = var.esxi_hostport
|
|
||||||
esxi_username = var.esxi_username
|
|
||||||
esxi_password = var.esxi_password
|
|
||||||
}
|
|
||||||
|
|
||||||
resource "esxi_guest" "exchange" {
|
|
||||||
guest_name = "exchange"
|
|
||||||
disk_store = var.esxi_datastore
|
|
||||||
guestos = "windows9srv-64"
|
|
||||||
|
|
||||||
boot_disk_type = "thin"
|
|
||||||
|
|
||||||
memsize = "8192"
|
|
||||||
numvcpus = "4"
|
|
||||||
resource_pool_name = "/"
|
|
||||||
power = "on"
|
|
||||||
clone_from_vm = "WindowsServer2016"
|
|
||||||
# This is the network that bridges your host machine with the ESXi VM
|
|
||||||
network_interfaces {
|
|
||||||
virtual_network = var.vm_network
|
|
||||||
mac_address = "00:50:56:a1:b2:c5"
|
|
||||||
nic_type = "e1000"
|
|
||||||
}
|
|
||||||
# This is the local network that will be used for 192.168.38.x addressing
|
|
||||||
network_interfaces {
|
|
||||||
virtual_network = var.hostonly_network
|
|
||||||
mac_address = "00:50:56:a1:b4:c5"
|
|
||||||
nic_type = "e1000"
|
|
||||||
}
|
|
||||||
guest_startup_timeout = 45
|
|
||||||
guest_shutdown_timeout = 30
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../ESXi/variables.tf
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../Vagrant/resources
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../Vagrant/scripts
|
|
||||||
@@ -11,3 +11,7 @@ wef:
|
|||||||
win10:
|
win10:
|
||||||
hosts:
|
hosts:
|
||||||
z.z.z.z:
|
z.z.z.z:
|
||||||
|
|
||||||
|
exchange:
|
||||||
|
hosts:
|
||||||
|
# v.v.v.v:
|
||||||
|
|||||||
10
Azure/Terraform/exchange.tf
Normal file
10
Azure/Terraform/exchange.tf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## Remove the block comment to enable the creation of the Exchange server
|
||||||
|
/*
|
||||||
|
module "exchange" {
|
||||||
|
source = "./modules/exchange"
|
||||||
|
resource_group_name = azurerm_resource_group.detectionlab.name
|
||||||
|
region = var.region
|
||||||
|
subnet_id = azurerm_subnet.detectionlab-subnet.id
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -1,8 +1,13 @@
|
|||||||
|
# https://github.com/terraform-providers/terraform-provider-azurerm/blob/1940d84dba45e41b2f1f868a22d7f7af1adea8a0/examples/virtual-machines/virtual_machine/vm-joined-to-active-directory/modules/active-directory/2-virtual-machine.tf
|
||||||
|
locals {
|
||||||
|
custom_data_content = file("${path.module}/../../files/winrm.ps1")
|
||||||
|
}
|
||||||
|
|
||||||
resource "azurerm_virtual_machine" "exchange" {
|
resource "azurerm_virtual_machine" "exchange" {
|
||||||
name = "exchange.windomain.local"
|
name = "exchange.windomain.local"
|
||||||
location = var.region
|
location = var.region
|
||||||
resource_group_name = azurerm_resource_group.detectionlab.name
|
resource_group_name = var.resource_group_name
|
||||||
network_interface_ids = [azurerm_network_interface.exchange-nic[count.index].id]
|
network_interface_ids = [azurerm_network_interface.exchange-nic.id]
|
||||||
vm_size = "Standard_D3_v2"
|
vm_size = "Standard_D3_v2"
|
||||||
|
|
||||||
delete_os_disk_on_termination = true
|
delete_os_disk_on_termination = true
|
||||||
@@ -39,7 +44,7 @@ resource "azurerm_virtual_machine" "exchange" {
|
|||||||
pass = "oobeSystem"
|
pass = "oobeSystem"
|
||||||
component = "Microsoft-Windows-Shell-Setup"
|
component = "Microsoft-Windows-Shell-Setup"
|
||||||
setting_name = "FirstLogonCommands"
|
setting_name = "FirstLogonCommands"
|
||||||
content = file("${path.module}/files/FirstLogonCommands.xml")
|
content = file("${path.module}/../../files/FirstLogonCommands.xml")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,21 +63,21 @@ resource "azurerm_virtual_machine" "exchange" {
|
|||||||
resource "azurerm_network_interface" "exchange-nic" {
|
resource "azurerm_network_interface" "exchange-nic" {
|
||||||
name = "exchange-nic"
|
name = "exchange-nic"
|
||||||
location = var.region
|
location = var.region
|
||||||
resource_group_name = azurerm_resource_group.detectionlab.name
|
resource_group_name = var.resource_group_name
|
||||||
|
|
||||||
ip_configuration {
|
ip_configuration {
|
||||||
name = "myNicConfiguration"
|
name = "myNicConfiguration"
|
||||||
subnet_id = azurerm_subnet.detectionlab-subnet.id
|
subnet_id = var.subnet_id
|
||||||
private_ip_address_allocation = "Static"
|
private_ip_address_allocation = "Static"
|
||||||
private_ip_address = "192.168.38.106"
|
private_ip_address = "192.168.38.106"
|
||||||
public_ip_address_id = azurerm_public_ip.exchange-publicip[count.index].id
|
public_ip_address_id = azurerm_public_ip.exchange-publicip.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "azurerm_public_ip" "exchange-publicip" {
|
resource "azurerm_public_ip" "exchange-publicip" {
|
||||||
name = "exchange-public-ip"
|
name = "exchange-public-ip"
|
||||||
location = var.region
|
location = var.region
|
||||||
resource_group_name = azurerm_resource_group.detectionlab.name
|
resource_group_name = var.resource_group_name
|
||||||
allocation_method = "Static"
|
allocation_method = "Static"
|
||||||
|
|
||||||
tags = {
|
tags = {
|
||||||
11
Azure/Terraform/modules/exchange/variables.tf
Normal file
11
Azure/Terraform/modules/exchange/variables.tf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
variable "resource_group_name" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "region" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subnet_id" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ TF_OUTPUT=$(terraform output)
|
|||||||
DC_IP=$(echo "$TF_OUTPUT" | grep -E -o "dc_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
DC_IP=$(echo "$TF_OUTPUT" | grep -E -o "dc_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
||||||
WEF_IP=$(echo "$TF_OUTPUT" | grep -E -o "wef_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
WEF_IP=$(echo "$TF_OUTPUT" | grep -E -o "wef_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
||||||
WIN10_IP=$(echo "$TF_OUTPUT" | grep -E -o "win10_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
WIN10_IP=$(echo "$TF_OUTPUT" | grep -E -o "win10_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
||||||
|
EXCHANGE_IP=$(echo "$TF_OUTPUT" | grep -E -o "exchange_public_ip = ([0-9]{1,3}[\.]){3}[0-9]{1,3}" | cut -d '=' -f 2 | tr -d ' ')
|
||||||
|
|
||||||
# Don't update unless there's default values in inventory.yml
|
# Don't update unless there's default values in inventory.yml
|
||||||
GREP_COUNT=$(grep -E -c 'x\.x\.x\.x|y\.y\.y\.y|z\.z\.z\.z' ../Ansible/inventory.yml)
|
GREP_COUNT=$(grep -E -c 'x\.x\.x\.x|y\.y\.y\.y|z\.z\.z\.z' ../Ansible/inventory.yml)
|
||||||
@@ -37,5 +38,10 @@ fi
|
|||||||
echo "Replacing the default values in DetectionLab/Azure/Ansible/inventory.yml..."
|
echo "Replacing the default values in DetectionLab/Azure/Ansible/inventory.yml..."
|
||||||
sed -i.bak "s/x.x.x.x/$DC_IP/g; s/y.y.y.y/$WEF_IP/g; s/z.z.z.z/$WIN10_IP/g" ../Ansible/inventory.yml
|
sed -i.bak "s/x.x.x.x/$DC_IP/g; s/y.y.y.y/$WEF_IP/g; s/z.z.z.z/$WIN10_IP/g" ../Ansible/inventory.yml
|
||||||
|
|
||||||
|
if [ ! -e "$EXCHANGE_IP" ]; then
|
||||||
|
echo "Exchange server found! Adding the IP to the Ansible inventory..."
|
||||||
|
sed -i.bak "s/# v.v.v.v/$EXCHANGE_IP/g" ../Ansible/inventory.yml
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Displaying the updated inventory.yml below!"
|
echo "Displaying the updated inventory.yml below!"
|
||||||
cat ../Ansible/inventory.yml
|
cat ../Ansible/inventory.yml
|
||||||
|
|||||||
@@ -16,6 +16,12 @@
|
|||||||
- common
|
- common
|
||||||
tags: wef
|
tags: wef
|
||||||
|
|
||||||
|
- hosts: exchange
|
||||||
|
roles:
|
||||||
|
- exchange
|
||||||
|
- common
|
||||||
|
tags: exchange
|
||||||
|
|
||||||
- hosts: win10
|
- hosts: win10
|
||||||
roles:
|
roles:
|
||||||
- win10
|
- win10
|
||||||
|
|||||||
9
ESXi/exchange.tf
Normal file
9
ESXi/exchange.tf
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
## Remove the block comment to enable the creation of the Exchange server
|
||||||
|
/*
|
||||||
|
module "exchange" {
|
||||||
|
source = "./modules/exchange"
|
||||||
|
disk_store = var.esxi_datastore
|
||||||
|
vm_network = var.vm_network
|
||||||
|
hostonly_network = var.hostonly_network
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -7,3 +7,31 @@ terraform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resource "esxi_guest" "exchange" {
|
||||||
|
guest_name = "exchange"
|
||||||
|
disk_store = var.disk_store
|
||||||
|
guestos = "windows9srv-64"
|
||||||
|
|
||||||
|
boot_disk_type = "thin"
|
||||||
|
|
||||||
|
memsize = "8192"
|
||||||
|
numvcpus = "4"
|
||||||
|
resource_pool_name = "/"
|
||||||
|
power = "on"
|
||||||
|
clone_from_vm = "WindowsServer2016"
|
||||||
|
# This is the network that bridges your host machine with the ESXi VM
|
||||||
|
network_interfaces {
|
||||||
|
virtual_network = var.vm_network
|
||||||
|
mac_address = "00:50:56:a1:b2:c5"
|
||||||
|
nic_type = "e1000"
|
||||||
|
}
|
||||||
|
# This is the local network that will be used for 192.168.38.x addressing
|
||||||
|
network_interfaces {
|
||||||
|
virtual_network = var.hostonly_network
|
||||||
|
mac_address = "00:50:56:a1:b4:c5"
|
||||||
|
nic_type = "e1000"
|
||||||
|
}
|
||||||
|
guest_startup_timeout = 45
|
||||||
|
guest_shutdown_timeout = 30
|
||||||
|
}
|
||||||
11
ESXi/modules/exchange/variables.tf
Normal file
11
ESXi/modules/exchange/variables.tf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
variable "vm_network" {
|
||||||
|
default = "VM Network"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "hostonly_network" {
|
||||||
|
default = "HostOnly Network"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disk_store" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
@@ -8,20 +8,20 @@
|
|||||||
cfg.winrm.retry_limit = 20
|
cfg.winrm.retry_limit = 20
|
||||||
cfg.vm.network :private_network, ip: "192.168.38.106", gateway: "192.168.38.1", dns: "192.168.38.102"
|
cfg.vm.network :private_network, ip: "192.168.38.106", gateway: "192.168.38.1", dns: "192.168.38.102"
|
||||||
|
|
||||||
cfg.vm.provision "shell", path: "scripts/fix-second-network.ps1", privileged: true, args: "-ip 192.168.38.106 -dns 8.8.8.8 -gateway 192.168.38.1"
|
cfg.vm.provision "shell", path: "../scripts/fix-second-network.ps1", privileged: true, args: "-ip 192.168.38.106 -dns 8.8.8.8 -gateway 192.168.38.1"
|
||||||
cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/provision.ps1", privileged: false
|
||||||
cfg.vm.provision "reload"
|
cfg.vm.provision "reload"
|
||||||
cfg.vm.provision "shell", path: "scripts/provision.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/provision.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/download_palantir_wef.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/download_palantir_wef.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: false
|
cfg.vm.provision "shell", inline: 'wevtutil el | Select-String -notmatch "Microsoft-Windows-LiveId" | Foreach-Object {wevtutil cl "$_"}', privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-splunkuf.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-splunkuf.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-windows_ta.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-windows_ta.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-utilities.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-utilities.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-redteam.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-redteam.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-choco-extras.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-choco-extras.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-osquery.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-osquery.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-sysinternals.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-sysinternals.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", path: "scripts/install-velociraptor.ps1", privileged: false
|
cfg.vm.provision "shell", path: "../scripts/install-velociraptor.ps1", privileged: false
|
||||||
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false
|
cfg.vm.provision "shell", inline: "Set-SmbServerConfiguration -AuditSmb1Access $true -Force", privileged: false
|
||||||
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: false
|
cfg.vm.provision "shell", inline: 'cscript c:\windows\system32\slmgr.vbs /dlv', privileged: false
|
||||||
|
|
||||||
Reference in New Issue
Block a user