Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
PowerShell DSC実践活用(1)

PowerShell DSC実践活用(1)

PowerShell DSCで導入された新しい構文キーワード

2014年6月6日

Windowsインフラ環境の構築を自動化できる「PowerShell DSC」とは? その使い方を紹介。DSCの構文をコードで示しながら、基本的な実践手順を説明する。

株式会社グラニ 吉崎 生
  • このエントリーをはてなブックマークに追加

PowerShell DSCとは

 DSC(Desired State Configurationの略)は、Windows PowerShell 4.0をコアとする「Windows Management Framework」のバージョン4.0(WMF 4.0)から導入された、マイクロソフトが提供するWindowsインフラ環境の自動構築プラットフォームだ。

 DSCはPowerShellでの専用構文を持っているが、それも含めて「PowerShell ISE」という統合スクリプティング環境(Integrated Scripting Environment)上のIntelliSenseでサポートされている。また、Windows Server 2012 R2、Windows 8.1からは標準で利用できるのも魅力の1つだ。

 同様のインフラ環境の自動構築ツールとしては、ChefPuppetが有名だ。そのChefも現在、WindowsにおいてDSCをサポートするようになった。

 Chefとの違いとして、

  • DMTF標準に沿ってManaged Object Format(以下、MOF)やWS-Managementで構成されている
  • Pullだけでなく、Pushもサポートしている
  • Pushでは、サーバーとノード間の通信にはWindows版WS-Management実装のWinRMを利用する
  • Pullでは、サーバーとノード間の通信にはHTTP(あるいはHTTPS)を利用する
  • PowerShellで記述ができる

といった点が挙げられる。国外ではStack Exchangeが利用しており、現在、Windowsにおける有力な手段の1つといえる。筆者の所属する株式会社グラニでも、AWS上のWindowsで動作させているサーバーのプロビジョニングやインフラ環境自体のバージョン管理に利用している。

 DSCはPowerShellでコードを書くことができ、Windows環境で動作する。さらに2014年5月3日に米国で開催されたMicrosoft TedEdで、Linuxで動作するDSCも発表された。ChefもWindowsにおける構成にDSCを使えるように対応を発表しており、PowerShell以外の言語でもDSCの機能を利用することが可能だ。

 DSCは昨年2013年10月に登場したばかりで、現在(2014年5月11日)はv1といえる状態だが、4月、5月とPreview版がリリースされているWMF 5.0ではパフォーマンスや記述に関して改善されている。

 なお、PowerShell DSCの基礎や導入方法について詳しくは、「@IT/Windows Server Insider: PowerShell DSCで始めるWindowsインフラストラクチャ自動化の基本」を併せて参照されたい。本連載では、@ITの記事内容からさらに一歩進めて、より実践的な活用方法について説明する。まず本連載の第1回である今回は、DSCでWindowsサーバーを構築する流れを、実際にConfigurationを記述しながら説明する。

MOFファイルについて

 DSCがサーバー構成に実際に使用するファイルは、.MOFファイルだ。リスト1を見ると分かるように、MOFファイル自体はテキストエディターでも書けるが、人間が読み書きするには、分かりにくい書式だ。

MOF
/*
@TargetNode='localhost'
@GeneratedBy=Administrator
@GenerationDate=05/20/2014 13:04:45
@GenerationHost=DSCSERVER
*/
 
instance of MSFT_RoleResource as $MSFT_RoleResource1ref
{
  ResourceID = "[WindowsFeature]IIS";
  Ensure = "Present";
  SourceInfo = "C:\\DSC\\Sample\\WebSiteConfigInstall.ps1::11::9::WindowsFeature";
  Name = "Web-Server";
  ModuleName = "PSDesiredStateConfiguration";
  ModuleVersion = "1.0";
 
};
 
instance of OMI_ConfigurationDocument
{
  Version="1.0.0";
  Author="Administrator";
  GenerationDate="05/20/2014 13:04:45";
  GenerationHost="DSCSERVER";
};
リスト1 MOFファイルの例

 そこでPowerShell V4.0では、DSCで使う.MOFファイルを生成するために専用のキーワード「Configuration」が用意され、「宣言的構文」と「IntelliSense」、「Configurationスキーマの構文チェック」がサポートされた。

