StackStorm 運用 TIPS ー config.yaml と config.schema.yaml の違い

 こんにちは、インフラ本部の大山裕泰です。
 ここでは StackStorm の開発・運用を実際に行っている人向けに、拡張モジュール (pack) のパラメータ設定のテーマで掘り下げた内容をお届けします。

 StackStorm がどんなもので、どういう問題を解決するかについては StackStormで始める運用自動化 ~入門編~ をご覧ください。

 このエントリによって、StackStorm pack の config.yaml と config.schema.yaml の違いや、どういったケースでどのような設定方法がベストかを理解できるようになると思います。

 冒頭で紹介した CodeZine の記事でも書きましたが、レガシーな pack の設定パラメータの記述方法として、対象 pack の `config.yaml` ファイルに記述する方法があります。その他に `config.schema.yaml` で設定されたパラメータを pack の設定コマンド `st2 pack config` から設定する方法と、StackStorm が参照するデータストア (本校執筆時点の StackStorm では `MongoDB` を使用) に設定する方法があります。
 ここでは AWS の StackStorm モジュール aws pack を例に、それぞれの方法の使い方や他の設定方法との違いについて解説して行きます。

config.yaml による設定

 config.yaml による設定は、最も単純な pack の設定パラメータの記述方法です。ユーザは config.yaml 編集し、StackStorm pack に任意のパラメータを渡すことができます。これにより、StackStorm の UI を通して外部サービスのイベントハンドリングやアクションを実行できます。
 以下は aws pack のデフォルトの config.yaml の全文になります。

---
# Note: credentials under "setup" object are deprecated and have been replaced
# with top-level values which have precedence and also work with dynamic config
# values.
setup:
  region: ""
  aws_access_key_id: null
  aws_secret_access_key: null

aws_access_key_id: null
aws_secret_access_key: null
region: "us-east-1"
interval: 20
st2_user_data: "/opt/stackstorm/packs/aws/actions/scripts/bootstrap_user.sh"

service_notifications_sensor:
  host: "localhost"
  port: 12345
  path: "/my-path"

sqs_sensor:
  input_queues:

sqs_other:
  max_number_of_messages: 1

 config.yaml は全ての pack で共通して pack の管理ディレクトリ (/opt/stackstorm/packs/{pack 名}/) の直下に置かれています。aws pack の場合には config.yaml は /opt/stackstorm/pack/aws/ 配下に置かれます。

config.schema.yaml による設定

 config.yaml はとても単純な仕組みで使い勝手が良いのですが、pack の管理ディレクトリ配下のファイルが状態を持ってしまうと、運用上で不都合が生じてしまいます。

 pack は StackStorm の ‘st2 pack install’ コマンドによって StackStorm-Exchange から最新のコードを取得し、対象 pack の管理ディレクトリ (/opt/stackstorm/packs/{pack名}/) にデプロイされた後、StackStorm に登録されます。
 また pack の削除は `st2 pack uninstall` コマンドで行いますが、その際 pack の管理ディレクトリがそっくり削除されるため、pack のデプロイ後に編集した config.yaml も削除されます。
 pack の削除以外でも、StackStorm-Exchange の pack が更新され config.yaml のスキーマが変わった場合には、pack のアップデート時にユーザが編集した config.yaml は上書きされてしまいます。

 こうした挙動は Infrastructure as Code のプラクティスに合ったもので問題ありません。
 むしろ config.yaml の存在によってポリシーと設定が結合する格好になり、上記のような運用上の問題が発生します。また、設定項目や設定値の型はユーザが自由に記述することができるため、設定周りのテストがしづらいという問題もあります。

 これに対して config.schema.yaml で記述される 設定スキーマ (Configuration schema) の仕組みが作られました。
 設定スキーマは、予め pack の作成者が必要な pack の設定項目のスキーマをスキーマファイル (config.schema.yaml) に定義しておき、ユーザは ‘st2 pack config ‘ コマンドによって、予め規定された設定項目・型の値を設定します。

 これによりテストし易くなるという利点のほか、設定結果を pack の管理ディレクトリとは別の設定項目を管理するディレクトリ ‘/opt/stackstorm/configs’ 配下に置き、ポリシーと分離させることで、pack のバージョンや状態に関わらず設定内容を独立させることができます。

 以下に aws pack の config.schema.yaml の全文を示します。

 ’st2 pack config aws’ を実行することで、上記のスキーマファイルに沿った入力が求められ、最終的に aws 用のオリジナルの設定ファイルが生成されます。

 なお、ここでの設定は cnofig.yaml の設定よりも優先されます。なので、同じ設定項目を config.yaml と config.schema.yaml から生成された設定ファイルの両方で設定されている場合には、後者の値が読み込まれます。

