Monday, 25 April 2016

W16 Lab Series: Part 2 - DNS Setup

Note: The DNS cmdlets used in this post require the WFA server is on Windows 2012 or better.

Every single IP address used on the network should have a corresponding DNS A-Record and PTR record; this is basic good network housekeeping. Ping by name to get the IP, ping -a by IP to get what it is. We need DNS entries in place for our Cluster Build. This post assumes the required reverse lookup zones already exist (they damn well should do if the DNS admins are doing their job properly.)

The awesome thing about OnCommand Workflow Automation is that, even though it is a NetApp product, you can use it to automate pretty much anything that has APIs exposed and a PowerShell/PERL way of utilizing those APIs. In this post, we use WFA to generate the DNS A and PTR records prior to the Cluster build (this is unlikely to be the job of the Storage Admin, still it’s nice to see how it could be done).

1) Installing DNS Tools on the WFA Server

Run the following command in PowerShell>

Add-WindowsFeature RSAT-DNS-Server

2) Giving the WFA User DNS Permission

We did this in Part 1, but here it is again (done on the Domain Conroller):

Add-ADGroupMember -Identity "DnsAdmins" -Members "WFA"

3) The PowerShell Code to do the DNS Job

The following code works without alteration both inside and outside WFA (using “WFA Environment Detection”). It takes as input a file path to a file containing the Hostnames and IP addresses we want to add to DNS, the DNS Domain where we want to create these, and the DNS server name where the records will first be created (prior to replication to other DNS servers.)


Param(
  [Parameter(Mandatory=$True,HelpMessage="File path")]
  [String]$FilePath,
  [Parameter(Mandatory=$True,HelpMessage="DNS Domain")]
  [String]$DnsDomain,
  [Parameter(Mandatory=$True,HelpMessage="DNS Server")]
  [String]$DnsServer
)

## ===== WFA ENVIRONMENT DETECTION ===== ##
[Boolean]$WfaDetected = $FALSE
If(Get-Command Get-WFALogger -ErrorAction SilentlyContinue){ $WfaDetected = $TRUE }

## ===== OUTPUT FUNCTION ===== ##
Function Wr{
  Param([String]$Echo = "",[String]$Ink = "WHITE")
  If($WfaDetected -and $Echo){
    If($Ink -eq "RED"){ Get-WFALogger -Error -message $("$Echo") }
    elseif($Ink -eq "YELLOW"){ Get-WFALogger -Warn -message $("$Echo") }
    else{ Get-WFALogger -Error -message $("$Echo") }
  }
  If(!$WfaDetected){ Write-Host $Echo -ForegroundColor $Ink }
};Wr

## ===== ADD-DNSRECORD ===== ##
[System.Array]$Content = @()
If(Test-Path $FilePath){
  Wr "Loaded file from $FilePath" GREEN;Wr
  $GetContent = Get-Content $FilePath
  $GetContent | Foreach{ $Content += $_.Trim("`t"," ") }
  $Content = $Content | Where { ($_ -ne "") -and !($_.StartsWith("#")) -and (($_.Split("`t").Count -ge 2) -or ($_.Split(" ").Count -ge 2)) }
  If($Content.Count -ge 2){
    $Content = $Content[1..($Content.Count -1)]
    $Content | Foreach {
      [String]$Separator = "`t"
      If($_.Split($Separator).Count -lt 2){ $Separator = " " }
      $Length    = $_.Split($Separator).Count
      $Hostname  = $_.Split($Separator)[0].Trim("`t"," ")
      $IpAddress = $_.Split($Separator)[$Length -1].Trim("`t"," ")
      Wr ("Running: Add-DnsServerResourceRecordA $HostName" + "." + "$DnsDomain $IpAddress") CYAN
      Add-DnsServerResourceRecordA -Name $HostName -ZoneName $DnsDomain -IPv4Address $IpAddress -CreatePtr -ComputerName $DnsServer
    } 
  }else{
    Wr "Not enough content, require at least 1 line header, and 1 line of Hostname IP Address" RED
  }
}else{
  Wr "Failed to load file from $FilePath" RED
};Wr


Note: A lot of the script is simply checking the input. The action line is the Add-DnsServerResourceRecordA line (the cmdlet requires Server 2012+).

4) The Input File

Here’s an example. The script can handle tab delimited, or space delimited lines, or a mixture of tab and space delimited. The first line is always assumed to be a heading line. It will not process lines beginning with # or empty lines. Each valid input line should just have a hostname and an IP Address.