DSCによる構成実施の基本的な流れ

 比較的構成がシンプルなPushで、DSCで構成を適用する流れを端的に示す。

  • Configurationを書く
  • Configurationを実行してMOFファイルを生成する
  • 生成されたMOFファイルをStart-DSCConfigurationコマンドレットで対象ノードに転送し、構成を実施させる

 それでは、さっそくConfigurationの書き方から、DSCの実行まで見てみよう。

PowerShell DSCの基本的な使い方

DSCのConfiguration構文

従来のPowerShellスクリプトの場合

 Windowsの管理に携わってきた方は、PowerShellスクリプトでのサーバー構成に慣れているだろう。従来のPowerShellでは、サーバーを「あるべき状態(Desired State)に構成(Configuration)」にするために、GUIでサーバーを構成する手順をPowerShellコードに落とし込んで記述していた。例えば、「Windowsの機能」の「IIS」と「ASP.NET」をインストールする場合の手順は、

  • 現在のサーバーにIIS機能が入っているかを確認
  • IIS機能がなければ追加する、あればスキップ
  • ASP.NET MVCの機能が入っているかを確認
  • ASP.NET MVCの機能がなければ追加する、あればスキップ

といった具合である。前提によっては、分岐が増えたり操作手順が変わったりするだろう。手順が分岐するに従って、PowerShellスクリプトもネストが深く、複雑化して読みにくくなっていく。例に挙げた手順を従来のPowerShell構文で書くと以下のようになる。

PowerShell
Import-Module ServerManager
 
# Web Server(IIS)の機能の状態を確認し、インストール
If (-not (Get-WindowsFeature "Web-Server").Installed)
{
  try
  {
    Add-WindowsFeature Web-Server -IncludeManagementTools -ErrorAction Stop
  }
  catch [Exception]
  {
    Write-Error $_
  }
}
 
# ASP.NET 4.5の機能の状態を確認し、インストール
If (-not (Get-WindowsFeature "Web-Asp-Net45").Installed)
{
  try
  {
    Add-WindowsFeature Web-Asp-Net45 -IncludeAllSubFeature -IncludeManagementTools -ErrorAction Stop
  }
  catch [Exception]
  {
    Write-Error $_
  }
}
リスト2 「Windowsの機能」の「IIS」と「ASP.NET」をインストールする場合のPowerShellスクリプト
新しいDSC構文を用いたPowerShellスクリプトの場合

 PowerShell V4.0では、ConfigurationというDSC専用の構文を用いることで「あるべき状態(Desired State)」を宣言的に記述できるようになり、これまでの冗長になりがちだった「あるべき状態を構成するための手順」を記述することから解放された。先ほどの例を「あるべき状態」を宣言すると、こうなる。

  • IIS機能が入っていてほしい
  • ASP.NETの機能が入っていてほしい

 この例だけでも、先ほどのインストールまでの手順を連ねるより、シンプルで分かりやすくなっている。実際のコードも同様にシンプルだ。

PowerShell DSC
Configuration WebSiteConfigInstall
{
  Node localhost
  {
    WindowsFeature IIS
    {
      Ensure               = "Present"
      Name                 = "Web-Server"
    }
 
    WindowsFeature IISMgmt
    {
      Ensure               = "Present"
      Name                 = " Web-Mgmt-Tools"
    }
 
    WindowsFeature ASP
    {
      Ensure               = "Present"
      Name                 = "Web-Asp-Net45"
    }
  }
}
 
WebSiteConfigInstall -OutputPath .
Start-DscConfiguration .\WebSiteConfigInstall -Wait -Verbose
リスト3 「Windowsの機能」の「IIS」と「ASP.NET」をインストールする場合のPowerShell DSCスクリプト

このコードの意味については後述の説明を参考にしてほしい。ここでは、このようにコードがシンプルになるとだけ確認してほしい。

DSCのConfigurationの構文

 DSCのConfigurationを実際に書くに当たって、その構文を説明する。

 さっそく、PowerShell ISEを起動してConfigurationを書いていこう。PowerShell ISE(powerShell_ise.exe)は、Windows PowerShell(powershell.exe)を管理者モードで起動した状態で「ise」と入力することで起動できる(図1)*1

