Add BI App file server and configuration management for hosts
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -28,3 +28,5 @@ terraform.rc
|
|||||||
*-credentials.tfbackend
|
*-credentials.tfbackend
|
||||||
|
|
||||||
.terraform.lock.hcl
|
.terraform.lock.hcl
|
||||||
|
|
||||||
|
vault.yml
|
||||||
20
configuration/ansible_fs/ansible.cfg
Normal file
20
configuration/ansible_fs/ansible.cfg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[defaults]
|
||||||
|
|
||||||
|
inventory = inventories/production/hosts.yml
|
||||||
|
|
||||||
|
roles_path = roles
|
||||||
|
|
||||||
|
host_key_checking = False
|
||||||
|
|
||||||
|
remote_user = Administrator
|
||||||
|
|
||||||
|
timeout = 30
|
||||||
|
interpreter_python = auto_silent
|
||||||
|
forks = 20
|
||||||
|
pipelining = True
|
||||||
|
bin_ansible_callbacks = True
|
||||||
|
retry_files_enabled = False
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no
|
||||||
|
transfer_method = scp
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
---
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
fs_server_password: ""
|
||||||
|
|
||||||
|
domain_name: ""
|
||||||
|
domain_join_user: ""
|
||||||
|
domain_join_password: ""
|
||||||
|
domain_ou_path: ""
|
||||||
10
configuration/ansible_fs/inventories/production/hosts.yml
Normal file
10
configuration/ansible_fs/inventories/production/hosts.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
all:
|
||||||
|
children:
|
||||||
|
fs_servers:
|
||||||
|
hosts:
|
||||||
|
SK3SFS1P.ad.cwx.hr:
|
||||||
|
ansible_host: 10.10.2.101
|
||||||
|
ansible_connection: ssh
|
||||||
|
ansible_shell_type: powershell
|
||||||
|
ansible_user: Administrator
|
||||||
|
ansible_password: "{{ fs_server_password }}"
|
||||||
6
configuration/ansible_fs/playbooks/setup-fs.yml
Normal file
6
configuration/ansible_fs/playbooks/setup-fs.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
- name: Configure file servers
|
||||||
|
hosts: fs_servers
|
||||||
|
roles:
|
||||||
|
- common
|
||||||
|
- smb_share
|
||||||
7
configuration/ansible_fs/roles/common/defaults/main.yml
Normal file
7
configuration/ansible_fs/roles/common/defaults/main.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
domain_name: "example.local"
|
||||||
|
domain_join_user: "{{ domain_join_user }}"
|
||||||
|
domain_join_password: "{{ domain_join_password }}"
|
||||||
|
domain_ou_path: ""
|
||||||
|
|
||||||
|
data_disk_number: 1
|
||||||
71
configuration/ansible_fs/roles/common/tasks/main.yml
Normal file
71
configuration/ansible_fs/roles/common/tasks/main.yml
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
- name: Wait for system to be fully booted
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
sleep: 10
|
||||||
|
|
||||||
|
- name: Ensure Windows Update service is running
|
||||||
|
ansible.windows.win_service:
|
||||||
|
name: wuauserv
|
||||||
|
state: started
|
||||||
|
start_mode: auto
|
||||||
|
|
||||||
|
- name: Ensure BITS service is running
|
||||||
|
ansible.windows.win_service:
|
||||||
|
name: BITS
|
||||||
|
state: started
|
||||||
|
start_mode: auto
|
||||||
|
|
||||||
|
- name: Install Windows updates (loop until no more pending)
|
||||||
|
ansible.windows.win_updates:
|
||||||
|
category_names:
|
||||||
|
- SecurityUpdates
|
||||||
|
- CriticalUpdates
|
||||||
|
- UpdateRollups
|
||||||
|
- Updates
|
||||||
|
state: installed
|
||||||
|
reboot: true
|
||||||
|
reboot_timeout: 3600
|
||||||
|
server_selection: windows_update
|
||||||
|
register: win_updates_result
|
||||||
|
until: win_updates_result.installed_update_count == 0
|
||||||
|
retries: 5
|
||||||
|
delay: 30
|
||||||
|
|
||||||
|
- name: Report Windows Update result
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: >-
|
||||||
|
Windows Update complete.
|
||||||
|
Last pass installed {{ win_updates_result.installed_update_count }} update(s).
|
||||||
|
Reboot required: {{ win_updates_result.reboot_required }}.
|
||||||
|
|
||||||
|
- name: Join Active Directory domain
|
||||||
|
microsoft.ad.membership:
|
||||||
|
dns_domain_name: "{{ domain_name }}"
|
||||||
|
hostname: "{{ inventory_hostname_short }}"
|
||||||
|
domain_admin_user: "{{ domain_join_user }}"
|
||||||
|
domain_admin_password: "{{ domain_join_password }}"
|
||||||
|
domain_ou_path: "{{ domain_ou_path | default(omit) }}"
|
||||||
|
state: domain
|
||||||
|
reboot: true
|
||||||
|
reboot_timeout: 1800
|
||||||
|
|
||||||
|
- name: Initialize data disk as GPT
|
||||||
|
community.windows.win_initialize_disk:
|
||||||
|
disk_number: "{{ data_disk_number }}"
|
||||||
|
style: gpt
|
||||||
|
online: true
|
||||||
|
|
||||||
|
- name: Create shares partition (F:)
|
||||||
|
community.windows.win_partition:
|
||||||
|
disk_number: "{{ data_disk_number }}"
|
||||||
|
partition_size: -1
|
||||||
|
drive_letter: F
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Format shares partition (F:)
|
||||||
|
community.windows.win_format:
|
||||||
|
drive_letter: F
|
||||||
|
file_system: NTFS
|
||||||
|
new_label: FileShares
|
||||||
|
allocation_unit_size: 65536
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
smb_shares:
|
||||||
|
- name: k8s
|
||||||
|
path: 'F:\Shares\k8s'
|
||||||
|
description: "Kubernetes CSI SMB persistent volume share"
|
||||||
|
full_access:
|
||||||
|
- "CWX\\k8s-svc-user"
|
||||||
|
change_access: []
|
||||||
42
configuration/ansible_fs/roles/smb_share/tasks/main.yml
Normal file
42
configuration/ansible_fs/roles/smb_share/tasks/main.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
- name: Install File Server role
|
||||||
|
ansible.windows.win_feature:
|
||||||
|
name: FS-FileServer
|
||||||
|
state: present
|
||||||
|
include_management_tools: true
|
||||||
|
register: fs_role
|
||||||
|
|
||||||
|
- name: Reboot if File Server role install requires it
|
||||||
|
ansible.windows.win_reboot:
|
||||||
|
when: fs_role.reboot_required
|
||||||
|
|
||||||
|
- name: Create share directories
|
||||||
|
ansible.windows.win_file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
loop: "{{ smb_shares }}"
|
||||||
|
|
||||||
|
- name: Create SMB shares
|
||||||
|
ansible.windows.win_share:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
description: "{{ item.description | default('') }}"
|
||||||
|
full: "{{ item.full_access | default([]) | join(',') or omit }}"
|
||||||
|
change: "{{ item.change_access | default([]) | join(',') or omit }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ smb_shares }}"
|
||||||
|
|
||||||
|
- name: Disable SMB1 protocol
|
||||||
|
ansible.windows.win_powershell:
|
||||||
|
script: |
|
||||||
|
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force
|
||||||
|
|
||||||
|
- name: Open SMB firewall port
|
||||||
|
community.windows.win_firewall_rule:
|
||||||
|
name: "File and Printer Sharing (SMB-In)"
|
||||||
|
localport: 445
|
||||||
|
action: allow
|
||||||
|
direction: in
|
||||||
|
protocol: tcp
|
||||||
|
state: present
|
||||||
|
enabled: true
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
34613730306335623333623230346639323439343264366138623465656138346535663236336635
|
62323935633064326661353036336664643438613562613439346166316436613431653664316634
|
||||||
3933323931303236313761656337383735373332393366620a396664653239623437353263306563
|
3536313163636338343664326436653133313531303462320a616135323639313431343231343934
|
||||||
64643237666633343165633230363065306561376166613735396562386464623532393730643765
|
61343965326235356339656237386365363061303633386431623430373734633535306439353937
|
||||||
3135326437616236640a363463383363626539383465663731313833306138633061386666313535
|
3935313331356336660a303162306433346335336232303733623035396661316664636236393164
|
||||||
37636564373437313933636234636339613330613935336666343433376630346664336336383538
|
35336330356335396262613739666139356161306663613435366339383761343666306632343732
|
||||||
62623761323539363536313031623135333831643638336234643264343632393863363539653461
|
65366439643532333532656566313764303061323461326439616235623931663665353961373236
|
||||||
32393333646131316337653636386563396562613961383335323431623835653434333839613635
|
37623366303430656132373261356466313735383435373133613564396463623638393530613235
|
||||||
63353433656630366166336239643766653938363033373137623532353237353261383261623437
|
31336466366166333164366564663564366662363236353936306332623738386534326438353363
|
||||||
31366237353462623731343766653832343936363738373031633231373038376435613662616234
|
65373630313535313166346661303235663966303637623433393164356533626233323632653264
|
||||||
34373861656361353863326432616436316537643065313564306131616636383939343438333838
|
62626235363939623532393863623665303731393066376562666536623066643863366564333135
|
||||||
37326532663639666332313239316635313637333262633636376237653036343465646638303263
|
34343030643266393235653239623431633763326533656366663537383461383763383034646563
|
||||||
31333866633966346534303564623164373637303337646632326135666535663566333833356537
|
64653565383061636530643561306132636532393432356166353063303831396537623662343039
|
||||||
30323061613231393332346262393261343731363462623536313964313466666238363532613762
|
63363735383530636239313231363332643839336135646262613931633734616663633737363434
|
||||||
65666163376231313065393861643635626136316434643761386137306530346533653366643830
|
65343233376461643338323232313730326439396161373133376232633866623334396330393437
|
||||||
63363738366134323665323232313439323865323235313331316164393431373362646630336261
|
37643261343265376466616537313864326436656532393830656135393939386564636235633138
|
||||||
39313732376531336230663032363437343862646331613831623063336164373465343136643037
|
65316364383230383532396364323739306465353237613533613239613965663134623438646434
|
||||||
66643130636538383339393435616563323930386262343134636134373434326561
|
63383730313265363535363466363433316339323666636164616164613832613233
|
||||||
|
|||||||
13
provisioning/SK3SFS1P/backend.tfbackend
Normal file
13
provisioning/SK3SFS1P/backend.tfbackend
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
bucket = "cwxbkp1-prod"
|
||||||
|
key = "proxmox/prod/SK3SFS1P/terraform.tfstate"
|
||||||
|
region = "eu-central"
|
||||||
|
|
||||||
|
endpoints = {
|
||||||
|
s3 = "https://nbg1.your-objectstorage.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
force_path_style = true
|
||||||
|
skip_credentials_validation = true
|
||||||
|
skip_metadata_api_check = true
|
||||||
|
skip_region_validation = true
|
||||||
|
skip_requesting_account_id = true
|
||||||
58
provisioning/SK3SFS1P/main.tf
Normal file
58
provisioning/SK3SFS1P/main.tf
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.6.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "~> 0.73"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backend "s3" {}
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "proxmox" {
|
||||||
|
endpoint = var.proxmox_endpoint
|
||||||
|
insecure = var.proxmox_insecure
|
||||||
|
api_token = var.proxmox_api_token
|
||||||
|
|
||||||
|
ssh {
|
||||||
|
username = var.proxmox_ssh_user
|
||||||
|
password = var.proxmox_ssh_password
|
||||||
|
agent = var.proxmox_ssh_agent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module "vm" {
|
||||||
|
source = "../modules/vm"
|
||||||
|
|
||||||
|
node_name = var.node_name
|
||||||
|
vm_id = var.vm_id
|
||||||
|
name = var.name
|
||||||
|
description = var.description
|
||||||
|
tags = var.tags
|
||||||
|
bios = "ovmf"
|
||||||
|
os_type = "win11"
|
||||||
|
|
||||||
|
cpu_cores = var.cpu_cores
|
||||||
|
memory_dedicated = var.memory_dedicated
|
||||||
|
|
||||||
|
clone_vm_id = var.clone_vm_id
|
||||||
|
clone_datastore_id = var.clone_datastore_id
|
||||||
|
|
||||||
|
init_ipv4_address = var.init_ipv4_address
|
||||||
|
init_ipv4_gateway = var.init_ipv4_gateway
|
||||||
|
init_dns_servers = var.init_dns_servers
|
||||||
|
init_username = var.init_username
|
||||||
|
admin_password = var.admin_password
|
||||||
|
cloud_init_datastore = var.cloud_init_datastore
|
||||||
|
|
||||||
|
disk_datastore = var.disk_datastore
|
||||||
|
disk_size = var.disk_size
|
||||||
|
|
||||||
|
data_disk_size = var.data_disk_size
|
||||||
|
data_disk_datastore = var.data_disk_datastore
|
||||||
|
|
||||||
|
network_bridge = var.network_bridge
|
||||||
|
network_vlan_id = var.network_vlan_id
|
||||||
|
}
|
||||||
19
provisioning/SK3SFS1P/outputs.tf
Normal file
19
provisioning/SK3SFS1P/outputs.tf
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
output "vm_id" {
|
||||||
|
description = "The Proxmox VM ID"
|
||||||
|
value = module.vm.vm_id
|
||||||
|
}
|
||||||
|
|
||||||
|
output "name" {
|
||||||
|
description = "The VM hostname"
|
||||||
|
value = module.vm.name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "ipv4_addresses" {
|
||||||
|
description = "IPv4 addresses reported by the QEMU agent"
|
||||||
|
value = module.vm.ipv4_addresses
|
||||||
|
}
|
||||||
|
|
||||||
|
output "mac_addresses" {
|
||||||
|
description = "MAC addresses of the VM's network interfaces"
|
||||||
|
value = module.vm.mac_addresses
|
||||||
|
}
|
||||||
27
provisioning/SK3SFS1P/terraform.tfvars.example
Normal file
27
provisioning/SK3SFS1P/terraform.tfvars.example
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
proxmox_endpoint = "https://proxmox.example.local:8006/api2/json"
|
||||||
|
proxmox_insecure = true
|
||||||
|
proxmox_api_token = "packer@pve!packer=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
|
|
||||||
|
proxmox_ssh_user = "root"
|
||||||
|
proxmox_ssh_password = "changeme"
|
||||||
|
proxmox_ssh_agent = false
|
||||||
|
|
||||||
|
node_name = "pve"
|
||||||
|
|
||||||
|
vm_id = 201
|
||||||
|
name = "SK3SFS1P"
|
||||||
|
init_ipv4_address = "10.0.0.101/24"
|
||||||
|
init_ipv4_gateway = "10.0.0.1"
|
||||||
|
init_dns_servers = ["10.0.0.2", "10.0.0.3"]
|
||||||
|
admin_password = "ChangeMe-StrongPassword!"
|
||||||
|
|
||||||
|
cpu_cores = 4
|
||||||
|
memory_dedicated = 8192
|
||||||
|
disk_size = 80
|
||||||
|
disk_datastore = "local-lvm"
|
||||||
|
data_disk_size = 30
|
||||||
|
data_disk_datastore = "local-lvm"
|
||||||
|
network_bridge = "vmbr0"
|
||||||
|
cloud_init_datastore = "local-lvm"
|
||||||
|
|
||||||
|
clone_vm_id = 1002
|
||||||
152
provisioning/SK3SFS1P/variables.tf
Normal file
152
provisioning/SK3SFS1P/variables.tf
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
variable "proxmox_endpoint" {
|
||||||
|
description = "URL of the Proxmox API (e.g. https://192.168.1.10:8006/)"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_insecure" {
|
||||||
|
description = "Skip TLS certificate verification (set true for self-signed certs)"
|
||||||
|
type = bool
|
||||||
|
default = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_api_token" {
|
||||||
|
description = "Proxmox API token in the form user@realm!tokenid=secret"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_ssh_user" {
|
||||||
|
description = "SSH username for the Proxmox node"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_ssh_password" {
|
||||||
|
description = "SSH password for connecting to the Proxmox node"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_ssh_agent" {
|
||||||
|
description = "Use SSH agent for authentication"
|
||||||
|
type = bool
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "node_name" {
|
||||||
|
description = "Proxmox cluster node name"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_id" {
|
||||||
|
description = "Unique Proxmox VM ID"
|
||||||
|
type = number
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "name" {
|
||||||
|
description = "VM hostname"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "description" {
|
||||||
|
description = "VM description"
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "tags" {
|
||||||
|
description = "Tags to apply to the VM"
|
||||||
|
type = list(string)
|
||||||
|
default = []
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cpu_cores" {
|
||||||
|
type = number
|
||||||
|
default = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "memory_dedicated" {
|
||||||
|
description = "RAM in MB"
|
||||||
|
type = number
|
||||||
|
default = 2048
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "clone_vm_id" {
|
||||||
|
description = "VM ID of the Windows template to clone"
|
||||||
|
type = number
|
||||||
|
default = 1002
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "clone_datastore_id" {
|
||||||
|
description = "Target datastore for the cloned disks (null = keep on source datastore)"
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disk_datastore" {
|
||||||
|
type = string
|
||||||
|
default = "local-lvm"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disk_size" {
|
||||||
|
description = "Disk size in GB"
|
||||||
|
type = number
|
||||||
|
default = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "data_disk_size" {
|
||||||
|
description = "Size in GB of the data disk. Set to null to skip."
|
||||||
|
type = number
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "data_disk_datastore" {
|
||||||
|
description = "Proxmox datastore ID for the data disk."
|
||||||
|
type = string
|
||||||
|
default = "local-lvm"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "network_bridge" {
|
||||||
|
type = string
|
||||||
|
default = "vmbr11"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "network_vlan_id" {
|
||||||
|
type = number
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "init_ipv4_address" {
|
||||||
|
description = "IPv4 address in CIDR notation (e.g. 10.10.2.100/24) or dhcp"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "init_ipv4_gateway" {
|
||||||
|
description = "IPv4 gateway address"
|
||||||
|
type = string
|
||||||
|
default = null
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "init_dns_servers" {
|
||||||
|
description = "List of DNS servers for initialization"
|
||||||
|
type = list(string)
|
||||||
|
default = []
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "init_username" {
|
||||||
|
description = "Username for the initial account"
|
||||||
|
type = string
|
||||||
|
default = "Administrator"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "admin_password" {
|
||||||
|
description = "Password for the initial account"
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cloud_init_datastore" {
|
||||||
|
description = "Datastore used to store the cloud-init drive"
|
||||||
|
type = string
|
||||||
|
default = "local"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user