In my previous blog I have described for Using vRealize Orchestrator to Create a DNS Entry When vRealize Automation Deploys a VM
In this blog I am going to describe how to Join Windows VM to AD using ansible playbook through vRealize Automation 8 .
Use case: -
There are also other simple solutions to join VM to AD through VM Customization Specifications But I have picked the use case, where client do not have VM Customization Specifications available on vCenter as per client compliance and security policy.
we need to integrate Ansible with vRealize Automation 8 before create blueprint. I have already explained in my previous blog. Please follow my previous blog for Ansible Integration.
First, we need to prepare VM template for WinRM configuration. This allow ansible to connect to guest VM.
Let’s start to configure base OS VM.
In this step you’re going to learn how to set up WinRm using certificate-based authentication using self-signed certificates so that Ansible can talk to them.
Enable PowerShell Remoting for Ansible WinRM :-
Windows Server 2016 or later servers have PowerShell Remoting enabled, it’s always a good idea to confirm that.
open up a PowerShell console as an administrator and run the following code snippet.
Set-Service -Name "WinRM" -StartupType Automatic
Start-Service -Name "WinRM"
Ensure Enable PS remoting is enabling on windows VM.
if (-not (Get-PSSessionConfiguration) -or (-not (Get-ChildItem WSMan:\localhost\Listener))) { |
Enable-PSRemoting -SkipNetworkProfileCheck -Force |
}
Enable Certificate-Based Authentication :-
Basic authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell.
Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true
Create a Local User Account :-
To use certificate-based authentication with Ansible, you must “map” a local user account to a certificate. You could use the local administrator account to do this but some time we cannot use local administrator so best way create a specific account to make management easier.
Here I have create username as ansibletestuser. This user must be part of Local Administrator Group.
Create the Client Certificate :-
Need to enable certificate-based auth with Ansible, We must have two certificates as a client certificate and a server certificate.
To create the client certificate, you must create a private and a public key. Start by SSHing to the Ansible host and run the following openssl command. This command creates a private key in a file called cert_key.pem and a public key called cert.pem.
cat > openssl.conf << EOL
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req_client]
extendedKeyUsage = clientAuth
subjectAltName = otherName:1.3.6.1.4.1.311.20.2.3;UTF8:ansibletestuser@localhost
EOL
export OPENSSL_CONF=openssl.conf
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out cert.pem -outform PEM -keyout cert_key.pem -subj "/CN=ansibletestuser" -extensions v3_req_client
rm openssl.conf
Once above task get done then after verify the folder if you can see cert_key.pem and cert.pem.
Now time to import the Client Certificate
First, you need to copy cert.pem from Ansible tower to Base OS VM.
Once you have the public certificate on the Windows host, import it into the Trusted Root Certification Authorities and Trusted People certificate stores using Import-Certificate as shown below.
pubKeyFilePath = 'C:\cert.pem'
$null = Import-Certificate -FilePath $pubKeyFilePath -CertStoreLocation 'Cert:\LocalMachine\Root'
$null = Import-Certificate -FilePath $pubKeyFilePath -CertStoreLocation 'Cert:\LocalMachine\TrustedPeople'
Create the Server Certificate :-
Ansible needs a certificate with a key usage for server authentication. This certificate will be stored in the Windows host’s LocalMachine\My certificate store.
$hostname = hostname
$serverCert = New-SelfSignedCertificate -DnsName $hostName -CertStoreLocation 'Cert:\LocalMachine\My'
Create the Ansible WinRm Listener :-
Once We have created both certificates. We need to create a WinRm listener on the base OS VM. This listener begins listening on port 5986 for incoming connections. Once created, this listener accepts incoming connections and will attempt to encrypt data using the server certificate created above.
$httpsListeners = Get-ChildItem -Path WSMan:\localhost\Listener\ | where-object { $_.Keys -match 'Transport=HTTPS' }
if ((-not $httpsListeners) -or -not (@($httpsListeners).where( { $_.CertificateThumbprint -ne $serverCert.Thumbprint }))) {
$newWsmanParams = @{
ResourceUri = 'winrm/config/Listener'
SelectorSet = @{ Transport = "HTTPS"; Address = "*" }
ValueSet = @{ Hostname = $hostName; CertificateThumbprint = $serverCert.Thumbprint }
# UseSSL = $true
}
$null = New-WSManInstance @newWsmanParams
}
Map the Client Certificate to the Local User Account :-
Ensure when Ansible connects to the Windows host using the server certificate, it will then carry out all instructions as a local user. In this case, all activity performed by Ansible will use the local user account, ansibletestuser.
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $testUserAccountName, $testUserAccountPassword
$ansibleCert = Get-ChildItem -Path 'Cert:\LocalMachine\Root' | Where-Object {$_.Subject -eq 'CN=ansibletestuser'}
$params = @{
Path = 'WSMan:\localhost\ClientCertificate'
Subject = "$testUserAccountName@localhost"
URI = '*'
Issuer = $ansibleCert.Thumbprint
Credential = $credential
Force = $true
}
New-Item @params
Once we have followed each of these steps as shown, you should now be able to execute Ansible commands against a Windows host and we have completed our base OS VM.
Ansible Playbook and Template creation:-
Ansible playbook to perform AD join for the VM need to be setup in Ansible server.
I used same playbook and created the template in Ansible.
---
- hosts: winclient
ansible_facts: yes
tasks:
- name: Add node to domain
win_domain_membership:
dns_domain_name: "{{ domainans }}"
domain_admin_user: "{{ domainans }}\\{{ adusr }}"
domain_admin_password: "{{adpass }}"
hostname: "{{ ansible_facts['nodename'] }}"
domain_ou_path: "{{ winadou }}"
state: domain
register: domain_state
- win_reboot:
when:
- domain_state.reboot_required is defined
Ansible Template
I am passing host variable from my ansible template. If you do not have Ansible template then you can define inside blueprint as well.
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_cert_key_pem: /usr/local/cert_key.pem
ansible_winrm_cert_pem: /usr/local/cert.pem
ansible_winrm_server_cert_validation: ignore
ansible_winrm_transport: certificate
winaddom: vrcloud.com
winadou: 'OU=vrcloddev,DC=vrcloud,DC=com'
vRA Blueprint :-
Now time to create blueprint and my blueprint looks like below.
name: Randhir_Windows
version: 1
formatVersion: 1
inputs:
MachineName:
type: string
title: Name for the VM
description: Enter the VM name
os-image:
type: string
oneOf
- title: MT0-Ansible
const: MT0-Ansible
SelectZone:
type: string
enum:
- Production
- Management
SelectFlavor:
type: string
enum:
- MTO-PROD-LARGE
- MTO-PROD-MEDIUM
- MTO-PROD-SMALL
resources:
Cloud_vSphere_Machine_1:
type: Cloud.vSphere.Machine
properties:
constraints:
- tag: '${input.SelectZone}'
image: '${input.os-image}'
flavor: '${input.SelectFlavor}'
hostName: '${input.MachineName}'
networks:
- network: '${resource.Cloud_vSphere_Network_1.id}'
assignment: static
Cloud_vSphere_Network_1:
type: Cloud.vSphere.Network
properties:
networkType: existing
name: vranew
networkCidr: 192.168.20.0/24
Cloud_Ansible_Tower_1:
type: Cloud.Ansible.Tower
properties:
host: '${resource.Cloud_vSphere_Machine_1.*}'
account: MTO-Ansible
jobTemplates:
provision
- MTODomain (This Ansible template name)
I have used above YAML code to create blueprint and deployed VM through it.
Let see if we have successful job in ansible to join VM to AD.
Yes, Job has been completed successfully and VM joint the domain as well you can see below.
Now we have successfully deployed vm and able to join AD.
Stay with me to read the next upcoming my blog, How to Join Linux VM to AD using Ansible playbook through vRealize Automation 8.x
I hope you enjoy reading this blog as much as I enjoyed writing it. Feel free to share this on social media if it is worth sharing.
No comments:
Post a Comment