データストアによる設定

 最後に、データストアによる pack の設定について解説します。
 ’st2 key set’ コマンドによって、以下のように任意の key/value をデータストアに登録させることができます。

 センサーの実装においては、上記の config.yaml/config.schema.yaml による設定は起動時に読み込まれ、ここでの設定値は動的に読み込まれるような 使い分け をしており、aws pack のセンサーではこれに沿って、データストアによる設定が優先されるように実装されています。

 また Jinja template の拡張により、以下のように config.schema.yaml から生成した設定ファイルから、データストアで設定した値を参照させることができます。

 以下で、設定ファイルで指定したキー ‘dev_api_key’ の値 ‘SecretValue’ を暗号化して設定します。

 ただ、これには 文字列型しか設定できない制限 が存在するため、使用する際には注意が必要になります。

TerraformでGitHubのチーム管理を自動化して事故った話

はじめまして。
ICTトラブルシューティングコンテストの実行委員をやっている黒崎 (@kuro_m88) です。
学生時代に第3回の運営をやり、社会人になってからは運営学生のサポートをしています。

ICTトラブルシューティングコンテスト(以下ICTSC)とは、学生による、学生のためのインフラ技術コンテストです。
来月の2016年8月27日 にNTT西日本杯 第6回 ICTトラブルシューティングコンテストが大阪で開催されます。
トラコンに関する過去のツチノコエントリーは以下をご参照ください。

ツチノコブログICTSCエントリ集

TerraformでGitHubのチーム管理を自動化してみた

ICTSCでは出題に利用するコードや出題する問題案の管理をGitHubを利用して行っています。
https://github.com/ictsc

ICTSCに携わる学生や社会人は基本的にこのGitHub Organizationに入っているのですが、回によって運営に携わる学生も違います。
第4回だけ運営だった人もいれば、第4回, 第5回は運営だったけど、第6回は競技者として参加するといったケースもあります。

ICTSCのGitHub Organizationに入っている人は今回で50人くらいになるので、誰が第何回の運営だったかぱっと把握するのが難しくなってきました。

一番簡単なのはその回の運営に関係ない人をOrganizationからはずすことなのですが、せっかく運営に関わってくれたのにはずすのも寂しいなと思い、ユーザ管理をある程度自動化できないかなと思い立った訳です。(課金体系が変わったら運用方法を考えないといけませんが…)

Terraform GitHub Provider

その頃会社でTerraformを使い始めたので、GitHubも同じような感じで管理できないかなー?と調べてみると…!

なんと、Terraform GitHub Providerがあるではないですか…!🎉
https://www.terraform.io/docs/providers/github/index.html

これを使えばGitHubのOrganizationの

  • メンバー管理
  • チーム管理
  • チームのメンバー管理
  • リポジトリの権限管理

ができるようです。やりたい操作が全部用意されていました!!

ドキュメントを読みながら、こんな感じのものを作ってみました。
https://github.com/ictsc/ictsc-github-member

簡単に説明しますと、まずICTSCのGitHub Organizationのメンバーをここで定義します。
ictsc-github-member/members.tf

次に、チームを作ります。例えば第6回の運営参加メンバーはICTSC6というチームに所属させます。
また、そのチームが読み書きできるリポジトリも定義しています。
ictsc-github-member/team-ictsc6.tf

過去の運営チーム(ICTSC5等)のチームはプライベートリポジトリを見られないようにしています。
ictsc-github-member/team-ictsc5.tf

