Glide Note

glidenote's blog

Let’s Encryptで証明書を作ってみた

社内向けのリバースプロキシを構築中に、まだ証明書を用意していないドメインで、Let’s Encryptを試す機会があったのでメモ。

去年アメリカに行ったタイミングから完全にブログ書く習慣がなくなってしまったので、リハビリも兼ねて。

前提

  • Port 80が空いている。外部からアクセスできる。
  • DNSが引けて、名前解決ができるようになっている

作業環境

  • CentOS 7.0, Amazon Linux
  • Nginx 1.9.10

Let’s Encryptのインストール

1
2
3
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt/
./letsencrypt-auto --help --debug

./letsencrypt-auto --help --debug のタイミングで依存パッケージがインストールされる。 無事インストールが完了するとヘルプが表示される。

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
Updating letsencrypt and virtual environment dependencies......
Requesting root privileges to run with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt --help

  letsencrypt-auto [SUBCOMMAND] [options] [-d domain] [-d domain] ...

The Let's Encrypt agent can obtain and install HTTPS/TLS/SSL certificates.  By
default, it will attempt to use a webserver both for obtaining and installing
the cert. Major SUBCOMMANDS are:

  (default) run        Obtain & install a cert in your current webserver
  certonly             Obtain cert, but do not install it (aka "auth")
  install              Install a previously obtained cert in a server
  revoke               Revoke a previously obtained certificate
  rollback             Rollback server configuration changes made during install
  config_changes       Show changes made to server config during installation
  plugins              Display information about installed plugins

Choice of server plugins for obtaining and installing cert:

  --apache          Use the Apache plugin for authentication & installation
  --standalone      Run a standalone webserver for authentication
  (nginx support is experimental, buggy, and not installed by default)
  --webroot         Place files in a server's webroot folder for authentication

OR use different plugins to obtain (authenticate) the cert and then install it:

  --authenticator standalone --installer apache

More detailed help:

  -h, --help [topic]    print this message, or detailed help on a topic;
                        the available topics are:

   all, automation, paths, security, testing, or any of the subcommands or
   plugins (certonly, install, nginx, apache, standalone, webroot, etc)

証明書を作る際に、letsencryptが80番を利用するので、nginxを一時的に落とす

1
sudo service nginx stop

下記コマンドを実行して証明書を作成する。

1
./letsencrypt-auto certonly --standalone -d webapp.glidenote.com

キー紛失時の復元用のメールアドレスを入力

規約の同意画面

完了すると下記のようにメッセージが表示される。証明書の期限は90日。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to xxxxxx@xxxxxxxxxxxxxxxx.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/webapp.glidenote.com/fullchain.pem. Your cert
   will expire on 2016-05-02. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

下記のような感じでファイルが出来上がる。

1
2
3
4
/etc/letsencrypt/live/webapp.glidenote.com/fullchain.pem
/etc/letsencrypt/live/webapp.glidenote.com/cert.pem
/etc/letsencrypt/live/webapp.glidenote.com/chain.pem
/etc/letsencrypt/live/webapp.glidenote.com/privkey.pem

nginxで利用するのは fullchain.pemprivkey.pem なので、nginxのconfを修正。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
  listen 443 ssl http2;

  server_name         webapp.glidenote.com;

  ssl_certificate     /etc/letsencrypt/live/webapp.glidenote.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/webapp.glidenote.com/privkey.pem;

  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;


~ snip ~~

}

nginxを起動させてみる。

1
2
sudo nginx -t
sudo service nginx start

ちゃんとエラーが出ない証明書が出来上がっている。

更新については公式ドキュメントにあるように、下記のようのあスクリプトを用意してcronで回しておけばOKの模様。(検証用途でしか利用していないので、更新作業はまだやってないです)

1
2
3
4
5
6
7
8
#!/bin/sh
service nginx stop  # or whatever your webserver is
if ! /path/to/letsencrypt-auto certonly -tvv --standalone --keep -d webapp.glidenote.com > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
fi
service nginx start # or whatever your webserver is

