Sunday, September 25, 2016

Taking first steps to DevOps world - part 2

This is second part of my multi part blog post series about suggested first steps (from point of view) to DevOps world.

Link to part 1

Environments defined by code

Purpose of scripting is automate routine tasks and release time for more important things. Another benefit on scripting is that script(s) will do steps always on same way.


Issue in traditional scripts is that dependency and error handling and especially version control is complex because it is impossible to say which scripts are applied to which environments.
Fortunately there is new tools like PowerShell DSC (Desired State Configuration) which can be used to define target environment/configuration and which will automatically make sure that correct scripts will be run on correct order.

Third lessons learned is that: Use code to define target environment/configuration instead of traditional scripts when possible.

Virtual servers

Here I have very simple example how all define these needed 12 virtual servers configuration using very simple piece of code. This example is done on Hyper-V environment (using xHyper-V module) but there is also similar module available for VMware on here.
configuration TestAppVMsToHyperV
{
    param
    (
        [string[]]$NodeName = 'localhost',

        [Parameter(Mandatory)]
        [string]$VMName,
        
        [Parameter(Mandatory)]
        [Uint64]$StartupMemory,

        [Parameter(Mandatory)]
        [Uint64]$MinimumMemory,

        [Parameter(Mandatory)]
        [Uint64]$MaximumMemory,

        [Parameter(Mandatory)]
        [String]$SwitchName,

        [Parameter(Mandatory)]
        [String]$Path,

        [Parameter(Mandatory)]
        [Uint32]$ProcessorCount,

        [ValidateSet('Off','Paused','Running')]
        [String]$State = 'Off',

        [Switch]$WaitForIP
    )

    Import-DscResource -module xHyper-V

    Node $NodeName
    {  
        xVhd DiffVhd
        {
            Ensure          = 'Present'
            Name            = $($VMName + ".vhd")
            Path            = $Path
            ParentPath      = "D:\Templates\NanoIIS_v1\NanoIIStemplate.vhd"
            Generation      = "Vhd"
        }
  
        xVMHyperV NewVM
        {
            Ensure          = 'Present'
            Name            = $VMName
            VhdPath         = $($Path + "\" + $VMName + ".vhd")
            SwitchName      = $SwitchName
            State           = $State
            Path            = $Path
            Generation      = 1
            StartupMemory   = $StartupMemory
            MinimumMemory   = $MinimumMemory
            MaximumMemory   = $MaximumMemory
            ProcessorCount  = $ProcessorCount
            MACAddress      = ""
            Notes           = ""
            SecureBoot      = $False
            EnableGuestService = $True
            RestartIfNeeded = $true
            WaitForIP       = $WaitForIP 
            DependsOn       = '[xVhd]DiffVhd'
        }
    }
}

########## Dev environment servers ########## 
# StartupMemory/ MinimumMemory = 2 GB
# MaximumMemory = 4GB
TestAppVMsToHyperV -NodeName "localhost" -VMName "DevFE01" -SwitchName "DevFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "DevFE02" -SwitchName "DevFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2

TestAppVMsToHyperV -NodeName "localhost" -VMName "DevBL01" -SwitchName "DevBL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "DevBL02" -SwitchName "DevBL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2


########## Q&A environment servers ##########
TestAppVMsToHyperV -NodeName "localhost" -VMName "QAFE01" -SwitchName "QAFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "QAFE02" -SwitchName "QAFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2

TestAppVMsToHyperV -NodeName "localhost" -VMName "QABL01" -SwitchName "QABL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "QABL02" -SwitchName "QABL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2

########## Production environment servers ##########
TestAppVMsToHyperV -NodeName "localhost" -VMName "ProdFE01" -SwitchName "ProdFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "ProdFE02" -SwitchName "ProdFE" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2

TestAppVMsToHyperV -NodeName "localhost" -VMName "ProdBL01" -SwitchName "ProdBL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2
TestAppVMsToHyperV -NodeName "localhost" -VMName "ProdBL02" -SwitchName "ProdBL" -State "Running" -Path "D:\ExampleAppVMs" -StartupMemory 2147483648 -MinimumMemory 2147483648 -MaximumMemory 4294967296 -ProcessorCount 2

That code creates these servers based on my Windows Server 2016 Nano template which I have created using this command:
New-NanoServerImage -Edition Standard -DeploymentType Guest -MediaPath E:\ -BasePath .\Base -TargetPath .\Nano\NanoIIStemplate.vhd -ComputerName NanoTemp -Packages Microsoft-NanoServer-DSC-Package,Microsoft-NanoServer-IIS-Package
More information about how to create Nano server templates you can find from here.


I have been working with automation for years and biggest issue what I have seen is that there is always someone who will go can do some unexpected configuration/upgrade/etc manually and that will break the automation.

Fourth lessons learned is that: Use Core or Nano servers instead of full GUI version of servers on your code defined environments. That will keep persons who do not know what they are doing out of from your servers ;)

When you have that environment define code ready you need apply it to virtualization platform. Here is simple example how to apply it locally on Hyper-V server:
.\TestAppEnvironmentsHyperV.ps1
Start-DscConfiguration -Path .\TestAppVMsToHyperV
That can be of course done also remotelly and on production you probably want use DSC pull server instead of pushing these configurations directly to servers.


This was second part of this blog post series. I will try post next one near future. Thanks for reading :)

No comments:

Post a Comment