これは、アドベントカレンダー3日目の記事です。
1日目、2日目を通して、DSCやCMツールがなぜ必要なのかその意義について説明しました。頑張らなくてもできるけど、めんどくさいことを任せられるっていうのはIaaS -> PaaS -> SaaSにつながる大事な感覚だと思います。
さて、3日目の今日は、PowerShell DSCについて見ていく前に、ChefとPowerShell DSCの経緯、両者の比較、そしてChef/DSCを比べながら用語の整理をしましょう。
PowerShell DSCがなんとなくしか想像できなくても、Chefをイメージしやすい人が多いと思うので少しイメージを膨らませていただければと思います。
Chef と PowerShell
PowerShell DSCを知らなくても、ChefチームとPowerShellチームの蜜月関係は耳にしたことがある方はいるのではないしょうか。ChefがDSCを使うことについて、PowerShellチームのトップであるJeffrey Snoverの言葉を、Chef Brings DevOps Platform and Practices to Windows and Microsoft Azure - Chef Blogから引用しましょう。
"Chef’s layering on top of PowerShell DSC aligns them with the Windows Server configuration strategy, which ensures their customers automatically benefit from our investments and our ecosystem. Together, Chef and Microsoft are empowering DevOps adoption in the enterprise with integrated technologies that improve collaboration and speed software development."
PowerShell DSCの上位レイヤーにChefを位置づけるというChefの姿勢は、Windowsサーバーの構成戦略に則っているのです。これにより、Chefユーザーは自動的にWindowsエコシステムの恩恵を享受できます。Chefが独自に頑張らずともWindowsの進化をユーザーが受けられるのは大きいです。
DSCをプラットフォームとしてChefというツールから扱うことで、ユーザー自身はWindowsやDSCを深く知らなくてもフローが変わりません。
- これまで通り必要なクックブック(DSC Cookbooks) を使って
- レシピを書いて
- 適用する。おわりです
新しいことをする時に従来の仕組みの根本をそのまま使えれば、導入から運用までスムーズに違和感なく行えます。違和感を小さくするのは新しい挑戦にとって本当に大事です。
ではなぜChefはDSCを使うことを決めたのでしょうか? 少し振り返りましょう。
なぜ Chef + PowerShell なのか
Windowsを管理する人にとってPowerShellは、より便利に強力に後押ししてくれます。Microsoftも期待に応えて、OS/アプリケーションの自動化をPowerShellに移行/公開してきました。
もはやcmdでの管理はないと明確にしています。
PowerShell + Chefという組み合わせをすることで、ChefがWindowsのために独自実装することなく、PowerShellソリューションを再利用できます。
- 新規Chefユーザーにとってもいい話でしょう
- 既存のChefパターンもScriptリソースで実施できます
- OSの低レイヤへのアクセスも、Cや静的言語を介することなく可能になります
Chef + PowerShell = Delight + PowerとChefチームの開発者は述べています。
Chef の PowerShellに対する軌跡
ChefとPowerShellの関係は、2011年の公開から3年に渡っています。
| 年 | 概要 |
|---|---|
| 2011年 | PowerShell クックブックがLWRP(lightweight resource and provider)として公開されました。 |
| 2013年 | Native PowerShellスクリプトリソースが公開されました。ここで 32/64bit を明示的に制御できるようになっており、Chefでは bash や他のスクリプトリソースと同等になったと扱っています。 |
| 2014年 | PowerShel クックブック が PowerShell 4.0をサポートするように更新されています。 |
DSCがない時にChefがどのようにPowerShellを利用していたのか、そこで起こった問題を少しみてみましょう。
guard と PowerShellクックブック
chef guardを使えば、not_if/ only_ifなど便利な構文を使ってスクリプトリソースをテストが楽になったりまぁ便利です。はい、いいですよね。
powershell_script "executionpolicy" do code 'Set-ExecutionPolicy RemoteSigned' not_if "(Get-ExecutionPolicy -Scope LocalMachine) -eq 'RemoteSiggned'" end powershell_script "smbsharelogs" do code 'New-SMBShare logshare C:\logs' not_if 'Get-SMBShare logshare' end
Windowsでそのまま実行できるように見えます?

