Glide Note

glidenote's blog

Terraform + GitHub + CircleCI + Atlasを利用してAWSの操作を自動化した

TL;DR

  • Terraform + GitHub + CircleCI + Atlas を用いてAWSの操作を自動化した
  • 各ツールの役割は下記のような感じ
    • Terraform => インフラへの変更ツール
    • GitHub => .tfファイルのバージョン管理
    • CircleCI => CI、Terraformをawsに対して実行
    • Atlas => インフラの状態を記録するterraform.tfstateの管理
  • インフラの継続的デリバリー - naoyaのはてなダイアリーにて、言及されていた範囲(Route53の変更、Chefの適用)をAWSの操作全体に拡大した

背景

今までの問題点

Terraform + GitHub + CircleCI + Atlas でインフラを管理するメリット

  • ブラウザからのポチポチ業から解放される
  • インフラ構成をコードで管理出来る。バージョン管理が出来る
  • インスタンス追加、EIPの設定などAWSの操作、インフラ構成の変更をGitHubのPR、レビュー、Mergeのプロセスに載せることが出来る
  • 自動化が可能になる
  • CircleCI上にインフラ変更のログを保持することが出来る
  • インフラの変更をGitHubのMergeボタンに集約出来る

実装概要

2015年2月18日現在最新のTerraform v0.3.6を用いて実現している

  1. EC2、EIPなどAWSの変更をコードに書いてGitHubにPush。(Atlasでterraform.tfstateを管理している場合はterraform pullして最新のterraform.tfstateもPush)
  2. Pushを契機にCircleCI上でterraform plan --refresh=falseを実行してtest。testが通ればPull Requestを作成
  3. Pull RequestをmasterにMerge
  4. masterへのMergeを契機にCircleCI上からterraformを実行
  5. terraform applyを実行して、awsに設定を反映
  6. Atlasにterraform pushして、terraform.tfstateファイルを管理
  7. 鮨を食べる

CircleCI上からterraformを実行しているキャプチャ

設定ミスやエラーが発生するとFailしてSlackに通知される

実際のtfファイルの感じ

クレデンシャル情報はCircleCI上で暗号化した環境変数を管理していて、Gitリポジトリ内では管理せず、 CI実行時に生成している。

1
2
3
4
5
6
7
8
9
10
# credential
provider "aws" {
    access_key    = "XXXXXXXXXXXXXXXXXXXX"
    secret_key    = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    region        = "us-west-1"
}