最後にこれらの操作をCircle CIで自動化できるようにします。
こんな感じの設定ファイルを書きました。
ictsc-github-member/circle.yml

運用方法

ICTSCのチームメンバに追加して欲しい人はプルリクエストを投げます。
https://github.com/ictsc/ictsc-github-member/pull/40

(ちなみに、彼は第5回の運営委員で、第6回は運営ではなく競技者として参加するのでこのプルリクエストは拒否します)

このリポジトリはpublicですが、マージする権限があるのは実行委員(社会人サポートチーム)の人だけなので、レビューののち production ブランチにマージするとCircleCI上でterraform applyが走り記述したとおりの権限がメンバーに与えられます👍

いい感じですね!👏

事故は突然に

github_membership.membership_for_kurochanという名前が冗長に感じたのでmembership_for_を取り払ってgithub_membership.kurochanのような書き方に統一したくなったので統一しました。

terraform planで変更内容を確認して、terraform applyしてみました。以下がその時のログです。

$ ~/terraform/terraform apply --var-file=conf/github.tfvars
github_membership.membership_for_kurochan: Refreshing state... (ID: ictsc:kurochan)
github_membership.membership_for_kurochan: Destroying...
github_membership.netmarkjp: Creating...
role: "" → "admin"
username: "" → "netmarkjp"
github_membership.kurochan: Creating...
role: "" → "admin"
username: "" → "kurochan"
github_membership.membership_for_kyontan: Destruction complete
github_membership.membership_for_kurochan: Destruction complete
github_membership.netmarkjp: Creation complete
github_membership.kurochan: Creation complete

コマンドの実行も成功し、当時管理者権限を持っていた僕ともう一名のアカウント設定の名前が、変更されています。
うんうん、ちゃんとうまく行ったようです。

ひととおり仕組みを作ったので学生に自慢しようと思った矢先、GitHubから一通の不穏なメールが…😨

!?!?

誰かに僕のアカウントの管理者権限が外されたようです。

せっかくterraformで管理しているのでもう一度terraform applyしてみましょう。

2 error(s) occurred:

* github_membership.netmarkjp: PUT https://api.github.com/orgs/ictsc/memberships/netmarkjp: 403 You must be an admin to add or update an organization membership. []
* github_membership.kurochan: PUT https://api.github.com/orgs/ictsc/memberships/kurochan: 403 You must be an admin to add or update an organization membership. []

Terraform does not automatically rollback in the face of errors.

403 You must be an admin to add or update an organization membership.

🔥🔥なんかやばそう!!🔥🔥

とりあえずもう一人の管理者権限を持っている方に僕を管理者に戻すようにお願いしました。

えっ、もうこれはどうしようもないのでは…😇

そしてだれもいなくなった…

管理者権限のあるユーザ全員(自分含め)から権限を剥奪してしまったようです。
誰一人管理者がいない状態なので、復旧のしようがありません。
学生にドヤ顔するつもりがなんと説明すればいいのか分からない状態になりました…。こんなことってあるのか…😱

困ったときの神頼み

どうしようもなくなったので神様(サポート)に連絡するしかありません。
自分の英語力で通じるのか自信なかったですがとりあえず連絡…

すると

よかった…回復してもらえそうです。

どうしてこうなったのか

最初のログを見ると一見成功したように見えます。
ただ、2度目実行した時には権限がなくなっていてエラーになっていたので、APIコールした瞬間はすくなくとも権限を持っていたようです。

ここからは僕の想像なので本当にこうなっていたのか分かりませんが、例えばGitHub側が

こんな感じの権限の更新の処理が非同期に行われる仕組みになっていたとしたらTerraformのように高速でAPIを叩くアプリケーションを実行した場合、今回ような事故が起きそうです。。

対策

Terraformを実行する用のユーザを作成しました。
このユーザに管理者権限をもたせ、このユーザのアカウントに関してはTerraformの管理外としました。
これで自分で自分の権限を剥奪するような事故は起きないはずです。

教訓