図1 PowerShellで「ise」と入力するとPowerShell ISEが起動する
図1 PowerShellで「ise」と入力するとPowerShell ISEが起動する

 図2にConfiguration構文のブロック構造を示した。それぞれのブロックについて見ていく。

図2 Configuration構文の「1Configuration Block」と「2Node Block」と「3Resource Block」の構造

 まずは、1の「Configuration Block」だ。

1Configuration Block ― 独自の構成(Configuration)内容を定義するブロック

 「Function」キーワードを使って独自の関数を作成できるように、DSCでは「Configuration」キーワードを使うことで同様に独自のコンフィギュレーション(=構成。以下、単に「Configuration」と表記)を作成できる。Configuration Blockでは、「Configuration」キーワードに続けて重複しない任意の名前(ここでは「WebSiteConfigInstall」)を付けてConfigurationを識別する。Configuration内部のブロックは「{ }」でその範囲が決まる。

PowerShell DSC
Configuration WebSiteConfigInstall 
{
} 
リスト4 Configuration Blockのコード例

 続いて、2の「Node Block」だ。

2Node Block ― コンピューターノード(Node)を定義するブロック

 Node Blockは、Configuration Blockの中に1つ以上設けることができる。「Node」キーワードの後ろに指定したコンピューター(以降、「ノード」と呼ぶ)がMOFファイルの出力対象であり、「あるべき状態(Desired State)」を行う対象だ。例えば「localhost」(=自分自身)を対象にするなら、次のようになる。

PowerShell DSC
Configuration WebSiteConfigInstall 
{
  Node "localhost" 
  {
  }
}
リスト5 Node Blockのコード例

 複数のノードを、同じあるべき状態にしたいときは、Nodeキーワードの後ろにかっこでくくった中に対象ノードをカンマ「,」区切りで書く(リスト6)。

PowerShell DSC
Configuration WebSiteConfigInstall 
{
  Node ("localhost", "10.0.3.169") 
  {
  }
}
リスト6 複数のノードを対象にしたNode Block(カンマ区切り)のコード例

 あるいは、ノードによってあるべき状態が異なるなら、Node Blockを複数並べることもできる(リスト7)。

PowerShell DSC
Configuration WebSiteConfigInstall 
{
  Node "localhost"
  {
  }
 
  Node "10.0.3.169"
  {
  }
}
リスト7 Node Blockを複数記述したコード例

 最後が、3の「Resource Block」だ。

3Resource Block ― 処理内容を記述したリソース(Resource)を定義するブロック

 Resource Blockは、Node Blockの中に1つ以上設けることができる。「リソース名」(標準で提供されているものなら「File」や「Archive」など、12種類のリソースがある)の後ろに任意の識別名を付けて他のリソースと区別する。

 このリソース(Resource)は、DSCで扱う対象の処理内容を記述したもので、Fileを扱うなら「Fileリソース」、Webサイトやアプリケーションプール(Application Pool)の作成なら「WebAdministrationsリソース」といったように設定する対象ごとに必要なリソース名を呼び出すこととなる。例えば「Windowsの機能」を扱うなら、リソース名は「WindowsFeature」だ。今回はIISをインストールしようと思うので、識別名は「IIS」とした(リスト8)。

PowerShell DSC
Configuration WebSiteConfigInstall 
{
  Node "localhost" 
  {
    WindowsFeature IIS 
    {
    }
  }
}
リスト8 Resource Blockのコード例

 Resource Blockの中には、そのリソースごとに設定されたName List(=キー名の一覧)のいずれかに当てはまるように「Key=Value」(キー名と、その値)を記述する。

 なお、リソースがどんなName Listを持っているかは、PowerShell ISEでリソース名の部分で(図3の例では「WindowsFeature」に入力カーソルを置いた状態で)CtrlSpaceキーを押すことにより、IntelliSenseに表示される。

図3 「WindowsFeature」で、キーボードの[Ctrl]+[Space]キーを押してIntelliSenseを表示した様子

