Workflow to setup Windows Domain with DC and hosts (#168)

Co-authored-by: willtome <wtome@redhat.com>
Co-authored-by: Chris Edillon <67980205+jce-redhat@users.noreply.github.com>
This commit is contained in:
Zach LeBlanc
2024-08-29 13:15:40 -05:00
committed by GitHub
parent 035f815486
commit 8a99b66adc
13 changed files with 304 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
.github/images/setup_domain_workflow.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -4,12 +4,17 @@
- [Windows Demos](#windows-demos) - [Windows Demos](#windows-demos)
- [Table of Contents](#table-of-contents) - [Table of Contents](#table-of-contents)
- [About These Demos](#about-these-demos) - [About These Demos](#about-these-demos)
- [Known Issues](#known-issues)
- [Jobs](#jobs) - [Jobs](#jobs)
- [Workflows](#workflows)
- [Suggested Usage](#suggested-usage) - [Suggested Usage](#suggested-usage)
## About These Demos ## About These Demos
This category of demos shows examples of Windows Server operations and management with Ansible Automation Platform. The list of demos can be found below. See the [Suggested Usage](#suggested-usage) section of this document for recommendations on how to best use these demos. This category of demos shows examples of Windows Server operations and management with Ansible Automation Platform. The list of demos can be found below. See the [Suggested Usage](#suggested-usage) section of this document for recommendations on how to best use these demos.
### Known Issues
We are currently investigating an intermittent connectivity issue related to the credentials for Windows hosts. If encountered, re-provision your demo environment. You can track the issue and related work [here](https://github.com/ansible/product-demos/issues/176).
### Jobs ### Jobs
- [**WINDOWS / Install IIS**](install_iis.yml) - Install IIS feature with a configurable index.html - [**WINDOWS / Install IIS**](install_iis.yml) - Install IIS feature with a configurable index.html
@@ -23,8 +28,13 @@ This category of demos shows examples of Windows Server operations and managemen
- [**WINDOWS / Helpdesk new user portal**](helpdesk_new_user_portal.yml) - Create user in AD Domain - [**WINDOWS / Helpdesk new user portal**](helpdesk_new_user_portal.yml) - Create user in AD Domain
- [**WINDOWS / Join Active Directory Domain**](join_ad_domain.yml) - Join computer to AD Domain - [**WINDOWS / Join Active Directory Domain**](join_ad_domain.yml) - Join computer to AD Domain
### Workflows
- [**Setup Active Directory Domain**](setup_domain_workflow.md) - A workflow to create a domain controller with two domain-joined Windows hosts
## Suggested Usage ## Suggested Usage
**Setup Active Directory Domain** - One-click domain setup, infrastructure included.
**WINDOWS / Create Active Directory Domain** - This job can take some to complete. It is recommended to run ahead of time if you would like to demo creating a helpdesk user. **WINDOWS / Create Active Directory Domain** - This job can take some to complete. It is recommended to run ahead of time if you would like to demo creating a helpdesk user.
**WINDOWS / Helpdesk new user portal** - This job is dependant on the Create Active Directory Domain completing before users can be created. **WINDOWS / Helpdesk new user portal** - This job is dependant on the Create Active Directory Domain completing before users can be created.

View File

@@ -1,7 +0,0 @@
---
- name: Rollback playbook
hosts: windows
tasks:
- name: "Rollback this step"
ansible.builtin.debug:
msg: "Rolling back this step"

15
windows/connect.yml Normal file
View File

@@ -0,0 +1,15 @@
---
- name: Connectivity test
hosts: "{{ _hosts | default('os_windows') }}"
gather_facts: false
tasks:
- name: Wait 600 seconds for target connection to become reachable/usable
ansible.builtin.wait_for_connection:
connect_timeout: "{{ wait_for_timeout_sec | default(5) }}"
delay: "{{ wait_for_delay_sec | default(0) }}"
sleep: "{{ wait_for_sleep_sec | default(1) }}"
timeout: "{{ wait_for_timeout_sec | default(300) }}"
- name: Ping the windows host
ansible.builtin.win_ping:

View File

@@ -9,18 +9,24 @@
name: Administrator name: Administrator
password: "{{ ansible_password }}" password: "{{ ansible_password }}"
- name: Update the hostname
ansible.windows.win_hostname:
name: "{{ inventory_hostname.split('.')[0] }}"
- name: Reboot to apply new hostname
ansible.windows.win_reboot:
reboot_timeout: 3600
- name: Create new domain in a new forest on the target host - name: Create new domain in a new forest on the target host
register: r_create_domain
ansible.windows.win_domain: ansible.windows.win_domain:
dns_domain_name: ansible.local dns_domain_name: ansible.local
safe_mode_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}" safe_mode_password: "{{ lookup('community.general.random_string', min_lower=1, min_upper=1, min_special=1, min_numeric=1) }}"
notify:
- Reboot host
- Wait for AD services
- Reboot again
- Wait for AD services again
- name: Flush handlers - name: Verify domain services running
ansible.builtin.meta: flush_handlers when: r_create_domain is changed
ansible.builtin.include_tasks:
file: tasks/domain_services_check.yml
- name: Create some groups - name: Create some groups
community.windows.win_domain_group: community.windows.win_domain_group:
@@ -48,28 +54,3 @@
groups: "GroupC" groups: "GroupC"
retries: 5 retries: 5
delay: 10 delay: 10
handlers:
- name: Reboot host
ansible.windows.win_reboot:
reboot_timeout: 3600
- name: Wait for AD services
community.windows.win_wait_for_process:
process_name_exact: Microsoft.ActiveDirectory.WebServices
pre_wait_delay: 60
state: present
timeout: 600
sleep: 10
- name: Reboot again
ansible.windows.win_reboot:
reboot_timeout: 3600
- name: Wait for AD services again
community.windows.win_wait_for_process:
process_name_exact: Microsoft.ActiveDirectory.WebServices
pre_wait_delay: 60
state: present
timeout: 600
sleep: 10

View File

@@ -4,22 +4,31 @@
gather_facts: false gather_facts: false
tasks: tasks:
- name: Extract domain controller private ip
ansible.builtin.set_fact:
domain_controller_private_ip: "{{ hostvars[groups['purpose_domain_controller'][0]]['private_ip_address'] }}"
- name: Set a single address on the adapter named Ethernet - name: Set a single address on the adapter named Ethernet
ansible.windows.win_dns_client: ansible.windows.win_dns_client:
adapter_names: 'Ethernet*' adapter_names: 'Ethernet*'
dns_servers: "{{ hostvars[domain_controller]['private_ip_address'] }}" dns_servers: "{{ domain_controller_private_ip }}"
- name: Ensure Demo OU exists - name: Ensure Demo OU exists
run_once: true
delegate_to: "{{ domain_controller }}" delegate_to: "{{ domain_controller }}"
community.windows.win_domain_ou: community.windows.win_domain_ou:
name: Demo name: Demo
state: present state: present
- name: Update the hostname
ansible.windows.win_hostname:
name: "{{ inventory_hostname.split('.')[0] }}"
- name: Join ansible.local domain - name: Join ansible.local domain
register: r_domain_membership register: r_domain_membership
ansible.windows.win_domain_membership: ansible.windows.win_domain_membership:
dns_domain_name: ansible.local dns_domain_name: ansible.local
hostname: "{{ inventory_hostname }}" hostname: "{{ inventory_hostname.split('.')[0] }}"
domain_admin_user: "{{ ansible_user }}@ansible.local" domain_admin_user: "{{ ansible_user }}@ansible.local"
domain_admin_password: "{{ ansible_password }}" domain_admin_password: "{{ ansible_password }}"
domain_ou_path: "OU=Demo,DC=ansible,DC=local" domain_ou_path: "OU=Demo,DC=ansible,DC=local"

9
windows/rollback.yml Normal file
View File

@@ -0,0 +1,9 @@
---
- name: Rollback playbook
hosts: "{{ _hosts | default('os_windows') }}"
gather_facts: false
tasks:
- name: Rollback this step
ansible.builtin.debug:
msg: "{{ rollback_msg | default('rolling back this step') }}"

View File

@@ -81,6 +81,52 @@ controller_templates:
- 'Yes' - 'Yes'
- 'No' - 'No'
- name: "WINDOWS / Rollback"
job_type: run
inventory: "Demo Inventory"
project: "Ansible official demo project"
playbook: "windows/rollback.yml"
execution_environment: Default execution environment
notification_templates_started: Telemetry
notification_templates_success: Telemetry
notification_templates_error: Telemetry
credentials:
- "Demo Credential"
survey_enabled: true
survey:
name: ''
description: ''
spec:
- question_name: Server Name or Pattern
type: text
variable: _hosts
required: false
- question_name: Rollback Message
type: text
variable: rollback_msg
required: false
- name: "WINDOWS / Test Connectivity"
job_type: run
inventory: "Demo Inventory"
project: "Ansible official demo project"
playbook: "windows/connect.yml"
execution_environment: Default execution environment
notification_templates_started: Telemetry
notification_templates_success: Telemetry
notification_templates_error: Telemetry
credentials:
- "Demo Credential"
survey_enabled: true
survey:
name: ''
description: ''
spec:
- question_name: Server Name or Pattern
type: text
variable: _hosts
required: false
- name: "WINDOWS / Chocolatey install multiple" - name: "WINDOWS / Chocolatey install multiple"
job_type: run job_type: run
inventory: "Demo Inventory" inventory: "Demo Inventory"
@@ -306,3 +352,139 @@ controller_templates:
type: text type: text
variable: HOSTS variable: HOSTS
required: false required: false
controller_workflows:
- name: Setup Active Directory Domain
description: A workflow to create a domain controller with two domain-joined Windows hosts.
organization: Default
notification_templates_started: Telemetry
notification_templates_success: Telemetry
notification_templates_error: Telemetry
survey_enabled: true
survey:
name: ''
description: ''
spec:
- question_name: AWS Region
type: multiplechoice
variable: create_vm_aws_region
required: true
default: us-east-2
choices:
- us-east-1
- us-east-2
- us-west-1
- us-west-2
- question_name: Keypair Public Key
type: textarea
variable: aws_public_key
required: true
# Create VM variables
- question_name: Owner
type: text
variable: create_vm_vm_owner
required: true
- question_name: Environment
type: multiplechoice
variable: create_vm_vm_environment
required: true
choices:
- Dev
- QA
- Prod
- question_name: Subnet
type: text
variable: create_vm_aws_vpc_subnet_name
required: true
default: aws-test-subnet
- question_name: Security Group
type: text
variable: create_vm_aws_securitygroup_name
required: true
default: aws-test-sg
simplified_workflow_nodes:
- identifier: Create Keypair
unified_job_template: Cloud / AWS / Create Keypair
success_nodes:
- Create VPC
- identifier: Create VPC
unified_job_template: Cloud / AWS / Create VPC
success_nodes:
- Create Domain Controller
- Create Computer (1)
- Create Computer (2)
- identifier: Create Domain Controller
unified_job_template: Cloud / AWS / Create VM
job_type: run
extra_data:
create_vm_vm_name: dc01.ansible.local
create_vm_vm_purpose: domain_controller
create_vm_vm_deployment: domain_ansible_local
vm_blueprint: windows_full
success_nodes:
- Inventory Sync
- identifier: Create Computer (1)
unified_job_template: Cloud / AWS / Create VM
job_type: run
extra_data:
create_vm_vm_name: winston.ansible.local
create_vm_vm_purpose: domain_computer
create_vm_vm_deployment: domain_ansible_local
vm_blueprint: windows_core
success_nodes:
- Inventory Sync
- identifier: Create Computer (2)
unified_job_template: Cloud / AWS / Create VM
job_type: run
extra_data:
create_vm_vm_name: winthrop.ansible.local
create_vm_vm_purpose: domain_computer
create_vm_vm_deployment: domain_ansible_local
vm_blueprint: windows_core
success_nodes:
- Inventory Sync
- identifier: Inventory Sync
unified_job_template: AWS Inventory
all_parents_must_converge: true
success_nodes:
- Test Connectivity
- identifier: Test Connectivity
unified_job_template: WINDOWS / Test Connectivity
job_type: run
extra_data:
_hosts: deployment_domain_ansible_local
failure_nodes:
- Cleanup Resources
success_nodes:
- Create Domain
- identifier: Create Domain
unified_job_template: WINDOWS / AD / Create Domain
job_type: run
extra_data:
_hosts: purpose_domain_controller
failure_nodes:
- Cleanup Resources
success_nodes:
- Join Domain
- identifier: Join Domain
unified_job_template: WINDOWS / AD / Join Domain
job_type: run
extra_data:
_hosts: purpose_domain_computer
domain_controller: dc01.ansible.local
failure_nodes:
- Cleanup Resources
success_nodes:
- PowerShell Validation
- identifier: Cleanup Resources
unified_job_template: WINDOWS / Rollback
job_type: run
extra_data:
_hosts: localhost
rollback_msg: "Domain setup failed. Cleaning up resources..."
- identifier: PowerShell Validation
unified_job_template: WINDOWS / Run PowerShell
job_type: run
extra_data:
_hosts: purpose_domain_controller
ps_script: "Get-ADComputer -Filter * | Select-Object -Property 'Name'"

View File

@@ -0,0 +1,27 @@
# Setup Active Directory Domain
A workflow to create a domain controller with two domain-joined Windows hosts.
## The Workflow
![Workflow Visualization](../.github/images/setup_domain_workflow.png)
## Ansible Inventory
There are additional groups created in the **Demo Inventory** for interacting with different components of the domain:
- **deployment_domain_ansible_local**: all hosts in the domain
- **purpose_domain_controller**: domain controller instances (1)
- **purpose_domain_computer**: domain computers (2)
![Inventory](../.github/images/setup_domain_workflow_inventory.png)
## Domain (ansible.local)
![Domain Topology](../.github/images/setup_domain_workflow_domain.png)
## PowerShell Validation
In the validation step, you can expect to see the following output based on querying AD computers:
![Expected Output](../.github/images/setup_domain_end_state.png)

View File

@@ -0,0 +1,37 @@
---
- name: Initial services check
block:
- name: Initial reboot
ansible.windows.win_reboot:
reboot_timeout: 3600
- name: Wait for AD services
community.windows.win_wait_for_process:
process_name_exact: Microsoft.ActiveDirectory.WebServices
pre_wait_delay: 60
state: present
timeout: 600
sleep: 10
rescue:
- name: Note initial failure
ansible.builtin.debug:
msg: "Initial services check failed, rebooting again..."
- name: Secondary services check
block:
- name: Reboot again
ansible.windows.win_reboot:
reboot_timeout: 3600
- name: Wait for AD services again
community.windows.win_wait_for_process:
process_name_exact: Microsoft.ActiveDirectory.WebServices
pre_wait_delay: 60
state: present
timeout: 600
sleep: 10
rescue:
- name: Note secondary failure
failed_when: true
ansible.builtin.debug:
msg: "Secondary services check failed, bailing out..."