HOSTNAME      IPADDRESS
naclu1        10.0.1.100
naclu1n1      10.0.1.101
naclu1n2      10.0.1.102
naclu1-svm0   10.0.1.111
naclu1n1-rep1 10.0.1.171
naclu1n1-rep2 10.0.1.181
naclu1n2-rep1 10.0.1.172
naclu1n2-rep2 10.0.1.182
naclu2        10.0.2.100
naclu2n1      10.0.2.101
naclu2-svm0   10.0.2.111
naclu2n1-rep1 10.0.2.171
naclu2n1-rep2 10.0.2.181


Note: These represent, cluster management, node management, svm0 is a management LIF that will be used by an Active Directory authentication SVM (will have no data volumes, just used for the Domain Tunnel), and rep1 and rep2 for node intercluster LIFs (replication).

5) Testing in PowerShell

Image: An example testing the script in PowerShell with the example input file above

6) Creating Command in WFA

6.1: Login to WFA
6.2: Click on Designer tab
6.3: Click on Commands
6.4: Click to add a new Command
6.5: Click on the Code tab and paste the script in as PowerShell, and click the button to ‘Discover Parameters’
6.6: Click on the Properties tab
6.7: Give the command a Name ‘Add DNS Records’
6.8: Give the command a String Representation like - DnsDomain + " update DNS from file " + FilePath
6.9: Click Save

Image: Creating the Add DNS Records Command in WFA

7) Creating the Workflow

7.1: Click on Workflows
7.2: Click on Add

Image: Creating a New Workflow

7.3: Drag the new ‘Add DNS Records’ command to the panel

Image: Creating a New Workflow - Adding a Command

7.4.1: Hover the pointer beneath “Add DNS Records” and click on the +
7.4.2: For DNS Domain, we’ll use a static entry “lab.priv” since only one DNS domain in lab corp.
7.4.3: For FilePath specify $FilePath - this will be a required input
7.4.4: For DnsServer, we again use a static entry “MSDMC01” for one of the DNS servers in lab corp.
7.4.5: Click OK

Image: Parameters for ‘Add DNS Records’

7.5.1: Click on the Details tab
7.5.2: Give the workflow a name “Add DNS Records”
7.5.3: Tick ‘Ready for production’

Image: Add Workflow Details tab

7.6.1: Click on the ‘User Inputs’ tab
7.6.2: Double-click on FilePath
7.6.3: Click on ‘Display Name’ and make more user friendly
7.6.4: Click on ‘Description’ and make more descriptive
7.6.5: Tick the ‘Mandatory’ tick box
7.6.6: Click OK
7.6.7: Click Save
7.6.8: Click Close

Image: New Workflow ‘User Inputs’ tab

8) Running the Workflow

IMPORTANT NOTE: This workflow requires NetApp WFA Server service to run as LAB\WFA.

Image: NetApp WFA Server service running as LAB\WFA

8.1: Find the new workflow in the Portal
8.2: Click the ‘Add DNS Records’ workflow
8.3: Enter the file path
8.4: Click Execute

Image: Running the Workflow

And - all being well - the workflow should run and the required DNS entries created.

Image: Add DNS Records successful execution


4 comments:

  1. This is a fantastic blog, thank you for your magic posts. It will help me too much!!!!

    ReplyDelete
  2. This is a fantastic blog, thank you for your magic posts. It will help me too much!!!!

    ReplyDelete
  3. hi there,

    My understanding is that name resolution changed in 8.3 and I think this type of thing is no longer required as it was in 8.2

    "Active Directory authentication SVM (will have no data volumes, just used for the Domain Tunnel)"

    TR 4379 page 15. That doesnt mean you cant do what you do here but just wanted to flag important changes in 8.3

    Thanks,
    Eric
    Another one of your online fans.

    ReplyDelete
    Replies
    1. Hi Unknown (Eric), there's a cunning reason why I was going to the trouble of making sure all my LIF IPs are in DNS and reverse lookup-able. The idea was the my cluster build workflow would know what cluster it's building, and simply need to do reverse lookups to get the IPs (i.e. reducing user input.) I can't see this workflow happening any time soon. Cheers VC
      PS A "Day-0 c-mode cluster build setup" appeared on the WFA Automation Store on the 13th May.

      Delete