WindowsFeature リソースが、どんなName Listを持っているかツールチップに表示されている。

 「WindowsFeature」リソースでは、「Windowsの機能」の名前をNameキーに指定する(このキーに使える値は、Get-WindowsFeatureコマンドレットで確認できる)。機能が存在してほしい場合は、Ensureキーの値を“Present”とする(機能が存在しないでほしい、つまりアンインストールする場合は、“Absent”だ)。今回はIISなので、Nameは「Web-Server」となる。

PowerShell DSC
Configuration WebSiteConfigInstall
{
  Node "localhost"
  {
    WindowsFeature IIS
    {
      Name   = "Web-Server"
      Ensure = "Present"
    }
  }
}
リスト9 「WindowsFeature」リソースのコード例

 Configurationを再利用しようと思ったとき、ハードコードでノードを羅列するよりも、1つのテンプレートとなるノードを作り、そこにノード名だけを外部からパラメーターとして渡したくなることもあるだろう。DSCもFunction同様に、「Param()」を利用して、実行時にパラメーターを外部から渡すことができる。例えばノードの名前を実行時に渡したいなら、次のように書ける。

PowerShell DSC
Configuration WebSiteConfigInstall
{
  param
  (
    [string[]]
    $Node
  )
 
  Node $Node
  {
    WindowsFeature IIS
    {
      Name   = "Web-Server"
      Ensure = "Present"
    }
  }
}
リスト10 実行時にノード名を渡す場合のNode Blockのコード例

 Param()を使うことでConfigurationの実行時に、Param()に指定した$Nodeが、-Nodeというパラメーターとして表示されて、ノード名の部分(=$Node)に値を渡すことができる(図4)。

図4 実行時にノード名を渡すコードのパラメーターのIntelliSense表示例

作成した「WebSiteConfigurationInstall」Configurationの実行文を記述しているところ。「-」を入力すると、パラメーターとして、param()で指定した$Nodeの「$」を除いた名称(つまり「Node」)がIntelliSenseに表示される。 なお、Configurationの実行文は、「WebSiteConfigurationInstall -Node <任意のノード名>」のように記述すればよい。

 シンプルなConfigurationの構文は以上だ。続いて、作成したConfigurationを実行してみよう。

DSCのConfigurationを実行する

 Configurationを実行することで、Nodeブロックに指定したノードごとに.MOFファイルが生成される。

 実行するには、Configurationを書いたときに付けた名前(ここでは「WebSiteConfigInstall」)を入力し、.MOFファイルの生成先パスを-OutputPathパラメーターに指定する。例えば以下の例では、現在のパス直下にWebSiteConfigInstallフォルダーを生成し、その中にノード分(今回はlocalhostのみ)の.MOFファイルを生成している。

PowerShell DSC
Configuration WebSiteConfigInstall
{
  param
  (
    [string[]]
    $Node
  )
 
  Node $Node
  {
    WindowsFeature IIS
    {
      Name   = "Web-Server"
      Ensure = "Present"
    }
  }
}
 
WebSiteConfigInstall -OutputPath . -Node localhost
リスト11 Configurationを実行するDSCコード例

各パラメーターを使って、.MOFファイルの生成先を「.」(=現在のディレクトリ内)に、ノード名を「localhost」に指定している。

図5 上記のDSCコードの実行結果

「C:\DSC\Sample\WebSiteConfigInstall」パスで、WebSiteConfigInstallというConfigurationを実行したことで、フォルダーとMOFファイルが生成された様子。

Configurationを転送し、構成を実施する

 MOFファイルができたら、次は対象ノードへMOFファイルを転送して構成を実行する。

【コラム】Configurationをノードに転送するための事前設定について

 Configurationをノードに転送する際は、対象となるノードとDSCサーバーの両方がWSMan(PowerShellでは「PSRemoting」と呼ぶ)で接続可能で、ExecutionPolicy(PowerShellのスクリプト実行権限)がRestrictedでない必要がある。一度設定すれば、変更がない限り再設定は不要だが、もし初めてPowerShellを実行するという方は、DSC実行するサーバーとノードの両方で次のコード3行を「管理者として起動したPowerShell」で実行してほしい(詳細は@ITの記事を参照されたい)。