ここから闇を見ることになるでしょう。2度目はこけたり、guardは32bitで動作するため32bit PowerShellは起動されたり。*1実はcmd.exeから呼び出されているからPowerShell.exeを起動して引数で渡さなきゃだっりとかー。
これらの問題に対応するため書きなおすと.....悲しみを見ます?
powershell_script "executionpolicy" do code 'Set-ExecutionPolicy RemoteSigned' not_if "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy bypass -command ((Get-ExecutionPolicy -Scope LocalMachine) -eq 'RemoteSiggned')" end powershell_script "smbsharelogs" do code 'New-SMBShare logshare C:\logs' not_if "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -noprofile -executionpolicy bypass -command (Get-SMBShare logshare)" end
あんなにシンプルだったのに、ps1 -noprofile -executionpolicy bypassとかついたり、えって感じです。bashではこのようなばかげた記述が不要なのに。
さらに、ダブルクォート"やシングルクォート"、リダイレクト演算子"を渡したい時はどうでしょうか? Rubyですでにstringのオーバーライドしてたら.... 3重クォートしますか?
それでも多くのChefコミュニティの人々が問題に取り組んできました。PowerShell + Chefがもっと楽に簡単になると信じて。
guardに関してはインタプリターを用いて書けるようになり、 64bitで動作するようになりました。一行guitad_interpreter :powershell_scriptが増えましたがシンプルになりましたね。
powershell_script "executionpolicy" do guitad_interpreter :powershell_script code 'Set-ExecutionPolicy RemoteSigned' not_if "(Get-ExecutionPolicy -Scope LocalMachine) -eq 'RemoteSiggned'" end powershell_script "smbsharelogs" do guitad_interpreter :powershell_script code 'New-SMBShare logshare C:\logs' not_if 'Get-SMBShare logshare' end
でも待ってください。
これって結局「PowrShell Script」を書かないといけないんですね。これを続けてると禿げます。 もっと、「あるべき状態」を示すだけでいいようにもっとシンプルにしたくないですか? だってChefのレシピの多くがそうですから。
Chef の PowerShell Script クックブックの辛さは他人事ではない
記事を読んでくださっている方で「WindowsでPowerShellにて全部構成しよう」と思った方は、Chefが直面したのと似たような問題に出あったことがあると思います。決して他人事ではありません。
ChefをはじめとするConfiguration Managementツール(構成管理ツール / 以下CMツール) では、構成管理をするにあたって、「スクリプトを毎回書いて実行する」辛さを軽減するために以下を採用しています。
- 「あるべき状態の宣言」と「ロジック」の分離
- Chefでいう、「レシピ(あるべき状態の記述)」でクックブック(ロジック)の呼び出し
- 「どうやるか」の手順ではなく、「どのような状態」でいてほしいかを
Declarative Syntax*2 で明確に簡潔に表現 - あるべき状態への収束(自動的にその状態になること)
ChefをはじめとするLinux/UNIXから3週ぐらい遅れましたが、WindowsでもCMツールを作ることになりました。その際、PowerShellチームがChefチームから多くを教わり、タッグを組んで構築されています。これが PowerShell Desired State Configuration (PowerShell DSC) です。
Chef と DSC と用語
前置きが長くなりました。
ChefとDSCを比較しながら用語をまとめていきましょう。Chefを利用したことがある人にとってはDSCがより身近に感じていただけると思います。DSCを使っている人にとっては、Chefが身近に感じられるでしょう。
以下が用語の一覧です。
| Feature | DSC | Chef |
|---|---|---|
| Configuration as Code | O | O |
| DSL*3 | O | O |
| DSLが統合されたスクリプト言語 | PowerShell | Ruby |
| リソースコンセプト | リソース/ コンフィグレーション |
クックブック / レシピ |
| 設定可能なリソース属性 | プロパティ | Attribute |
| 冪等性*4 | O | O |
| あるべき状態への収束 | O | O |
| クライアント/ エージェントツール |
LCM / Start-DSCConfiguration |
chef-client / chef-client |
Configuration as Code
コード(Code) で構成(Configuration) を行うというコンセプトです。
対比としてよくいわれるのは、ポチポチマウスをクリックしてというアレですね。
DSCで構成をするということは、コードで構成を行うということです。つまり、アプリケーションと同様にインフラがコードになります。
- バージョン管理システムでコード管理ができます
- コードから自動的なテスト、展開/配置、適用までアプリケーションと同様に扱えます
- コードがバージョン管理をされると、インフラもバージョン管理できます
- 職人のマウスさばき(謎)もなく、コードという形で知識が共有されます
設定をコードで行うことは、慣れてないと難しいと感じるかもしれませんが、それに勝るメリットがあります。
DSL
特定のタスク向けに設計されたコンピュータ言語を意味する
Chefの記法は、特定のルールに基づいています。DSCの記法もそうです。
たとえばChefのレシピなら。
[cookbook] '名称' do [Key_name] "[key_value]" [value_name] "[value_value]" end
PowerShell DSCのコンフィグレーションは↓です。Chefのレシピに似た宣言的な構文なのがわかるでしょう。
[リソース] 名称
{
[Key_name] = "[key_value]"
[value_name] = "[value_value]"
}
「あるべき状態を宣言」する構文になっているため、よく 宣言型構文(Declarative Syntax)と呼ばれます。*5
PowerShell v5からは、DSCリソースを記述しやすいようにクラス構文も追加されます。詳しくはこちらの記事
宣言型構文に対して、従来のPowerShell関数は「処理を順次記述していくことを記述」する命令型構文 といわれます。この辺の記事で違いを説明しているので詳しく知りたい方はどうぞ。
function hoge ([System.String]$Path)
{
Get-ChildItem -Path $Path | where Extension -match ".ps1|.psm1|.psd1"
}
DSLが統合されたスクリプト言語
Chefが動作するスクリプト言語は、Rubyですね。
PowerShell DSCが動作するスクリプト言語は、PowerShellです。*6
統合されたということは、キーワードや構文によって「より書きやすく」、実行、適用など「より処理しやすく」しているということです。
DSC自体は、他言語から直接呼び出して適用もできますが、PowerShellほど特化した言語はありません。
リソースコンセプト
「あるべき状態」を維持する時に命令型構文で記述すると、「何をどのような状態にしたいのか」「どうやってその状態にするのか」がコードで分離しにくくなってしまいがちです。
そこで、ChefもDSCも、この2つを分離しています。
| 対象 | DSC | Chef | 概要 |
|---|---|---|---|
| どうやるか (ロジック) |
リソース (Resource) |
クックブック (Cookbook) |
どのような状態であるべきか |
| 何をどのような状態に (呼出し) |
コンフィグレーション (Configuration) |
レシピ (Recipe) |
ロジックを呼び出してあるべき状態を宣言型構文で指示 |
分離によって、利用者(呼びだす時)はロジックは「リソースを準備」するだけで再利用できます。*7
あとはあるべき「状態を宣言」することに集中できます。
- 何をしたいかに応じてロジック(リソース/クックブック) を設置
- リソースに応じて、呼び出しを宣言(コンフィグレーション/レシピ)
リソースによって宣言するキーは変化しますが、構文に変化はなくいつも同じ使い心地で記述できます。
前述の通り、ChefはDSCを直接呼び出せます。
環境変数にEDITORという名前でEDITORを登録する宣言型構文で両者を見てみましょう。
env 'editor' do key_name "EDITOR" value "vim" end
DSCのコンフィグレーションは、ブランケット程度の違いでほぼ同じですね。
environment editor
{
Name = "EDITOR"
Value = "vim"
}
冪等性
http://ja.wikipedia.org/wiki/%E5%86%AA%E7%AD%89
ある操作を1回行っても複数回行っても結果が同じであることをいう概念
そのままです。コンフィグレーション/レシピで宣言した状態が設定されてなければ設定。設定されていればスキップ。
と、繰り返し実行しても設定する対象の状態があるべき状態で維持されるようにします。
あくまでもロジックの責任となるため、リソース/クックブックによっては冪等性が担保されていないことがあるので注意です。基本的に、冪等性が満たされるべきですし、利用者はそれを期待します。
あるべき状態への収束
DSCもChefも、あるべき状態を維持します。一度設定しても、状態が変わったことを検知して再度あるべき状態にする。
この、あるべき状態を維持する機能をDSCもChefももっています。*8
この機能がないとどうなるでしょうか? タスクスケジューラ/cronで繰り返し実行をスケジュールするようなカオスな世界になります。
放っておいても、自動的にあるべき状態に収束するのは大事です。
クライアント/ エージェントツール
Chefの構成については、この記事がわかりやすいでしょう。
DSCの構成に関しては、ここで説明しています。
ChefもDSCも、設定を行う側と設定される側がいます。
クライアント/エージェントツールは、設定される側で「どうやってあるべき状態の設定を受け取ったり、取得したりするのか」、まさに エンジン ととも言うべき役割を果たします。
Chef : chef-clientがクライアント/エージェントツールに該当します
DSC : Local Configuration Manager(以下LCM) が該当します
DSC 特有の用語
DSCには、Chefにはない特有の用語があります。それを見ていきましょう。
CIM (Common Information Model)
CIM はネットワーク環境やエンタープライズ環境で管理情報を記述するためのモデルです。
つまりCIMを使うことで、システム、ネットワーク、アプリケーション、およびサービスの管理情報の共通の定義を利用できます。結果、Windowsに依存せず、Linuxなど他OSを含めてクロスプラットフォームに適用するための根本となります。
これは、Microsoftも参画しているDMTF (Distributed Management Task Force) という団体で業界を跨いで協議、策定されました。
ベンダー拡張可能な仕様となっているため、Windowsへの独自拡張としてWMI (Windows Management Infrastrucure) がありました。が、PowerShell 3.0からはMicrosoftはより標準的な実装となるCIMに移行を進めています。
なぜCIMなのかというと、PowerShellをクロスプラットフォームに使うための基盤となるモデルであるからです。
大事なことは2点です。
- DSC は CIM名前空間に定義されている
- Windows だけでなくOMI (Open Management Infrastrucure)を利用して Linux で利用することが本質的に可能*9
ちなみにOMIはCIM標準に従ったオープンソース実装です。
MOF (Managed Object Format)
MOFは、CIMの要素の定義に使用される標準言語であり、CIMのクラスとインスタンスを定義する構文を指定します。
詳細が、MSDNに概要があります。
MOF ファイルをコンパイルすると、すべてのクラス定義とインスタンスが CIM リポジトリに登録されます。
DMTFでも仕様が公開されています。
MOFは、構文(スキーマ)が記述されたテキストファイル(ドキュメント)のため、MOF Scheme Documentと英語で呼ばれることが多いです。
簡潔にいうと、CIMに何か指示をする場合はMOFスキーマドキュメントを利用すると容易に操作ができます。
そのため、DSCでいう「あるべき状態を記述したコンフィグレーションを実行」とは、実際には「コンフィグレーションをMOFにコンパイルする作業」を意味します。
大事なことは2点です。
- コンフィグレーションを実行すると、「あるべき状態」を定義したMOFファイルが生成される
- DSCがどうやってあるべき状態を ノードに適用しているかというと、MOF を使って CIM に構成を指示している
DSCで、コンフィグレーションから生成したMOFの一例はこうです。
コンフィグレーション
Configuration WebServer
{
WindowsFeature IIS
{
Ensure = "Present"
Name = "Web-Server"
IncludeAllSubFeature = $false
LogPath = "C:\Logs\DSC\WindowsFeature\Web-Server.txt"
}
}
MOF
instance of MSFT_RoleResource as $MSFT_RoleResource1ref
{
ResourceID = "[WindowsFeature]IIS::[WebServer]WebServer";
LogPath = "C:\\Logs\\DSC\\WindowsFeature\\Web-Server.txt";
IncludeAllSubFeature = False;
Ensure = "Present";
SourceInfo = "C:\\WebServer.ps1::3::5::WindowsFeature";
Name = "Web-Server";
ModuleName = "PSDesiredStateConfiguration";
ModuleVersion = "1.0";
};
WSMan (Web Service Management)
WSManもCIMにて規定されています。
http://dmtf.org/jp/standards/wsman
WS-Management(Webサービス・マネジメント)は、ITインフラストラクチャー全体においてシステムが管理情報へのアクセスと交換を行うための共通の方法を提供することで、IT管理のコストと複雑さに対処します。
標準化された、SSHとは別のリモートアクセス手段を提供していると思ってください。
Windows PowerShellのPSRemotingもWSManで実装されています。*10
AnsibleはLinuxからWindowsサーバーを構成する時にPSRemotingを利用しています。
大事なことは、2点です
- DSC のPUSHモードは、PSRemoting を介してノードに接続する
- DSC がLinux に PUSHで構成できるのは、この WSMan (PSRemoting) を使って、Linux にインストールした OMIに接続できるため
DSC (Desired State Configuration)
Desired State Configuration (= あるべき状態) の略です。
DSCは、CIM名前空間に実装されています。そのため、PowerShell DSCと良くセットで呼称されますが、実際はPowerShell以外から直接叩くこともできます。PowerShellが構文、キーワードをサポートしており、管理/自動化が得意であるために良くPowerShell DSCと一緒にいわれるだけです。
Chefは、DSCを利用できるといいましたが、コンフィグレーションだけでなかう、コンパイルして生成されたMOFを直接読んでDSCに適用することもできます。
まとめ
いかがでしたでしょうか?
語感に多少の違いがあっても、CMツールで広く使われています。もしこれまでCMツールになじみが薄い場合は、用語で躓いてしまいがちなので早めに抑えておくといいですね。
いよいよ明日からは、DSCの設定について見ていきます。
明日は、DSCが持つ2つの動作モード「PUSH」と「PULL」について説明します。