terraform planはあくまでも実行計画を表示するだけであって、実際に適用したら成功するかどうかは別の話で保証されないということを身を持って経験しました…。
実行される内容が問題ないかしっかり確認してから適用しましょう。。(以後気をつけます)

さいごに

ICTトラブルシューティングコンテストではこのような実際の経験を元にしたトラブルの問題を運営学生がたくさん作っています!
次回コンテストも面白い(つらい?)トラブルが出題されると思いますのでご期待ください!!

サーバセットアップの強い味方、ノートパソコン接続KVMコンソールの紹介

最近ギックリ腰(筋膜炎)で腰の大切さ、ありがたさを実感したトウマツです。こんにちは。
今回は、便利ツールを見つけましたので、みなさまに紹介したいと思います。

DMM.comラボは、DMM.comのサービスを快適にご利用いただくために、毎日のようにサーバを増設しています。

このサーバ増設には、サーバに対してIPアドレス等の初期設定をする為に、キーボード、ディスプレイ、マウスの3点セットが必要となる場合があります。
しかし、これらは大きく、重く、そしてかさばるので持ち運びに適さず、ギックリ腰の僕には苦行です。また、ディスプレイは電源を必要とするため200V供給のみのラックでは電源の確保も一苦労なのです。

というわけで、そんな悩みを解決してくれそうなツールを探してみたところ、良さげなツールを発見したので実際にどんな使い方が出来るのかを試してみました。

ノートパソコン接続KVMコンソール
http://www.startech.com/jp/Server-Management/KVM-Switches/USB-Crash-Cart-Adapter~NOTECONS02

CrashCartAdapter単体

 

実際にMacBook Pro‎とノートパソコン接続KVMコンソールを接続し、サーバをセットアップしてみるの図

CrashCartAdapter全体

 

このノートパソコン接続KVMコンソールをノートパソコンに接続して専用アプリケーションを起動すると、ノートパソコンのキーボードとマウスの入力信号をサーバにそのまま転送し、サーバから出力されるビデオ出力をノートパソコンの画面上に表示します。
つまり、従来サーバの初期設定に必要であったキーボード、ディスプレイ、マウスは不要となり、ノートパソコン1台とこのノートパソコン接続KVMコンソールのみ持っていけば済むのです。

ノートパソコン接続KVMコンソールの専用アプリケーションは、Mac OS XやWindowsにはもちろん、Linuxにも対応しています。また操作画面の録画機能を搭載していたり、USB CD-ROMに見せかけてISOイメージを読み込ませたりできるなど、「現場」で必要な機能が詰まっており、DMM.comラボのサーバデータセンタチームでも評判のツールの一つです。

というわけで、今後も面白そう、便利そうなツールをどんどん紹介していきますのでよろしくお願いします。

 

※こちらから購入しました@2015/12/02時点 $323.99
KVM Console to USB 2.0 Portable Laptop Crash Cart Adapter
(もちろんアフェリエイトではありません)

Internet Week 2015 で無線 LAN について話してきました&車載動画

11/17〜19に行われた Internet Week 2015 にて「失敗から学ぶWi-Fi構築」というテーマで講演させていただきました。Wi-Fi で陥りがちなアンチパターンと、それがなぜ失敗してしまうのか、どうしたら改善できるのかというテーマのプログラムでした。

無線LANに限らず、トラブルシューティングでは「なんか変だぞ?」という直感が、理屈よりも先に働くことがあるかと思います。これは経験や、どういう仕組みで動いているかを知ることによって、なんとなく変だなという直感として意識に上がってくるようになるのではないかと思っています。

電波は見えないし聞こえないけど、それがどういったものかをなんとなく知ることで、無線独特の特性、電波の飛び方や干渉の起こり方をなんとなくでも想像できるようになればと思い、このプログラムでお話しました。資料はのちほど Internet Week 2015 のページに掲載される予定です。

オフィス街と郊外を測定しながら走ってみた動画

プログラムの最後に紹介しました車載動画です。都内繁華街で電波が非常に混み合っているエリアから、電波がクリーンなお台場まで、簡易測定器を積んだ車で移動しながら撮影してみました。