PowerShell DSC
Enable-PSRemoting -Force
Set-Item wsman:\localhost\Client\TrustedHosts -Value * -Force
Set-ExecutionPolicy RemoteSigned
リスト12 Configuration転送のための事前設定を行うコマンド例

 今回は、設定を実行するDSCサーバーが、自分自身(localhost)を対象にしているので、DSCサーバーのみで実行した。

図6 PowerShell Remotingを有効に設定し、Execution PolicyをRemoteSignedにしている様子

RemoteSignedなら、手元で書いたスクリプトの実行が許可される。

 準備ができたら、MOFファイルをノードに転送して実行しよう。このときに使うのが、Start-DscConfigurationコマンドレットだ。

PowerShell DSC
Configuration WebSiteConfigInstall
{
  param
  (
    [string[]]
    $Node
  )
 
  Node $Node
  {
    WindowsFeature IIS
    {
      Name   = "Web-Server"
      Ensure = "Present"
    }
  }
}
 
WebSiteConfigInstall -OutputPath . -Node localhost
Start-DscConfiguration -Path .\WebSiteConfigInstall -Wait -Verbose
リスト13 MOFファイルをノードに転送するDSCコード例

 Start-DSCConfigurationコマンドレットは、MOFファイルをノードに転送して実行し、ノードの状態を収束させる。つまり実行トリガーだ。

 -Pathパラメーターに、Configuration実行時の-OutPathパラメーターに指定したMOFファイルの生成先ディレクトリ+Configuration名(つまり上記のコード例では「.」+「WebSiteConfigInstall」で、「.\WebSiteConfigInstall」)を指定する。これにより、Configurationで生成された.MOFファイルが、WinRMを使って作ったCIM(Common Information Model)セッションで対象ノードに転送され、ノードの構成がMOFファイルに記述された「あるべき状態」に収束する。

 -Waitパラメーターは、Start-Configurationコマンドレットの実行が完了するまで待機して次の入力をさせない。今回はホスト画面で確認するために使っている。

 -Verboseパラメーターは実行経過、結果の詳細メッセージを表示するために利用する。

 PowerShell ISEで、F5キーを押してConfigurationを実行することでlocalhostがあるべき状態に構成される(図7)。

図7 記述したConfigurationを、Start-DscConfigurationでlocalhostに構成を適用した実行結果

 IISが宣言通りにインストールされたことが、GUIのサーバーマネージャーでも確認できる(図8)。

図8 サーバーマネージャーにIISの項目でローカルホストが表示された

冪等性(べき等性)

 DSCのリソースは、ChefやPuppetがそうであるように冪等性を備えている。冪等性は、ある操作を1回行っても複数回実行しても同じ結果になるという概念だ。リソースの作り方によっては冪等性が担保されないのだが、多くにおいて冪等性を考慮して作成されている。

 今回のConfigurationで利用したWindowsFeatureリソースも冪等性を考慮しており、再度実行してもすでにIISがインストールされているため、テストまでは実行するが設定はスキップされ(図9)、動作に影響がないようになっている。

図9 再度DSCを実行しても、すでに適用済みであることがテストされ、設定はスキップされる

 以上、DSCでのConfigurationについて詳細を説明した。次回は、DSCで利用するリソースを自分で作成する流れを説明する。

PowerShell DSC実践活用(1)
1. 【現在、表示中】≫ PowerShell DSCで導入された新しい構文キーワード

Windowsインフラ環境の構築を自動化できる「PowerShell DSC」とは? その使い方を紹介。DSCの構文をコードで示しながら、基本的な実践手順を説明する。

PowerShell DSC実践活用(1)
2. 本番で使えるPowerShell DSCリソース作成入門

Windows Serverの構成管理を自動化できるツール「PowerShell DSC」を使いこなそう。PowerShellでDSCのリソースを自作する方法とは?

PowerShell DSC実践活用(1)
3. PowerShell v5の新機能と、実戦で使ってほしい機能

Windows 10に標準搭載され、Windows 7/8.1/Server 2008/2012向けにもリリースされたWMF 5.0に同梱されるPowerShell 5.0の新機能と、PowerShellユーザーに特にお勧めの機能を紹介する。

サイトからのお知らせ

Twitterでつぶやこう!