provider "atlas" {
    token         = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# instance
resource "aws_instance" "dev001_foobar_net" {
    ami             = "ami-xxxxxxxx"
    instance_type   = "t2.micro"
    key_name        = "xxxxxxxxxxxxxxxx"
    security_groups = ["sg-xxxxxxxx"]
    subnet_id       = "subnet-xxxxxxxx"
    tags {
        Name    = "dev001.foobar.net"
        Role    = "common"
        Service = "operator"
        Env     = "dev"
    }
}
1
2
3
4
5
# eip
resource "aws_eip" "dev001_foobar_net_eip" {
    instance = "i-xxxxxxxx"
    vpc      = true
}

などTerraformは同じディレクトリ内にある.tfファイルを見てくれるので、 用途毎で.tfファイルを分けて運用してます。

その他

  • 2014年8月にTerraformがリリース直後にチャレンジしたが、機能が足りずに実現出来なかったが、半年経過して必要機能が揃い実現出来た。
  • 今日現在(2015年2月18日)TerraformにはAWS上の既存設定をファイルに落とし込む機能がないので、一から作る必要がある。
  • 今回はインスタンスの一斉リプレイスがあったので、そのタイミングを利用して導入した。
  • AtlasとGitHubの連携機能がリリース予定なので、それがリリースされるとさらに便利になるかもしれない(1月リリース予定だったけど)
  • 今回はAtlasとTerraformだけを組み合わせたが、AtlasはVagrant、Packer、Consulとも連携が出来るので引き続き検証中

参考

Serverspec本を読んで、先鋭化されつつあるWeb系インフラエンジニアを知る

Serverspec

Serverspecを執筆されたmizzyさんからご恵贈頂きました。ありがとうございます。

本書の詳細な紹介はあんちぽさんのブログと、mizzyさんが出演したRebuildがオススメです。

事前に断っておくと私がここで記載している「インフラエンジニア」はITインフラエンジニアの話です。

以前サーバ/インフラ徹底攻略を本ブログで紹介したあとに、 書内のある特集を執筆担当された方と話していて、

Web系インフラエンジニアがどんどん先鋭化されつつあって、この本の内容を理解出来る人ってどれくらいいるんだろうね

という事を仰っていたのが非常に印象的であった。

先鋭化という言葉を聞いて、昨今のWebインフラエンジニア界隈の技術を思い起こすと、 Serverspecの登場以前、以後でその先鋭化具合が顕著になったと個人的に思っている。

サーバのテスト標準ツールとなったServerspec

ServerspecはWeb系インフラエンジニアに待望されていたものであり、 その登場により現在のサーバ構築において

  1. PuppetやChefなどでインフラのコードを書く
  2. 適用する
  3. Serverspecでテストを実行する

という一連の作業がスタンダードになった。

サーバ構築の一連の作業において一番面倒な確認作業をコードに出来ることで、 自動化、属人性の排除、CIはもちろん、何が設定されていて、何が動いているのかなどインフラの透明性を高める事が可能になった。

またserverspec/serverspecのcontributorsを見ると、 Web系インフラエンジニアが非常に多いことから分かるように、作者のmizzyさんを中心に、 Web系インフラエンジニアが自分たちで使うためにPRを送り、それが取り込まれ機能拡張され進化したツールだと思っている。

Kaizen Platform, Inc.でのServerspec利用

私の現在勤めるKaizen Platform, Inc.においても、技術顧問であり本書の前書きを担当した伊藤直也さんによって Serverspecは導入され、インフラエンジニアのyoshiakisudo、@m_doiによりChef + Serverspec + GitHub + CircleCI + Docker を組み合わせる形に進化し、

  1. Chefのレシピを書く。Serverspecのテストを書く
  2. GitHubにPushする
  3. GitHubへのPushを契機にCircleCI上に新規にDockerコンテナを立て、Chefを適用
  4. DockerコンテナにServerspecを流してテストを実行する

というサイクルを1日に十数回まわして、インフラの継続的な改善を行っている。

サーバへのChef適用

余談であるが、サーバへのChef適用は@m_doiのより昨年夏からChatOps化されており、

チャット(Slack)上からhubot経由でGitHub上にデプロイ用PRを作成

作成されたPRのmerge

mergeを契機にCircleCI経由でサーバにChefを適用

というようになっていて、手元やサーバからコマンドラインを操作して実行することはない。

これが可能なのもServerspecにより、インフラコードのテストが行われているためであり、Serverspecの功績は非常に大きい。

Serverspec本を読むことは、Serverspecという強力な武器を手にして、飛躍的に進化し続けているWeb系インフラエンジニアを知るために 最も有用な手段である。

最近1週間くらいずっとAmazonでベストセラー1位になっているので、もう既にみんな読んでいると思いますが傑作です。

本書内で拙作の

を紹介して頂いて、期せずしてオライリー本デビューをさせていただきました。ありがとうございます

監視アーキテクチャ(Sensu,Pingdom,Mackerel,StatusPage.io,PagerDuty)についてまとめてみる(2014年12月版)

Sensu Advent Calendarに便乗して、Kaizen Platform, Inc.の2014年12月現在の監視アーキテクチャの話をちょっとしてみようと思う。

モニタリング領域

サービスを監視している領域

Pingdom

  • Pingdom - Website Monitoring
  • 外部ネットワークからのサービスの死活監視。アメリカ、ヨーロッパ、アジアなどの拠点からサービスの死活監視が出来るため、特定の地域からアクセス出来ない場合なのが検知出来る。
  • 後述するstatuspage.ioとの連携で、障害を検知すると、サービスのステータス状況が自動で変わるようになっている

Sensu

  • Sensu | The open source monitoring framework.
  • 監視フレームワーク
  • サーバを内部ネットワークから監視するために利用
  • サーバのプロセス監視、サーバ間の疎通監視、エラー監視など一般的な監視はSensuが担当
  • 自作の監視プラグインなども利用して監視

Mackerel

Incident Management領域

アラート通知先や障害情報の自動更新を管理している領域

StatusPage.io

  • StatusPage.io - Hosted Status Pages for Your Company
  • サービスのステータスを外部に公開、障害情報の公開に利用。 Kaizen Platform Inc Status
  • Pingdomと連携しているので、サービスに障害があった場合は自動でお知らせが出る。
  • Twitter連携しているので障害情報を公開すると、Twitterアカウントにもお知らせが出せる。

PagerDuty

  • Incident Management System for IT Monitoring Tools | PagerDuty
  • アラートのハンドリングに利用
  • 各監視サービスのアラートは全てPagerDutyに集約
  • アラートの通知先をSMS、電話、スマホアプリ、チャットなどに設定出来る。
  • 通知スケジュールも細かく設定出来るので、日替わりでエスカレーション先のエンジニアを切り替えている
  • スマホアプリの出来が良い。

Infomation / Escalation領域

お知らせ、エスカレーション領域

Twitter

  • 前述のstatuspage.ioと連携。
  • statuspage.io上で障害情報を掲載するとTwitterにも投稿されるので、障害情報の更新において二度手間が無い。

Slack

  • Slack: Be less busy
  • 各種アラートがPagerDuty経由でSlackに通知される
  • Slackに逐一通知されるんので、アラートの履歴や対応状況などが一目で分かるようになっている

電話、SMS、メール、アプリへのPush通知など

  • PagerDutyが通知をハンドリングしてくれるので、「最初はSMSにアラートを送って、反応が無ければ○○分後電話する」など通知設定をして運用している。
  • 監視担当の人がその日都合が悪かったりした場合など、通知先の変更が簡単にできる。

その他

  • Mackerelの部分には、Datadogも検証。非常に素晴らしいサービスだった。
  • 現時点ではDatadogの方が高機能なんですが、MackerelがDatadogの超えてくれるのを期待してMackerelを採用

なぜ複数のサービスを組み合わせて監視しているかは技術顧問の伊藤直也さんのスライドを見ると分かるかと思います。

来年にはガラッと変わっているかもしれないけど、各コンポーネントがAPIで疎結合化されているのでアーキテクチャの変更も容易。

些細な障害、兆候も検知して見逃さないように、いろいろと試行錯誤を繰り返している。

ncコマンドでファイル転送するときにpvコマンドで進捗を表示する

ファイルを送受信するときに暗号化する必要が無い場合は 高速なのでncコマンドを多用しているんですが、進捗表示の方法を毎回忘れてググっているので自分用にメモ。

送信側

3000ポートを転送に使う場合。

1
pv hogemoge.zip | nc -l 3000

受信側

1
nc foobar.com 3000 | pv > hogemoge.zip

ファイル転送中は下記みたいな感じで転送済みデータサイズ、転送速度、残り時間、プログレスバーなど進捗が確認出来る

簡易的な回線速度の測定にも使えるので、大変便利。

参考

CloudFrontのログをfluent-plugin-bigqueryを利用してBigQueryに入れるようにした

TL;DR

  • Amazon CloudFrontのアクセスログをBigQueryに入れるようにした
  • BigQueryへのデータ投入には社内の他プロジェクトでも利用していて実績があり、KAIZENがメンテナになっているfluent-plugin-bigqueryを利用

背景

ここ2ヶ月くらい、あらゆるログをBigQueryに集約しつつあって、今回はAmazon CloudFrontのアクセスログについて作業をした。

Amazon CloudFrontのアクセスログには以下のような特徴がある。

  • Amazon CloudFrontのアクセスログは数時間〜1日程度遅れでS3のBucketに追加される。時系列はバラバラ
  • CloudFrontのアクセスログがtsv形式。
  • ベストエフォート型で全てのログがS3に収容される保証は無い
  • gzで圧縮されてS3に追加される(BigQueryに入れるにはgz形式から展開する必要がある)
  • ログファイルの数が非常に多い。作業していた環境でだいたい1日に15,000個くらいgzファイルがあって、全部をダウンロードするのに160分くらいかかる

という感じ。

仕組みの詳細

データの流れ

  1. CloudFrontのログが自動でS3に追加される
  2. batchサーバからs3cmd syncでcronで定期的にs3からログファイル(gz形式)をローカルに持ってくる
  3. batchサーバで、取得したログファイルをzcat ${FILE} >> /var/log/cloudfront/access.log で連結する
  4. batchサーバのFluentdでin_tailを用い/var/log/cloudfront/access.logを読み込む
  5. fluent-plugin-bigqueryを用いてBigQueryにデータを投入する(日付毎にデータ投入先のテーブルを分ける)

こんな感じでBigQueryにデータが入っている

先日発表されたS3 Event Notificasionsを検証中なので、問題が無ければ、Amazon SQSを利用した処理に切り替え予定。

この方式を採用した理由

  • 私がFluentdの運用に慣れていた。
  • KAIZENがメンテナをしているfluent-plugin-bigqueryを利用したかった
  • BigQueryへのデータ投入部分を自前で実装しなくて良い
  • BigQueryへのデータ投入周りのエラーハンドリング、再送処理をfluent-plugin-bigqueryに任すことが出来る
  • logrotateを利用して、ログの世代管理が出来る。Fluentdがログ切り替えを検知出来る。(nginxのログなど他のアクセスログと同じような感じで扱える)
  • Fluentdを利用しているので、スケールが容易
  • /var/log/cloudfront/access.log-YYYYMMDD.gzというように日別でログが分かれているので、障害やトラブル発生時のリカバリーも簡単になっている。(障害が発生した日の15,000個とかのログをS3から持ってきて云々… みたいな面倒な処理が必要ない)

その他

  • CloudFrontのログがS3に追加されるのが遅い場合1日程度かかるので、翌日のテーブルにデータが入ってしまう。BigQueryからデータを取り出すときに工夫が必要
  • BigQueryにデータ投入先のテーブルが存在しないと死ぬので、別でテーブル作成の仕組みと監視をしておく必要あり。
  • データサイズが大きい場合、テーブルを適切に分割していないとBigQuery破産に。
  • テーブルの自動作成、監視にはbigqueryを利用

該当部分のtd-agent.confの設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<source> 
  type         tail 
  path         /var/log/cloudfront/access.log
  pos_file     /var/log/td-agent/cloudfront-access-log.pos
  tag          extracted.cflog

  format       tsv
  keys         day,time,x_edge_location,sc_bytes,c_ip,cs_method,cs_Host,cs_uri_stem,sc_status,cs_Referer,cs_User_Agent,cs_uri_query,cs_Cookie,x_edge_result_type,x_edge_request_id,x_host_header,cs_protocol,cs_bytes,time_take
</source>

<match extracted.cflog>
  type                        bigquery

  buffer_type                 file
  buffer_path                 /var/log/td-agent/cf.bq.*.buffer

  method                      insert

  auth_method                 private_key
  email                       ''
  private_key_path            ''

  buffer_chunk_limit          768k
  buffer_queue_limit          5000
  flush_interval              1
  try_flush_interval          0.05 
  num_threads                 10 
  queued_chunk_flush_interval 0.01

  project                     ''
  dataset                     ''
  table                       %Y%m%d

  fetch_schema                true
</match>

BigQueryにログを集約したことで集計も調査も非常に簡単になって、本当にBigQuery素晴らしい。