測定器には metageek Wi-Spy を利用しました。この測定器は つながらない無線LAN!?(2/3) 調査編 で紹介したものです。

waterfall_wifi
この画面(Chanalyzer4)は、左右が周波数 (無線LANのチャネル表示)です。上下に分かれていますが、上は現在の電波強度、下はその履歴です(記録したものがだんだん下に動いていくのでウォーターフォールグラフなどとも呼びます)。

このケースでは 1, 6, 11 ch でいわゆる Wi-Fi が利用されているように見えます。それぞれのチャネルの真ん中が凹んでいますが、これが IEEE802.11a/g の特徴です。

Wi-Fi で利用されている変調方式 OFDM は、ひとつの通信を複数のサブキャリアと呼ばれる電波に分割して伝送します。802.11g (20MHz幅) であれば52本のサブキャリアに分割し、ひとつの通信となっています。この真ん中の部分は実装上の都合で通信に利用するのが難しいため、使われていません。このため、中心に凹みが観察されます。

秋葉原から出発し、お台場の暁埠頭まで移動しました。これは2.4GHz帯を観測しています。

  • 無線LANではないと思われる電波がかなり多い(意外)
  • 無線LANだけを拾うアプリ(inSSIDer, WiFi Analyzer等のアプリ)だけでは状況を正しく判断できそうにない
  • 繁華街ではほんの少し移動しただけで状況が大きく変わり、この辺はこういう状況である、等といったことは言いにくい

waterfall2

移動した約50分間のウォーターフォールを一枚に圧縮してみました。繁華街を離れ、海に近づくに従って電波の密度が下がっていき、バンド全体がクリーンになっていくのがわかると思います。

とはいえ、海の倉庫街(特に税関のある辺り)から広域にわたって何だかわからない電波が出ていたりもしましたので、やはり実際に測定してみないとわからない、かつ、この瞬間ではこういう電波状況だったが今後どうなるかもわかりません。突然トラブったりすることもあり得ます。

今度、電波がクリーンそうな熊野に行ってきたいと思います(フレッツが来ていない限界集落)。測定したら面白そうな場所があったらぜひ教えてください! 

「DMM.com Labo ツチノコ杯」ICTトラブルシューティングコンテストを終えまして 冗長化編

こんにちは!
学生ツチノコのsaiです!

今回はICTトラブルシューティングコンテスト(以下、トラコン)の一日目で出題されたネットワークの問題、スイッチ間の冗長化についてお話しようと思います。

※問題作成者ではなく大会参加者の記事となります。確実な正答ではございませんので、ご了承くださいませ。

問題のシナリオと条件

<大まかなシナリオ>
人員が増加するのでスイッチをもう一台追加することとなった。
現状、既存のスイッチと新たに導入したスイッチ間をUTPケーブル一本で接続している。
そのためか、追加されたスイッチに接続している端末のネットワークが遅くなったりと不安定である。

<条件>
1.スイッチ間の経路冗長化と通信帯域の拡張をする際、ネゴシエーションはしない設定で行う。
2.ポートはFastEthernet0/1と0/2を使用し、トランクポートとすること。

 

問題を解くに当たっての知識

・STP (スパニングツリープロトコル)

@network Cisco・アライド実機で学ぶ様  http://atnetwork.info/ccna3/stp1.html

・アクセスポートとトランクポート

ネットワークエンジニアとして様 http://www.infraexpert.com/study/vlanz2.html

・イーサチャネル

@network Cisco・アライド実機で学ぶ様  http://atnetwork.info/ccnp5/fec07.html

この問題は以上の知識と、ネットワークにおける基礎的な知識があれば解ける問題でした。

CCNAレベルを理解していれば、調べずともこの問題を解けるのではないでしょうか!

トラコンは前回か前々回まで参加する学校等の関係もありネットワーク問題の割合が多く、その難易度も高いものでした。(参加してませんが、VPNとかVPNとかVPNとか)

しかし色んな学校が参加するにあたって、問題もネットワークによるのではなくバランスの取れたものにしたようです。

 

今回の設定について

設定だけで言うと

