読者です 読者をやめる 読者になる 読者になる

tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShell DSC Advent Calendar 2014 : Day 3 Chef と PowerShell DSC のこれまでと用語まとめ

これは、PowerShell DSC Advent Calendar 2014 - Adventar 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 を深く知らなくてもフローが変わりません。

  1. これまで通り必要なクックブック(DSC Cookbooks) を使って
  2. レシピを書いて
  3. 適用する。おわりです。

新しいことをする時に従来の仕組みの根本をそのまま使えれば、導入から運用までスムーズに違和感なく行えます。違和感を小さくするのは新しい挑戦にとって本当に大事です。

ではなぜ Chef は DSC を使うことを決めたのでしょうか?少し振り返りましょう。

なぜ Chef + PowerShell なのか

Windows を管理する人にとって PowerShell は、より便利に強力に後押ししてくれます。マイクロソフトも期待に応えて、OS/アプリケーションの自動化をPowerShell に移行/公開してきました。

もはや cmd での管理はないと明確にしています。

PowerShell + Chef という組み合わせをすることで、Chef が Windows のために独自実装することなく、PowerShellソリューションを再利用できます。

  • 新規Chef ユーザーにとってもいい話でしょう。
  • 既存のChefパターンもScriptリソースで実施できます。
  • OSの低レイヤへのアクセスも、Cや静的言語を介することなく可能になります。

Chef + PowerShell = Delight + PowerChefチームの開発者は述べています

Chef の PowerShellに対する軌跡

Chef と PowerShell の関係は、2011年の公開から3年に渡っています。

概要
2011年 PowerShell クックブックがLWRP(lightweight resource and provider)として公開されました。
2013年 Native PowerShellスクリプトリソースが公開されました。ここで 32/64bit を明示的に制御できるようになっており、Chefでは bash や他のスクリプトリソースと同等になったと扱っています。
2014年 PowerShel クックブック が PowerShell v4をサポートするように更新されています。

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 でそのまま実行できるように見えます?

f:id:guitarrapc_tech:20141203040854p:plain

ここから闇を見ることになるでしょう。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

あんなにシンプルだったのに、PowerShell -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 も、この二つを分離しています。

対象 DSC Chef 概要
どうやるか
(ロジック)
リソース
(Resource)
クックブック
(Cookbook)
どういう状態であるべきか
何をどういう状態に
(呼出し)
コンフィグレーション
(Configuration)
レシピ
(Recipe)
ロジックを呼び出してあるべき状態を宣言型構文で指示

分離によって、利用者(呼びだす時)はロジックは「リソースを準備」するだけで再利用できます。*7

あとはあるべき「状態を宣言」することに集中できます。

  • 何をしたいかに応じてロジック(リソース/クックブック) を設置
  • リソースに応じて、呼び出しを宣言(コンフィグレーション/レシピ)

リソースによって宣言するキーは変化しますが、構文に変化はなくいつも同じ使い心地で記述できます。

前述の通り、Chef は DSC を直接呼び出せます。

環境変数にEDITOR という名前でvim を登録する宣言型構文で両者を見てみましょう。

env 'editor' do
    key_name "EDITOR"
    value    "vim"
end

DSC のコンフィグレーションは、ブランケット程度の違いでほぼ同じですね。

environment editor
{
    Name = "EDITOR"
    Value = "vim"
}
冪等性

ある操作を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 v3 からは 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 にて規定されています。

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」について説明します。

*1:PowerShell を 64bit で動かすように指示が必要になる

*2:宣言的記法

*3:Domain Specific Language

*4:べきとうせい

*5:わかり難い人は、DSC 用の何をしたいかわかりやすくした構文があると思っていただけるといいと思います。

*6:静的言語としては、C# が第一級市民です。話が脱線するのでここでは触れません。

*7:OSSで公開されたものでも、自分で書いてもいいです

*8:DSC は Pull に限ります。

*9:現在はPushのみ

*10:HTTP : TCP 5985 / HTTPS : TCP 5986