参考

ChatOps + NightmareでメトリクスグラフとBIレポートをSlackに投げるようにした

TL;DR

  • Slack + Hubot + Nightmare + CircleCI を利用してSlackにNewRelicのメトリクスグラフやBIレポートを投げるようにした
  • Slackなどチャットツールとのintegrationが無いツールでもグラフを投稿出来るようにした
  • 会社のKPIやサービスの状態をSlack上からhubotを利用して誰でも簡単に確認が出来るようになった

仕組み

  1. Slack上でHubotを呼び出す(hubot-cronで自動で稼働する)
  2. HubotがCircleCIのAPIを叩いて、rebuid
  3. CircleCI上でNightmareを利用し、NewRelicやBIツールのスクリーンショットを取得し、s3にアップロード
  4. SlackのIncoming webhooksを利用してグラフを投稿する

NewRelicにログインしてスクリーンショットを取るスクリプトサンプル

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
var Nightmare = require('nightmare');
var fs = require('fs');

var urls = [];
urls.push('https://rpm.newrelic.com/accounts/xxxxxxxxxxxxxxxxxxxxxxxxxxx');
urls.push('https://rpm.newrelic.com/accounts/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
urls.push('https://rpm.newrelic.com/accounts/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');

var i = 0;

for(u in urls) {
    var url = urls[u];
    var filename = '/tmp/tmp' + i + '.png';
    fs.appendFile('/tmp/urls.txt',url+'\n');
    new Nightmare()
      .viewport(1600, 900)
      .useragent("Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36")
      .goto('https://login.newrelic.com/login')
      .type('#login_email', '[email protected]')
      .type('#login_password', 'foobarpass')
      .click('#login_submit')
      .wait()
      .goto("https://rpm.newrelic.com/set_time_window?tw%5Bdur%5D=last_3_days")
      .goto(url)
      .wait(10000)
      .screenshot(filename)
      .run(function (err, nightmare) {
        if (err) return console.log(err);
        console.log('Done!');
     });
    i = i + 1;
}

circle.yml

  • CircleCI上のphantomjsが古くグラフが正常に表示されないので、2.0.1にバージョンアップしてます。
  • ブランチ毎で処理を変更
  • スクリーンショットをs3にアップロードして、slackにpostするスクリプトはいろいろとハードコードされているので割愛…
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
36
37
38
dependencies:
  pre:
    - bundle install
    - npm install
    - sudo apt-get update; sudo apt-get install libicu52
    - curl --output /home/ubuntu/bin/phantomjs-2.0.1-linux-x86_64-dynamic https://s3.amazonaws.com/circle-support-bucket/phantomjs/phantomjs-2.0.1-linux-x86_64-dynamic
    - chmod a+x /home/ubuntu/bin/phantomjs-2.0.1-linux-x86_64-dynamic
    - sudo ln -s --force /home/ubuntu/bin/phantomjs-2.0.1-linux-x86_64-dynamic /usr/local/bin/phantomjs

test:
  pre:
    - phantomjs --version
    - npm test

deployment:
  master:
    branch: master
    commands:
      - node ./scripts/foobar.js
      - ./bin/post_image_to_slack -c \#bot-test -t "post title" -u "kaizenbot"

  newrelic-webapp-overview:
    branch: newrelic/webapp-overview
    commands:
      - node ./scripts/newrelic-webapp-overview.js
      - ./bin/post_image_to_slack -c \#engineering -t "New Relic Webapp Overview" -u "New Relic Report Bot"

  newrelic-external-services:
    branch: newrelic/external-services
    commands:
      - node ./scripts/newrelic-external-services.js
      - ./bin/post_image_to_slack -c \#engineering -t "New Relic External Services" -u "New Relic Report Bot"

  domo-variations:
    branch: domo/variations
    commands:
      - node ./scripts/domo-variations.js
      - ./bin/post_image_to_slack -c \#general -t "K2 & BP Variations" -u "BI Report Bot"

実際の動作

  • 実際にはhubot-cronを用いて自動で動くようになっています。
  • BIレポートは日替わりで内容を変えるようにしてます。
  • hubotを利用して、誰でも任意のタイミングで実行出来るようにしてます。

参考

私が悪戦苦闘しているのを横目に、技術顧問が寿司情報を収集するのにサラッと使いこなしていた有益プレゼン死霊

CDNをAkamaiに切り替えた

2ヶ月くらい前にCDNをAkamaiに切り替えたので、知見を公開。 (追記 2015年8月18日 私個人の認識不足で用語の使い方に問題があったので一部修正しました s/SLA 100%/高可用性構成/g)

TL;DR

  • Kaizen Platform, Inc.で利用しているCDNをAkamaiに切り替えた
  • Akamaiはスタートアップでも利用出来るコスト感
  • 高可用性構成のAkamaiを利用することでCDNの可用性というインフラエンジニア的に頭の痛い問題が減った

CDN第一世代 AWS CloudFront CDN (-2015年1月)

  • CDNにCloudFrontを利用

サービスで利用しているインフラのほとんどがAWSで稼働しており、 その関係でCDNもCloudFrontを選択。

CDN第二世代 CloudFront + CDN77 (2015年1月-5月)

  • AWS CloudFrontにおいて、2014年11月、12月と立て続けに障害が発生し、 CloudFrontの障害がサービス提供に与える影響が大きいため、対策を実施。
  • Route53のDNSフェイルオーバーとCloudFront + CDN77を利用し、CDNを冗長構成

対策を講じるにあたりヌーラボさんの下記のブログが大変参考になった。

ヌーラボさんの記事を参考に予備系CDNの調査と選定

当時のCDNの必須要件

  • 専用 IP 独自 (SSL Dedicated IP Custom SSL) が利用出来る。
  • Amazon S3をバックエンドに利用出来る
  • 日本とUSにエッジがある
  • 予備系なので従量課金が良い
  • AWSとは別の独自ネットワーク上に構成されている

当時6社くらいのCDN検証と問い合わせを行い、上記条件を満たすCDNとしてCDN77.comが最適だったので、 Route53のDNSフェイルオーバーとCloudFront + CDN77を利用し、CDNを冗長構成にした。(ヌーラボさんで利用していたKeyCDNは当時調査していたときSNI Custom SSLしか提供しておらず要件を満たさず)。 余談ですがCDN77は結構込み入った技術的な質問にも1時間以内で返信してきて、 サポート体制が素晴らしかったのも選定要因になりました。

CDNの冗長構成を構築したんですが、幸か不幸か、CloudFrontに障害が発生しなかったため、 予備系のCDN77が稼働することは無かった。

CDN第三世代 Akamai(2015年6月-)

  • CDNにAkamaiを利用
  • AkamaiはSLA100%なので利用することはないと思いますが高可用性構成のため利用することはほぼ無さそうですが、予備系としてそれまで稼働していたCloudFrontを残す(追記 2015年8月18日 誤解を招く表現なので修正しました)

CloudFront + CND77の冗長構成の懸念点

  • 検証としてCloudFrontをDisableにしたときには自動でCDN切り替わったが、CloudFrontが実際に障害になったときの挙動が検証不可のため、自動で切り替わるか確認出来ず
    • Route53のDNSフェイルオーバーに10〜20分程度要する(CloudFrontが完全に反応無くなるまでコンテンツが返ってくるためフェイルオーバーが実行されない)
  • CloudFrontの障害発生頻度として、年に1〜2回程度なので、そこで正常に冗長構成が稼働するか不安がある

Akamaiを選択した理由

  • 高可用性構成
  • 私を含めインフラのメンバー全員前職などでAkamaiを利用していたので、特徴などを把握している
  • 数年間Akamaiを利用した経験の中で障害無し
  • 担当営業の方の頑張り&ボリュームディスカウントがあり、スタートアップでも利用できる、財布に優しいコスト感

Akamai With ChatOps

ngs/hubot-cloudfront で、SlackからCloudFrontのInvalidateを実行していた部分を hubot-akamai-ccu を導入し、 SlackからAkamaiのキャッシュのInvalidateを実行出来るようにもした。


この手の話はあまり外に出すような話じゃないかと思うんですが、 Kaizen Platform, Inc.のエンジニア行動指針というのが、社内Qiita Teamにあって、 冒頭にCEO @sudokenのmessageが載っていて、 その中に

様々な国や地域で多くの人が前向きに協力したくなるようなオープンな組織や事業でいよう

というのがあり、この情報が役に立つ人達もいると思うので公開しました。 CDNの可用性はインフラエンジニア的にかなり頭の痛い問題だと思いますし、 参考になれば幸いです。

先日Hashicorp Product Meetupに 参加したときに、KAIZENのエンジニア行動指針を見たいとの意見を頂いたので、 その他の行動指針を一部公開すると下記のような感じになってます。

「Amazon Web Services パターン別構築・運用ガイド」が良かった

Amazon Web Services パターン別構築・運用ガイド 一番大切な知識と技術が身につく

発売日に買っていたんですが、多忙で感想を書くのを忘れていた。。

前職では業務でAWSをほぼ触らず、6年弱ずっとオンプレミス環境でインフラエンジニアをやっていたので、 昨年KAIZENへの転職を機にはじめてAWSをガッツリ触るようになった。(個人レベルではもちろん触ってましたが)

AWSを実際に触ってみると

  • 各サービスの特徴
  • それぞれのサービスを組み合わせた構成例
  • 各種設定方法

などについて、体系的に学べる書籍などが無く(あっても情報が古い)、 ウェブ上の断片的な情報をその都度参照して、 恐ろしく非効率な方法で習得して、苦労していたので、 本書は体系的にAWSのことが習得出来るので大変ありがたかった。

リファレンス的に利用出来るので、「この設定どうするんだろう」みたいな時に 役に立ってくれている。

紙書籍は450ページもあり、ちょっと持ち歩くのがツラそうだったので、 Kindle版を購入したんですが、ページが画像として処理されているので、 ページ送りが非常に遅く、また文字検索が出来ないのがちょっと残念な感じだったけど 非常にわかりやすく、内容的にはすばらしかった。

AWSはサービス開発のスピードが速く、新機能が増えたり、UIが変わったりと 変化が激しいので、1〜2年後には訳に立たなくなってしまうかもしれないが、 現時点(2015年5月)でAWSに関しての体系的な知識を習得するのにはオススメだと思う。

本書目次

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
Chapter1 AWSの基本
1-1 AWSとは
クラウドとは
物理サーバ(オンプレミス)とAWSの違い
レンタルサーバ(共有サーバ)とAWSの違い
プライベートクラウドとAWS
AWSのサービス全体像
1-2 AWSのネットワークサービス
リージョンとアベイラビリティゾーン
Virtual Private Cloud (VPC)
Route53
AWSネットワークとVPCネットワーク
1-3 コンピュータ基盤としてのAWS
Amazon Elastic Compute Cloud(EC2)
Amazon Elastic Block Store(EBS)
EC2におけるバックアップ
Amazon Simple Storage Service(Amazon S3)
Amazon Glacier
1-4 アプリケーション基盤としてのAWS
Relational Database Service(RDS)
Elastic Beanstalk
ElastiCache
1-5 サービスとしてのAWS
AWSのアプリケーションサービスの概念
SESとSQS
SNSとCloudWatch
1-6 AWS利用のコスト
AWSの料金体系
AWSの料金計算の仕方
Chapter2 AWSを利用する
2-1 AWS利用の準備
AWSアカウントの作成
ユーザアカウントの作成(IAM)
2-2 AWS CLI
AWS CLIのインストールと設定
AWS CLIの基本的な使用方法
2-3 AWS SDK
サポートされる言語とバージョン
AWS SDKのインストールと設定
AWS SDKの基本的な使用方法
2-4 VPCネットワークの作成
Default-VPC
Custom-VPCを作成する
2-5 仮想コンピュータ(Amazon EC2)の利用
AWS操作用の公開鍵・秘密鍵の作成(KeyPair)
Security Groupを作成する
EC2を起動する
AMIを作成する
ElasticIP(EIP)の利用
2-6 ELB(Elastic Load Balancer)を使用する
ELBのサービス詳細
ELBの作成
Chapter3 パターン別構築例
3-1 EC2を利用した動的サイトの構築
WordPressを使ったブログサイトの構築
ロードバランシングとHTTPSサイトの構築
Marketplacesを利用して、構築済みのインスタンスを利用する
3-2 Elastic Beanstalkによる動的サイトのサーバレス構築
Elastic Beanstalkを利用した再構築
Elastic Beanstalkを利用したロードバランシングとHTTPSサイトの構築
3-3 S3による静的サイトのサーバレス構築
S3による静的サイトの構築
Route53を利用してDNSを設定する
Route53へドメインの移管
CloudFrontとの連携
3-4 Auto Scalingによる自動スケーリングシステムの構築
Auto Scalingの設定
Auto Scalingを利用するためのアプリケーション構成
Auto Scaling使用時のEC2インスタンスの初期化処理
Immutable Infrastructure
3-5 Elastic BeanstalkとLambdaによるバッチサーバの構築
Elastic Beanstalkによるバッチサーバの冗長化構成
Lambdaによるサーバレスな処理システムの構築
3-6 CloudFormationによるテンプレートを利用した自動構築
CloudFormationの概要
CloudFormationによるネットワーク構築
CloudFormationによるサーバ構築
3-7 SESによるメール送信システムの構築
SESを使ってメールを送信する
EC2インスタンスにメールサーバを構築する
外部のメール送信サービスを利用する
3-8 AWS上に開発環境を構築する
開発環境の構築と運用
継続的インテグレーション(CI)を実施する
3-9 モバイルアプリからAWS上のリソースを利用する
Cognitoによるユーザ認証と2-tierアーキテクチャ
AWSのモバイル開発プラットフォーム
SNSによるモバイルプッシュ通知
Chapter4 AWSのセキュリティ
4-1 AWSのセキュリティへの取り組み
責任共有モデル
第三者認証
4-2 IAM(AWS Identity and Access Management)
AWSのアカウント種類
IAMユーザとIAMグループ
IAMロール
4-3 データ暗号化
AWSが提供するデータ暗号化サービス・機能
4-4 WAF・IDS・IPSによる外部からの攻撃対策
外部からの攻撃の種類と防御方法
エージェント型とリバースプロキシ型のサービス導入例
4-5 VPCでネットワークセキュリティを高める
VPCによるSubnet構成
SecurityGroupとNetworkACL
4-6 AWSと脆弱性診断
侵入(ペネトレーション)テスト
侵入(ペネトレーション)テストツール
Chapter5 管理と運用
5-1 ジョブ管理
ジョブ管理システムの概念
サービス型のジョブ管理システム
5-2 システムを監視する
AWSのなかから監視する
AWSの外から監視する
5-3 アラートを通知する
AWSの機能を利用した通知方法
Twilioを利用した電話通知
5-4 データをバックアップする
EBSのデータバックアップ
S3とGlacierを使ったバックアップと管理
AMIの運用方法
5-5 AWSにおけるログ管理
AWSのサービスログ/操作履歴のログを収集保存する
EC2インスタンスのログを収集保存する
5-6 AWSにおけるコスト管理
AWSにおけるコスト管理
AWSのコストを節約する
5-7 AWSの利用を支えるサポートの仕組み
AWSサポート
AWS Trusted Advisor

参考

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とも連携が出来るので引き続き検証中

参考