1.スイッチA、スイッチBのFa0/2をケーブルで接続
2.ターミナルFa0/1とFa0/2にswitch mode trunkchannel-group 1 mode onを両方のスイッチに入力し適用
3.show etherchannel summayを使用し、イーサチャネルの状態を確認
4.pingを相互でvlan1に飛ばしイーサチャネルの疎通を確認
5.copyコマンドを使用し、スタートアップコンフィグに設定を反映

経路の冗長化、帯域拡張、トランクポートの設定は以上で問題ないと思われます。

 

設定の解説

では、順に解説していきます!(4,5は割愛)

1.スイッチA、スイッチBのFa0/2をケーブルで接続

これによってスイッチA―B間は二本のケーブルで繋がれた状態になっています。
しかし、ブロードキャストストームを防ぐため、STPによって一つのポートがブロッキングポートとなるので (RSTPの場合はオルタネートポートと名称が変わります)
二本繋いだけど、ループになっちゃうから一本だけ日頃使わないようにしといた という状態になります。

「なんだよ、それじゃ意味ないじゃん!!」

・・・と、待った待った。実はそんなことないんですね!
STPはループを回避するにプラスして冗長化もしてくれています。

そもそも 冗長化 とは…

まず例としてスイッチとパソコンの間にケーブルが一本あり、それを介してネットサーフィンをしているとします。
もしも、このケーブルが断線してしまったらどうなるでしょう・・・
当たり前ですが、パソコンはインターネットに接続できなくなりネットサーフィンも出来なくなってしまいます!ohᔪ( ᐪᐤᐪ )ᔭNo!

スイッチのケーブルをもう一本増やしてみましょう。
そうすると、ネットサーフィン中に片方のケーブルが断線したとしても、もう片方のケーブルがアクティブ状態となり接続が保たれるようになります!
これが冗長化!片方動かなくなってももう片方が動く!それが冗長化!
つまり冗長化を使用すると、可用性が向上するわけです!
STP以外にもRSTP、ルーターではVRRP、HSRP等、冗長化するためのプロトコルは色々あります。
設定によってはロードバランシング(負荷分散)も実現できる為、ネットワークを常時止めないという点においてとても重視される項目になります。

 

つまりは、日頃一本ケーブルを使わないだけで、片方が断線なりした場合はもう片方が肩代わりするわけです。便利ですね!
ということで、とりあえずの冗長化はケーブルの接続だけでOKです。

 

2.ターミナルでFa0/1とFa0/2にswitch mode trunkchannel-group 1 mode onを両方のスイッチに入力し適用

前者のコマンドを使用することにより、任意のポートをトランクポートに設定することが可能になります。
これによって複数のVLANの通信をトランクポートを通じ橋渡しができます!

後者のコマンドはイーサチャネルというものの設定をしています。
これは「複数の物理ポート」「一つの論理ポート」に束ねる技術です!
束ねたインタフェースをポートチャネルといい、ポートチャネルで接続する事で通信帯域を増やす事ができます!
STPでは片方のケーブルは日頃使わない状態になっていましたが、この設定を施すとケーブル二本の通信帯域を有効的に使用できるというわけです!
因みに、mode onの部分はネゴシエーションしない場合の設定となっておりますが、両方のポートでmode onの設定を入れておく必要があります。

 

この問題の設定自体は以上で終了です。

ですが、実際に反映されているか、自分の思ったように行われているかの確認のために以下を行っています。

3.show etherchannel summayを使用し、イーサチャネルの状態を確認

このコマンドを使用するとポートチャネルとそれに属しているインタフェースが見れるようになっています。

 

 

(´-`).。oO(showコマンド、ほんと便利だ)

 

まとめ

この問題では、「ネットワークが遅くなったりと不安定である」というのがトラブルの症状となっていました。

問題文の中に「冗長化と通信帯域の拡張」と対処すべき項目が記述してあったので、チームによってはスムーズに終わったのではないでしょうか。

また、今回とりあげられている冗長化はネットワークやサービスを止めないために重要であると思います。

必要となる場面は多岐にわたるので、解けなかった!知らなかった!という方は勉強してみてもいいかもですね!