雑記

インフラのことだったりプログラムのことだったりどうでもいいこと書いたり。要は雑記。

EC2のタグをCLIで管理するtapewriterというツールを作った

タイトル通りですが、EC2のタグをCLIで管理したくて(=コード化したくて)作ってみました。

route53をDSLで管理するroadworkerという素晴らしいツールがあるのですが、おもいっきりその影響を受けています。 (や、ほんと素晴らしいツールで結構な衝撃だったんです)

なにをするもの?

EC2のタグをjsonで管理できるようになるツールです。 jsonなのでバージョン管理もバックアップも取れます。

どんなところで使うの?

  • タグのバックアップをとりたいとき
  • タグをバージョン管理したいとき
  • ブラウザでの作業が嫌だというとき
  • タグを一気に変更したいとき

つかいかた

 タグをエクスポートする

% tapewriter -r ap-northeast-1 -f dev-app.json --export --filter '{"Env":"dev", "Role":"app"}' 

フィルターが使えます

タグを編集する

  • 変更前
{
  "instances": [
    {
      "id": "i-11111111",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "hoge",
        "State": "standby"
      }
    },
    {
      "id": "i-22222222",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "fuga",
        "State": "standby"
      }
    }
  ]
}
  • 変更後
{
  "instances": [
    {
      "id": "i-11111111",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "hoge",
        "State": "run"
      }
    },
    {
      "id": "i-22222222",
      "region": "ap-northeast-1",
      "tags": {
        "Env": "dev",
        "Role": "app",
        "Name": "fuga",
        "State": "run"
      }
    }
  ]
}

Stateタグを変更しています。

dry-run(テスト実行)

どんな変更がされるか確認

% tapewriter -r ap-northeast-1 -f dev-app.json --apply --dry-run

適用

タグを適用

% tapewriter -r ap-northeast-1 -f dev-app.json --apply

実際使ってみて

複数インスタンスのタグを一気に変更したいときにあってよかったなーと思いました。

でも1つのインスタンスのタグを一つだけ変える、とかだったらAWSコンソールからやったほうが早いです。

そもそも

みんなタグってどうやって管理しているんだろ。というかそもそも使ってないのか?ちょっと聞いてみたい。

sensuについてちょっとだけ発表した

資料は以下。

こういった発表は初めてだったんだけど、伝えたいこと全然言えなかった。 難しいものですね。

多分内容的にはニッチなものです。 最近では監視系はSaaSを利用するパターンが主流だと思うんだけど、お金とか事業や会社の方針でSaaSが使えないという方もいらっしゃるとは思うので、そういった方の参考になればなーと思います。

ちなみにdemo中で利用したものは以下です。

気がづいたらGrafanaの2.0(beta)がリリースされてた

ざっと見た感じ、結構変わってますね。

  1. グラフのスナップショットがとれるらしい -> 障害時にスナップしてチャットに送るとかできるのかな
  2. シングルパネルが表示できる -> 最新のロードアベレージとかパッと見てわかるようになる
  3. バックエンドをブラウザ上から複数保存 -> グラフにするときにどのバックエンドを利用するか選択可能
  4. グラフ毎に表示させる時間帯を変更可能に(これまでは1ページで同じ時間を表示させてた)
  5. Grafanaがデーモンとして起動するようになってる
  6. 各パッケージでインストールできるようになってる
  7. アカウント管理ができる -> ダッシュボード見るのにログインを挟むことができる(なしにもできそう)

それ以外にもUIがわりかし変わってました(でも大幅な変更でないので違和感はない)

上記だと1と2の機能がずっと欲しかったんで、早速いろいろ試したいと思います。

コマンドで暗号方式を指定してSSL接続する

今更だけど、OpenSSL関連の脆弱性でお世話になったコマンドを備忘録としてめも。

POODLE、FREAKの時に使いました。

SSL3対応か確認する(POODLEの確認)

% openssl s_client -connect example.com:443 -ssl3

暗号化スイートでEXPORTが使われているか確認(FREAKの確認)

% openssl s_client -connect example.com:443 -cipher EXPORT

いずれも接続に失敗したら、脆弱性に対応済みということ。

SSLの接続テストを実施してくれるサイトで試してもいいんだけど、診断に時間かかったりするので、簡易にさくっと試すならコマンドで確認するのがオススメ。

nginxのluaモジュールを使ってみる

インストール

インストールの方法としてopenrestyを使う方法と各ライブラリをひとつずつ用意して通常のnginxに組み込む形があった。 openrestyを使うことが強く推奨とのことですが、今回はnginxに自分で組み込む形にします。 (公式が配布していないnginxを使うということに心理的に抵抗があっただけ。openresty自体はlua-nginx-moduleのメンテナさんが作ったものらしいので、まぁ大丈夫だろうけど)

事前に用意が必要なのが以下

  • LuaJIT
  • ngx_devel_kit
  • ngx_lua

LuaJIT

# cd /usr/local/src
# git clone http://luajit.org/git/luajit-2.0.git
# cd luajit-2.0
# make
# make install

ngx_devel_kit

# cd /usr/local/src
# git clone https://github.com/simpl/ngx_devel_kit.git

ngx_lua

# cd /usr/local/src
# git clone https://github.com/openresty/lua-nginx-module.git

あとはnginxのconfigureオプションに以下を追加すればよいだけ。他のオプションは環境に応じて付与する感じ。

--with-ld-opt=-Wl,-E,-rpath,/usr/local/lib
--add-module=/usr/local/src/ngx_devel_kit
--add-module=/usr/local/src/lua-nginx-module

実際の設定

サブドメインによってproxy先を変更してみる

問い合わせ先はファイルで設定(問い合わせ先をredisとかにすることも可能)

server {
    listen       80;
    server_name  ~^(?<subdomain>[^\.]+).example.com;

    # /etc/nginx/route/settings/$subdomain に記載されているhost:portに対してproxyする
    location / {
        # この環境ではlocalにdnsmasqを立てたので、127.0.0.1を指定。実環境では普通にdnsサーバを指定する。
        resolver 127.0.0.1 valid=30s;

        # 先にproxy_toを定義しておかないと、シンタックスチェックが通らない
        set $proxy_to "";
        # luaの部分
        rewrite_by_lua '
          # サブドメインを引数に内部リダイレクト
          res = ngx.location.capture("/settings/" .. ngx.var.subdomain)
          # proxy先の設定ファイルが存在すれば、proxy_to変数に読みこんだ結果をセット
          # 存在しなかったら404で終了
          if res.status == ngx.HTTP_OK then
              ngx.var.proxy_to = string.gsub(res.body, "\\n", "")
          else
              ngx.exit(ngx.HTTP_NOT_FOUND)
          end
        ';

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        proxy_pass http://$proxy_to;
        proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;
    }

    # proxyy先設定ファイルを各区人
    location ~ ^/settings {
        internal;
        root /etc/nginx/route;
    }
}

proxy先の設定ファイルは以下のフォーマット /etc/nginx/route/settings/hoge

localhost:8080

上記の場合、「hoge.example.com」にアクセスした場合、proxy先はlocalhost:8080となる。

ちなみになんでRedisじゃなくてファイルにしているかというと、Redis落ちるとサイトにアクセスできなくなるということであり、そうなるとRedisもちゃんと管理しなきゃになり、カジュアルにこの機能を使おうとするとちょっとおおげさかなと思ってでした。

唯一懸念だったのがパフォーマンスだったけど、サイボウズさんですらほぼ影響はなかったとのことなので気にしなくてよさげですしね(もちろん本番に反映するときはちゃんと自分でも検証しますが)

参考