Desired State Configuration
トピック
Desired State Configuration とは
Desired State Configuration (DSC) は、PowerShell に組み込まれたツールで、コードによって Windows ホストのセットアップを定義するために使用することができます。DSC の全体的な目的は Ansible と同じですが、実行方法が異なるだけです。Ansible 2.4 からは、win_dsc
モジュールが追加され、Windows ホストとのやりとりの際に、既存の DSC リソースを活用することができます。
DSC の詳細は、DSC Overview を参照してください。
ホスト要件
win_dsc
モジュールを使用するには、Windows ホストに PowerShell v5.0 以降がインストールされている必要があります。サポート対象のホストはすべて、PowerShell v5.0 にアップグレードすることができます。
PowerShell の要件を満たしていれば、DSC を使用することは、win_dsc
モジュールでタスクを作成するのと同じぐらい簡単です。
DSC を使用する理由
DSC と Ansible モジュールには、リソースの状態を定義して保証するという共通の目的があります。このため、DSC ファイルリソース や Ansible``win_file`` のようなリソースを使用して、同じ結果を得ることができます。どちらを使用するかは、シナリオによって異なります。
DSC リソースで Ansible モジュールを使用する理由:
ホストが PowerShell v5.0 をサポートしていない、または簡単にアップグレードできない
DSC リソースは、Ansible モジュールに存在する機能を提供しない。たとえば、win_regedit は
REG_NONE
のプロパティータイプを管理できますが、DSC のRegistry
リソースでは管理できません。DSC のリソースはチェックモードのサポートが限られているが、Ansible モジュールの中にはより優れたチェック機能を持つものがある
DSC リソースでは差分モードがサポートされないが、一部の Ansible モジュールではサポートされる
カスタムリソースでは、事前にホスト上で追加のインストール手順を実行する必要があるが、Ansible モジュールは Ansible に組み込まれている
Ansible モジュールが機能する DSC リソースにバグがある
Ansible モジュールで DSC リソースを使用する理由:
Ansible モジュールは、DSC リソースに存在する機能をサポートしていない
利用可能な Ansible モジュールがない
既存の Ansible モジュールにバグがある
つまるところ、タスクが DSC で実行されるか Ansible モジュールで実行されるかは重要ではありません。重要なのは、タスクが正しく実行され、Playbook が読めることです。Ansible よりも DSC の方を使用した経験があり、それで必要なことができるのであれば、そのタスクには DSC を使用すると良いでしょう。
DSC の使用方法
win_dsc
モジュールは、管理しているリソースに応じて変化するように、フリーフォームのオプションを取り入れています。組み込まれているリソースのリストは、resources を参照してください。
Registry リソースを例にとると、これは Microsoft が文書化したDSCの定義です。
Registry [string] #ResourceName
{
Key = [string]
ValueName = [string]
[ Ensure = [string] { Enable | Disable } ]
[ Force = [bool] ]
[ Hex = [bool] ]
[ DependsOn = [string[]] ]
[ ValueData = [string[]] ]
[ ValueType = [string] { Binary | Dword | ExpandString | MultiString | Qword | String } ]
}
タスクを定義する際には、使用する DSC リソースを resource_name
に設定する必要があります。この場合、resource_name
は Registry
に設定する必要があります。module_version
はインストールされている DSC リソースの特定のバージョンを参照することができますが、空白にするとデフォルトで最新バージョンになります。その他のオプションは Key
や ValueName
のようにリソースを定義するためのパラメーターになります。タスクのオプションは大文字小文字を区別しませんが、DSC リソースのオプションと Ansible の``win_dsc`` のオプションを区別しやすくするために、大文字小文字をそのままにしておくことが推奨されます。
上記の DSC レジストリーリソースの Ansible タスクバージョンは、以下のようになります。
- name: Use win_dsc module with the Registry DSC resource
win_dsc:
resource_name: Registry
Ensure: Present
Key: HKEY_LOCAL_MACHINE\SOFTWARE\ExampleKey
ValueName: TestValue
ValueData: TestData
Ansible 2.8 より、win_dsc
モジュールは、Ansible からの入力オプションを DSC 定義で自動的に検証します。つまり、オプション名が間違っていたり、必須オプションが設定されていなかったり、値が有効な選択肢でなかったりすると、Ansible は失敗します。Ansible を冗長レベル 3 以上 (-vvv
) で実行した場合、戻り値には、指定された resource_name
に基づいて可能な呼び出しオプションが含まれます。以下は、上記の Registry
タスクの呼び出し出力の例です。
changed: [2016] => {
"changed": true,
"invocation": {
"module_args": {
"DependsOn": null,
"Ensure": "Present",
"Force": null,
"Hex": null,
"Key": "HKEY_LOCAL_MACHINE\\SOFTWARE\\ExampleKey",
"PsDscRunAsCredential_password": null,
"PsDscRunAsCredential_username": null,
"ValueData": [
"TestData"
],
"ValueName": "TestValue",
"ValueType": null,
"module_version": "latest",
"resource_name": "Registry"
}
},
"module_version": "1.1",
"reboot_required": false,
"verbose_set": [
"Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceSet,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
"An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
"[SERVER2016]: LCM: [ Start Set ] [[Registry]DirectResourceAccess]",
"[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Create registry key 'HKLM:\\SOFTWARE\\ExampleKey'",
"[SERVER2016]: [[Registry]DirectResourceAccess] (SET) Set registry key value 'HKLM:\\SOFTWARE\\ExampleKey\\TestValue' to 'TestData' of type 'String'",
"[SERVER2016]: LCM: [ End Set ] [[Registry]DirectResourceAccess] in 0.1930 seconds.",
"[SERVER2016]: LCM: [ End Set ] in 0.2720 seconds.",
"Operation 'Invoke CimMethod' complete.",
"Time taken for configuration job to complete is 0.402 seconds"
],
"verbose_test": [
"Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = ResourceTest,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.",
"An LCM method call arrived from computer SERVER2016 with user sid S-1-5-21-3088887838-4058132883-1884671576-1105.",
"[SERVER2016]: LCM: [ Start Test ] [[Registry]DirectResourceAccess]",
"[SERVER2016]: [[Registry]DirectResourceAccess] Registry key 'HKLM:\\SOFTWARE\\ExampleKey' does not exist",
"[SERVER2016]: LCM: [ End Test ] [[Registry]DirectResourceAccess] False in 0.2510 seconds.",
"[SERVER2016]: LCM: [ End Set ] in 0.3310 seconds.",
"Operation 'Invoke CimMethod' complete.",
"Time taken for configuration job to complete is 0.475 seconds"
]
}
invocation.module_args
キーは、設定された実際の値と、設定されなかった他の可能な値を表示します。DSC プロパティーのデフォルト値は表示されず、Ansible タスクで設定された値のみが表示されます。*_password
オプションは、セキュリティー上の理由から出力ではマスクされます。他に機密性の高いモジュールオプションがある場合は、タスクに no_log: True
を設定して、すべてのタスク出力がログに記録されないようにしてください。
プロパティータイプ
各 DSC リソースプロパティーには、それに関連付けられたタイプがあります。Ansible は、実行時に定義されたオプションを正しいタイプに変換しようとします。[string]
や [bool]
のような単純なタイプでは、これは単純な操作ですが、[PSCredential]
や配列 ([string[]]
など) のような複雑なタイプでは、特定のルールが必要です。
PSCredential
[PSCredential]
オブジェクトは認証情報を安全な方法で保存するために使用されますが、Ansible にはこれを JSON でシリアル化する方法がありません。DSC PSCredential プロパティーを設定するには、そのパラメーターの定義に、ユーザ名とパスワードをそれぞれ _username
と _password
をサフィックスにした 2 つのエントリーを追加する必要があります。たとえば、以下のようになります。
PsDscRunAsCredential_username: '{{ ansible_user }}'
PsDscRunAsCredential_password: '{{ ansible_password }}'
SourceCredential_username: AdminUser
SourceCredential_password: PasswordForAdminUser
注釈
2.8 より古いバージョンの Ansible では、Ansible のタスク定義に no_log: true
を設定して、使用する認証情報がログファイルまたはコンソールの出力に保存されないようにする必要があります。
[PSCredential]
は、DSC リソースの MOF 定義において``EmbeddedInstance("MSFT_Credential")`` と共に定義されます。
CimInstance タイプ
[CimInstance]
オブジェクトは、DSC がそのリソースで定義されたカスタムクラスに基づいてディクショナリーオブジェクトを格納するために使用されます。[CimInstance]
を取り込む値を YAML で定義することは、YAML でディクショナリーを定義することと同じです。たとえば、Ansible で``[CimInstance]`` の値を定義する場合は、以下のようになります。
# [CimInstance]AuthenticationInfo == MSFT_xWebAuthenticationInformation
AuthenticationInfo:
Anonymous: false
Basic: true
Digest: false
Windows: true
上記の例では、CIM インスタンスは、クラス MSFT_xWebAuthenticationInformation の表現です。このクラスは、Anonymous
、Basic
、Digest
、Windows
という 4 つのブール変数を受け入れます。[CimInstance]
で使用するキーは、それが表現するクラスによって異なります。使用できるキーと各キーの値のタイプについては、リソースのドキュメントを参照してください。クラスの定義は、通常、<resource name>.schema.mof
にあります。
HashTable タイプ
[HashTable]
オブジェクトもディクショナリーですが、定義できる/しなければならない厳密な鍵のセットがありません。[CimInstance]
のように、YAML で通常のディクショナリー値のように定義します。[HashTable]]
は、DSC リソースの MOF 定義において EmbeddedInstance("MSFT_KeyValuePair")
と共に定義されます。
配列
[string[]]
や [UInt32[]]
のような単純なタイプの配列は、リストまたはコンマ区切りの文字列として定義され、それらがタイプにキャストされます。リストを使用すると、DSC エンジンに渡す前に win_dsc
モジュールで値が手動で解析されないため、推奨されます。たとえば、Ansible で単純なタイプの配列を定義するには、次のようにします。
# [string[]]
ValueData: entry1, entry2, entry3
ValueData:
- entry1
- entry2
- entry3
# [UInt32[]]
ReturnCode: 0,3010
ReturnCode:
- 0
- 3010
[CimInstance[]]
(ディクショナリーの配列) のような複雑なタイプの配列は、次の例のように定義できます。
# [CimInstance[]]BindingInfo == MSFT_xWebBindingInformation
BindingInfo:
- Protocol: https
Port: 443
CertificateStoreName: My
CertificateThumbprint: C676A89018C4D5902353545343634F35E6B3A659
HostName: DSCTest
IPAddress: '*'
SSLFlags: 1
- Protocol: http
Port: 80
IPAddress: '*'
上記の例は、MSFT_xWebBindingInformation クラスの 2 つの値のある配列です。[CimInstance[]]
を定義すると、リソースドキュメントを参照して、定義で使用するキーを確認してください。
日時
[DateTime]
オブジェクトは、ISO 8601 の日時フォーマットで日付と時間を表す DateTime 文字列です。[DateTime]
フィールドの値は、文字列が Windows ホストに適切にシリアライズされるように、YAML で引用する必要があります。以下は、Ansible で``[DateTime]`` の値を定義する方法の例です。
# As UTC-0 (No timezone)
DateTime: '2019-02-22T13:57:31.2311892+00:00'
# As UTC+4
DateTime: '2019-02-22T17:57:31.2311892+04:00'
# As UTC-4
DateTime: '2019-02-22T09:57:31.2311892-04:00'
上記のすべての値は、UTCの 日付時刻が 2019 年 2 月 22 日午後 1 時 57 分 31 秒 2311892 ミリ秒であることと同じです。
別のユーザーとして実行
デフォルトでは、DSC は各リソースを、Ansible がモジュールの実行に使用するアカウントではなく、SYSTEM アカウントとして実行します。つまり、HKEY_CURRENT_USER
のレジストリーハイブのように、ユーザープロファイルに基づいて動的に読み込まれるリソースは、SYSTEM
のプロファイルで読み込まれます。PsDscRunAsCredential
は、DSC エンジンが別のアカウントで実行されるように、すべての DSC リソースに設定することができるパラメーターです。PsDscRunAsCredential
はタイプが PSCredential
なので、サフィックス _username
と``_password`` で定義されています。
レジストリーリソースタイプを例として使用し、Ansible ユーザーの HKEY_CURRENT_USER
ハイブにアクセスするタスクを定義する方法を説明します。
- name: Use win_dsc with PsDscRunAsCredential to run as a different user
win_dsc:
resource_name: Registry
Ensure: Present
Key: HKEY_CURRENT_USER\ExampleKey
ValueName: TestValue
ValueData: TestData
PsDscRunAsCredential_username: '{{ ansible_user }}'
PsDscRunAsCredential_password: '{{ ansible_password }}'
no_log: true
カスタムの DSC リソース
DSC のリソースは、Microsoft の組み込みオプションに限定されません。カスタムモジュールをインストールすることで、通常では利用できない他のリソースを管理することができます。
カスタムの DSC リソースの見つけ方
PSGallery を使用すると、カスタムリソースと、それを Windows ホストにインストールする方法に関するドキュメントを見つけることができます。
Find-DscResource
コマンドレットを使用して、カスタムリソースを検索することもできます。以下に例を示します。
# Find all DSC resources in the configured repositories
Find-DscResource
# Find all DSC resources that relate to SQL
Find-DscResource -ModuleName "*sql*"
注釈
Microsoft が開発した DSC リソースで、x
で始まるものは、実験的なリソースであり、サポートがないことを意味しています。
カスタムリソースのインストール
DSC リソースをホストにインストールする方法は 3 つあります。
Install-Module
コマンドレットを手動で使用Ansibleモジュール
win_psmodule
を使用モジュールを手動で保存して別のホストにコピー
以下は、win_psmodule
を使用して xWebAdministration
リソースをインストールする例です。
- name: Install xWebAdministration DSC resource
win_psmodule:
name: xWebAdministration
state: present
インストールすると、win_dsc モジュールは、resource_name
オプションでリソースを参照することで、リソースを使用できるようになります。
上記の最初の 2 つの方法は、ホストがインターネットにアクセスできる場合にのみ機能します。ホストがインターネットにアクセスできない場合は、まずインターネットにアクセスできる別のホスト上で上記の方法を使用してモジュールをインストールし、それをコピーする必要があります。モジュールをローカルのファイルパスに保存するには、次の PowerShell コマンドレットを実行します。
Save-Module -Name xWebAdministration -Path C:\temp
これにより、C:\temp
の中に``xWebAdministration`` フォルダーが作成され、このフィルダーはどのホストにもコピーできるようになります。PowerShell がこのオフラインリソースを見るためには、環境変数 PSModulePath
で設定されたディレクトリーにコピーされている必要があります。ほとんどの場合は、この変数を通じてパス C:\Program Files\WindowsPowerShell\Module
が設定されますが、win_path
モジュールを使用して異なるパスを追加することができます。
例
zip ファイルの展開
- name: Extract a zip file
win_dsc:
resource_name: Archive
Destination: C:\temp\output
Path: C:\temp\zip.zip
Ensure: Present
ディレクトリーの作成
- name: Create file with some text
win_dsc:
resource_name: File
DestinationPath: C:\temp\file
Contents: |
Hello
World
Ensure: Present
Type: File
- name: Create directory that is hidden is set with the System attribute
win_dsc:
resource_name: File
DestinationPath: C:\temp\hidden-directory
Attributes: Hidden,System
Ensure: Present
Type: Directory
Azure の操作
- name: Install xAzure DSC resources
win_psmodule:
name: xAzure
state: present
- name: Create virtual machine in Azure
win_dsc:
resource_name: xAzureVM
ImageName: a699494373c04fc0bc8f2bb1389d6106__Windows-Server-2012-R2-201409.01-en.us-127GB.vhd
Name: DSCHOST01
ServiceName: ServiceName
StorageAccountName: StorageAccountName
InstanceSize: Medium
Windows: true
Ensure: Present
Credential_username: '{{ ansible_user }}'
Credential_password: '{{ ansible_password }}'
IIS Web サイトのセットアップ
- name: Install xWebAdministration module
win_psmodule:
name: xWebAdministration
state: present
- name: Install IIS features that are required
win_dsc:
resource_name: WindowsFeature
Name: '{{ item }}'
Ensure: Present
loop:
- Web-Server
- Web-Asp-Net45
- name: Setup web content
win_dsc:
resource_name: File
DestinationPath: C:\inetpub\IISSite\index.html
Type: File
Contents: |
<html>
<head><title>IIS Site</title></head>
<body>This is the body</body>
</html>
Ensure: present
- name: Create new website
win_dsc:
resource_name: xWebsite
Name: NewIISSite
State: Started
PhysicalPath: C:\inetpub\IISSite\index.html
BindingInfo:
- Protocol: https
Port: 8443
CertificateStoreName: My
CertificateThumbprint: C676A89018C4D5902353545343634F35E6B3A659
HostName: DSCTest
IPAddress: '*'
SSLFlags: 1
- Protocol: http
Port: 8080
IPAddress: '*'
AuthenticationInfo:
Anonymous: false
Basic: true
Digest: false
Windows: true
参考
- Ansible Playbook
Playbook の概要
- Ansible のヒントと裏技
Playbook のヒントと裏技
- List of Windows Modules
Windows 固有のモジュールリスト (すべて PowerShell に実装)
- User Mailing List
ご質問はございますか。Google Group をご覧ください。
- リアルタイムチャット
Ansible チャットチャンネルへの参加方法