Complicated deployments

The time saved from the automated deployment of both DSC resources and DSC configuration scripts, along with configuration status reporting, was of enough value to allow you to finally start working on those things you would do if only you had the time. You're leaving on time nowadays and coworkers are lining up to take advantage of being added to your list of managed servers.

The target node count has increased significantly. Since you started this project, the company has grown and the Apollo application is handling more requests than ever. The application team decides that the available time for new features is being compromised by having to deploy the company website code named Aurora by themselves. After talking with your boss, both your teams decide to hand off deploying Aurora to you. A couple of knowledge transfer sessions happen later and you have a list of software requirements and configuration steps for Aurora.

Adding the software requirements to your DSC configuration is a piece of cake. All the IIS features required to build a web server on Windows 2012 R2 are already built-in; they just need to be enabled. For security and access restriction reasons, the company has decided that any web server software cannot just be installed on any server that has the application database on it, so you add a new Node statement to your DSC configuration script and a new role to your ConfigurationData hash for web servers.

Getting the website to the target nodes is slightly more difficult. The application team doesn't use MSIs to install the Aurora website and, instead, uses ZIP files that they used xcopy with to transfer to the web server as well as a simple bat script to extract them and overwrite the existing files. They know this is a fragile and error-prone approach and are working to get a better installer made for the site, but it's not high on the priority list. Realizing you can't wait for that to happen, you decide to move forward with what you have right now. After attempting to use the File DSC resource to download the ZIP file, you realize it can't handle remote files over HTTP.

Fortunately, there is a xRemoteFile DSC resource that does exactly what you need. You chain xRemoteFile to an xArchive DSC resource to download and extract the file to a temporary location. Now, you can use the File DSC resource to check whether the destination contents match your extracted folder. All that is left is creating a web application pool and site:

    Configuration PantheonDeployment
    {
      <#
      Import-DscResource -Module..
      #>
    
      Node ($AllNodes).NodeName{ <#..#> }
    
      Node ($AllNodes.Where({$_.Roles -contains 'appserver'})).NodeName{ <#..#> }
    
      Node ($AllNodes.Where({$_.Roles -contains 'WebServer'})).NodeName
      {
        WindowsFeature IIS
        {
          Ensure = 'Present'
          Name   = 'Web-Server'
        }
    
        WindowsFeature IISConsole
        {
          Ensure    = 'Present'
          Name      = 'Web-Mgmt-Console'
          DependsOn = '[WindowsFeature]IIS'
        }
    
        WindowsFeature IISScriptingTools
        {
          Ensure    = 'Present'
          Name      = 'Web-Scripting-Tools'
          DependsOn = '[WindowsFeature]IIS'
        }
    
        WindowsFeature AspNet
        {
          Ensure    = 'Present'
          Name      = 'Web-Asp-Net45'
          DependsOn = @('[WindowsFeature]IIS')
        }
    
        xWebsite DefaultSite
        {
          Ensure       = 'Present'
          Name         = 'Default Web Site'
          State        = 'Stopped'
          PhysicalPath = 'C:inetpubwwwroot'
          DependsOn    = @('[WindowsFeature]IIS','[WindowsFeature]AspNet')
        }
    
        xRemoteFile DownloadAuroraZip
        {
          Uri             = $Node.Aurora.Sourcepath
          DestinationPath = (Join-Path 'C:WindowsTemp' (Split-Path -Path $Node.Aurora.Sourcepath -Leaf))
          DependsOn       = @('[xWebsite]DefaultSite')
        }
    
        xArchive AuroraZip
        {
          Path            = (Join-Path 'C:WindowsTemp' (Split-Path -Path $Node.Aurora.Sourcepath -Leaf))
          Destination     = 'C:WindowsTemp'
          DestinationType = 'Directory'
          MatchSource     = $true
          DependsOn       = @('[xRemoteFile]DownloadAuroraZip')
        }
    
        File AuroraContent
        {
          Ensure          = 'Present'
          Type            = 'Directory'
          SourcePath      = Join-Path 'C:WindowsTemp' ([IO.Path]::GetFileNameWithoutExtension($Node.Aurora.Sourcepath))
          DestinationPath = $Node.Aurora.DestinationPath
          Recurse         = $true
          DependsOn       = '[xArchive]AuroraZip'
        }
    
        xWebAppPool AuroraWebAppPool
        {
          Ensure = "Present"
          State  = "Started"
          Name   = $Node.WebAppPoolName
        }
    
        xWebsite AuroraWebSite
        {
          Ensure       = 'Present'
          State        = 'Started'
          Name         = $Node.Aurora.WebsiteName
          PhysicalPath = $Node.Aurora.DestinationPath
          DependsOn    = '[File]AuroraContent'
        }
    
        xWebApplication AuroraWebApplication
        {
          Name         = $Node.Aurora.WebApplicationName
          Website      = $Node.Aurora.WebSiteName
          WebAppPool   = $Node.Aurora.WebAppPoolName
          PhysicalPath = $Node.Aurora.DestinationPath
          Ensure       = 'Present'
          DependsOn    = @('[xWebSite]AuroraWebSite')
        }
      }
    }
    $data   = Join-Path $PSScriptRoot 'data_example_04.psd1'
    $output = Join-Path $PSScriptRoot 'PantheonDeployment'
    PantheonDeployment -ConfigurationData $data -OutputPath $output  

With all this new configuration data to track, it's no wonder you need to update your ConfigurationData hash:

    @{
      AllNodes = @(
        @{
          NodeName        = 'app01'
          ConfigurationId = 'ab2c2cb2-67a3-444c-bc55-cc2ee70e3d0c'
          Roles           = @('appserver')
        },
        @{
          NodeName        = 'app02'
          ConfigurationId = '8e8f44e6-aaac-4060-b072-c9ae780ee5f7'
          Roles           = @('appserver')
        },
        @{
          NodeName        = 'web01'
          ConfigurationId = 'b808fb65-5b16-4f83-84c6-aa398a6abdd5'
          Roles           = @('webserver')
        },
        @{
          NodeName             = '*'
          RefreshMode          = 'Pull'
          ConfigurationMode    = 'ApplyAndAutoCorrect'
          PSDSCCPullServer     = 'https://dsc01:8080/PSDSCPullServer.svc'
          AllowModuleOverwrite = $true
          RebootNodeIfNeeded   = $true
          Apollo   = @{
            Name               = 'Apollo'
            ProductId          = '{e70c4829-91dc-4f0e-a404-4eba81f6feb9}'
            SourcePath         = 'http://build.pantheon.net/apollo/packages/releases/apollo.1.1.0.msi'
            Arguments          = ''
            ConfigFilePath     = "$env:ProgramFilesApolloconfigapp.config"
            ConfigFileContents = "importantsetting=`$true"
          }
          Aurora = @{
            SourcePath         = 'http://build.pantheon.net/aurora/releases/aurora.zip'
            DestinationPath    = "$env:SystemDriveinetpubwwwaurora"
            WebApplicationName = 'Aurora'
            WebSiteName        = 'Aurora'
            WebAppPoolName     = 'AuroraAppPool'
          }
        }
      )
    }  

You already have a hash for Apollo, so all you have to do is add a new hash for Aurora with the appropriate details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset