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:
BIN
.github/images/setup_domain_end_state.png
vendored
Normal file
BIN
.github/images/setup_domain_end_state.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
.github/images/setup_domain_workflow.png
vendored
Normal file
BIN
.github/images/setup_domain_workflow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
.github/images/setup_domain_workflow_domain.png
vendored
Normal file
BIN
.github/images/setup_domain_workflow_domain.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
BIN
.github/images/setup_domain_workflow_inventory.png
vendored
Normal file
BIN
.github/images/setup_domain_workflow_inventory.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -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.
|
||||||
|
|||||||
@@ -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
15
windows/connect.yml
Normal 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:
|
||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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
9
windows/rollback.yml
Normal 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') }}"
|
||||||
@@ -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'"
|
||||||
|
|||||||
27
windows/setup_domain_workflow.md
Normal file
27
windows/setup_domain_workflow.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Setup Active Directory Domain
|
||||||
|
|
||||||
|
A workflow to create a domain controller with two domain-joined Windows hosts.
|
||||||
|
|
||||||
|
## The Workflow
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Domain (ansible.local)
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## PowerShell Validation
|
||||||
|
|
||||||
|
In the validation step, you can expect to see the following output based on querying AD computers:
|
||||||
|
|
||||||
|

|
||||||
37
windows/tasks/domain_services_check.yml
Normal file
37
windows/tasks/domain_services_check.yml
Normal 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..."
|
||||||
Reference in New Issue
Block a user