タグ: AWS

Route53へのDNSとドメインの移行

次のものを AWS に移行しました。

  • ドメイン移管(53ningen.com): ムームードメインから Route 53 へ
  • ドメインネームサーバー移行: ムームードメインから Route 53 へ

また、もとの運用では存在しなかった、次のようなものを導入しました。

  • L7レイヤーでのヘルスチェック
  • DNSフェイルオーバー

この資料は自分向けの作業ログであるため、実際には各ステップ冒頭に記された公式ドキュメントを理解した上で読むことを強く推奨します。

手元環境

 作業は基本的には terraform を使って行いました。ただし、ドメインの移管に関しては Route 53 のマネジメントコンソールとムームードメインのコントロールパネルを操作する必要があります。

1. DNS を Route 53 へ移行

 ドメインも Route 53 に移管しますが、その際に元のレジストラ(ムームードメイン)が提供するネームサーバーからドメインが削除されてしまうので、前もって DNS を Route 53 に切り替えておきます。

1.1. ホストゾーン(Hosted Zone)の作成

公式ドキュメント: 既存ドメインの DNS サービスを Amazon Route 53 に移行する

 ホストゾーンとはドメインに紐づくリソースレコードのセットです。おおよそゾーンファイルと対応していると考えて良いと思います。実際にゾーンファイルを取り込むこともできるようです(公式ドキュメント: ゾーンファイルをインポートしてリソースレコードセットを作成する)。

 ホストゾーンには、パブリックなものとVPC向けのプライベートなものがあります。マネジメントコンソールからドメイン名を入力すれば作成が完了しますが、今回はこのリソースを terraform で管理します。

terraform plan は以下のとおり

 terraform apply してホストゾーンを作成すると SOA レコードNS レコード も自動的に作成されます。今回はドメイン名とIPアドレスを紐づけるために A レコード の追加が必要になります。そのため、その記述を追加します。メールサーバーの移行が必要であれば MX レコード、サブドメインなどの運用をやっているのであれば CNAME レコード など適当な感じに必要なものも移行しておきましょう。ひとまず今回は A レコード のみを作ります(Route 53 が対応しているDNSリソースは サポートされる DNS リソースレコードタイプ を参照)。terraform apply を実行するとレコードが作成されます。

1.2. DNSの変更

 マネジメントコンソールの NS レコード欄の DNS サーバーを、ムームードメインのコントロールパネルで指定します。反映が有効になるまで少し時間がかかるため、少し待って dig で確認すると良いとおもいます。

1.3. コストの計算

公式ドキュメント: 料金

 お仕事ならこの計算作業する前にやるべきですが、個人のお遊びサーバーなので作業後に計算しました。

  • ホストゾーン
    • 0.50 USD(ホストゾーンごと)/月 – 最初の25のホストゾーン
    • 0.10 USD(ホストゾーンごと)/月 – それ以上のホストゾーン
  • 標準的クエリ
    • 0.400 USD(100 万クエリごと) – 最初の 10 億クエリ/月
    • 0.200 USD(100 万クエリごと) – 10 億クエリ以上/月

おおよそ 1ホストゾーン + 最初の10億クエリ = 0.50 + 0.40 = 0.90 USD

1.4. ヘルスチェックの設定 (Optional)

公式ドキュメント: Amazon Route 53 ヘルスチェックの作成と DNS フェイルオーバーの設定

 ヘルスチェック(L7)とDNSフェイルオーバーが利用できます。ヘルスチェックで障害を検知した場合に Cloudwatch Alarm と連携をさせたり、DNSフェイルオーバーを利用して待機系に参照を向けたりすることが可能です。

 ひとまずベーシックなウェブサーバーのヘルスチェックは以下のように設定できます。その他諸々 terraform を利用する際にオプション記述については terraform 公式ドキュメント: aws_route53_health_check を参照してください。

ヘルスチェックに関しては、

  • AWSエンドポイント
    • ヘルスチェック 1 件につき 0.50 USD*/月
    • オプション機能 1 件につき 1.00 USD/月
  • AWS以外のエンドポイント:
    • ヘルスチェック 1 件につき 0.75 USD*/月
    • オプション機能 1 件につき 2.00 USD/月
  • 任意のヘルスチェック機能は以下の通りです。
    • HTTPS
    • 文字列マッチング
    • 短インターバル
    • レイテンシー計測

となっています。

「AWS エンドポイント」とは、AWS の中で稼働するリソース(たとえば Amazon EC2 インスタンス)のうち、ヘルスチェックと同じ AWS アカウントの中でプロビジョニングされるか、ヘルスチェックと同じアカウントが請求先となっているものを指します。計算済みヘルスチェックとメトリクスベースのヘルスチェックは AWS エンドポイントのヘルスチェックとして請求されます。Elastic Load Balancing のリソースまたは Amazon S3 ウェブサイトバケットがエンドポイントであるヘルスチェックについては、お客様への請求は発生しません。Elastic Load Balancing のリソースおよび Amazon S3 ウェブサイトバケットをエンドポイントとするヘルスチェックについては、AWS によって自動的にプロビジョニングされ、Amazon Route 53 の一部として追加料金なしでご利用いただけます。

1.5 DNSフェイルオーバーの設定 (Optional)

公式ドキュメント: DNS フェイルオーバーの設定
terraform 公式ドキュメント: aws_route53_record

 ヘルスチェックを入れたついでに、障害発生時に S3 の静的ホスティング機能 + Cloudfront によるメンテナンスページのほうへ参照を向けるようなDNSフェイルオーバー設定を入れてみます。DNSフェイルオーバー設定については無料で利用することができます。最終的な構成図は以下のような形になります。


 
 ディザスタリカバリを想定した構成として、ap-northeast-1 リージョンで稼働させるアプリケーションサーバーに対して、メンテナンスページを静的ホスティングする際の S3 リージョンは地理・物理的に違う系統の適当なリージョンを選択します。今回は us-east-1 を選択しました。

 S3 の前段に置いた Cloudfront は主に S3 からの配信をキャッシュする役割と、メンテナンスを表すステータスコード 503 でリソースを返す役割を持っています。S3 バケットの作成とファイルの配置、静的ホスティング機能の有効化および Cloudfront の設定は以下のように terraform で記述することができます。

terraform 公式ドキュメント: aws_s3_bucket
terraform 公式ドキュメント: aws_cloudfront_distribution

resources/error には、適当なメンテナンス表示 html ファイルを、 policies/maintenance.53ningen.com_s3_policy.json には以下のようにバケットのファイルの読み取りを許可するポリシーを配置します。

つづいて Route 53 ホストゾーンにフェイルオーバーの設定をします。通常時は既存の A レコードが有効になるようにしつつ、ヘルスチェックに失敗した場合にメンテナンスページを静的にホスティングしている S3 のほうに参照を向けるような設定を入れます。また ttl を最初の設定より短く 60 秒に変更します。 terraform を用いて次のように記述できます。

 最後に動作確認として、動いているウェブサーバーを停止し、きちんとメンテナンス表示に切り替わるか確認します。またウェブサーバーを起動したときに、ヘルスチェックが通るようになり、きちんとアプリケーションサーバーに参照が戻るかも合わせてチェックしておきましょう。

2. ドメインを Route 53 に移管する

公式ドキュメント: ドメインの移管

ムームードメインで購入した 53ningen.com ドメインを Route 53 に移管します。ステップとしては以下のとおりです。

  1. WHOIS 情報としてレジストラの情報を代理公開している場合は、ムームードメインのコントロールパネルから自分のものに変更する
  2. 確認のメールが飛んでくるので踏む
  3. AUTH_CODE をメモ
  4. Route 53 の Domain registration から Transfer Domain to Route 53 に進みドメイン名を入力
  5. AUTH_CODE を入力
  6. 移管後のDNSとして先ほど作った Route 53 の Hosted Zone を指定する
  7. AWSから移管確認のメールが飛んでくるので踏む
  8. そのうち移管が完了する

Waiting for the current registrar to complete the transfer (step 7 of 14)
ドメインが移管の要件を満たしているか現在のレジストラが確認しています。このステップは、ドメインの TLD に応じて最大 10 日かかる場合があります。

結構待ったりいろんな確認メールのリンクを踏んだりする必要がありますが、あまりテクニカルな手順はないはず…。

ES2015+Flowなlambda関数をApexで管理する

ES2015 + 型チェッカー flow で書かれた AWS Lambda 関数を Apex で管理する方法について、つらつらとメモ。この記事は @nagisio 先生のご指導のおかげで成立しています(謝辞)。

  • キーワード
    • AWS Lambda
    • yarn
    • ES2015
    • flow
    • Apex

記事読むの面倒くさいので、動くリポジトリよこせという方はここをcloneすべし(動かしてから理解する方が楽なのですよねー :wakaru:)

ES2015 + flow + Apex の環境構築

yarn の導入

導入はかんたん。

  1. npm initpackage.json を作る
  2. npm install yarn --dev で yarn を導入する
    • global に入れたい方はどうぞ

package.json はきっとこんな感じになっているのではなかろうか

ESS2015 + flow の環境構築

まずは必要なものを片っ端からいれていく

次に .babelrc を次のようにする

node_modules/flow-bin/cli.js init でflow の設定ファイル .flowconfig を作り、以下のような感じにする

もう多分この時点で ES2015 + flow のコードが書けるので適当に src/hello/index.js に適当なコードを書いてみよう

続いてトランスパイルして functions 下に成果物を出力してみよう

成果物は次のようになっているだろう

良い感じにハローワークに行きたいくなる良いラムダ関数ですね。さて、ここまできたらあとは Apex を導入して AWS にデプロイするだけです。

ちょっとその前に、トランスパイルするコマンドが長ったらしくてだるいのでエイリアスを張っておきましょう。package.json の script の部分をちょちょいといじるといい感じに npm run build で諸々実行できます。

Apex の導入

今回 AWS Lambda 関数の管理には Apex をつかいます。Apexの挙動は非常に単純で project.json に指定されたリソースやタイムアウト時間、IAMロールの設定で、functions直下にある各ディレクトリをそれぞれラムダ関数とみなし、デプロイしてくれます。

導入はかんたん

project.json をイカのよう設定すればよいでゲソ(各自IAMロールは適切なものを指定してください)

apex deploy でデプロイできます。apex invoke hello で実行できます。

良い

ESLint の導入(お好みで)

ESLintを入れたい方は適当に必要そうなやつをどうぞ(適当)

.eslint を適当に書く

deploy 前に uglify の処理を入れる

lambda の起動時間は多分デプロイされる成果物のサイズが小さい方がはやいので、uglifyをかけたほうがよさそう。packaage.jsonを書き換えればいい感じに実現可。

npm run build:prod で functions 下にできる成果物を確認してみるとちゃんとできてるか確認出来る。

ステージ管理

このあたりの対応が一番筋がよさそう👉 Lambda with Apex: 環境変数で環境別にLambda環境を整える

おわりに

ES2015 + flow + Apex で快適な AWS Lambda ライフを!

terraform を使ったAWS構成管理 ハンズオン

terrafrom は、インフラの構築や設定などをコードで表現して管理できるようにするツールです。AWS や Azure、 Heroku など様々な環境に対応しています。

この資料はラビットハウス社内で開催される、 AWS リソースを terrform で管理するためのハンズオン向けに作成した資料になります。AWS 構成管理をコードで管理したいなどと思っている方のなかにも、こういったツールが面倒臭そうだとか、すぐ使えなくなってしまいそうだとお思いの方が多いかと思いますが、 terraform の挙動はとてもシンプルで学習コストはものすごい低いツールです。また AWS 構成をコード化することでより深く AWS について理解することできる側面もあると考えています。

是非この機会に terraform に入門してみませんか…? この記事の通りにコマンドを入力していけば、きっとあなたも1時間もしないうちに terraform を使いこなせるようになっているでしょう。

1. 環境構築

このハンズオンでは terraform v0.7.4 を前提として話を進めます

Mac の場合

Windows の場合

https://www.terraform.io/downloads.html

AWS 側の準備

あらかじめterraformで用いるIAMユーザーを作成しておきましょう

  1. IAM ユーザー管理ページにアクセス
  2. 新規ユーザーの作成
  3. 必要なポリシーのアタッチ
  4. access_key, secret_key の作成

2. S3 bucket を管理する

まずは S3 bucket を作ったり変更したり壊したりして遊んでみましょう。下準備として、適当な作業用ディレクトリを作成してください。次に AWS リソースにアクセスするための設定を書きます。

2-1. S3 bucket を作る

早速 S3 bucket を作ってみましょう。次のようなファイルを作成してください。ただし bucket の名称はグローバルで一意になるように定めてください。

以上のようなファイルを作ったら、terraform validate で正しい .tf ファイルを記述できているかを確認してみましょう。きっと上記の通りに書けば問題なくコマンドが通ると思います。

つづいて terraform plan コマンドで、これからどのようなことが実行されるのかを確認します。この操作は常に安全で、AWSに対して情報の読みとり操作しか行われません。

+ aws_s3_bucket.terraform_tutorial とあるように S3 の bucket が作成されることが確認出来たので terraform apply コマンドで実際に実行してみましょう。

無事、成功したようですので、とりあえず aws cli から s3 bucket が本当に存在するのか確認してみましょう。

ちゃんと s3.tf ファイルで指定した com.github.53ningen.terraform.tutorial という名前の bucket ができていることがわかります。さて、terraform apply が無事に成功したあとには terraform.tfstate というファイルができていると思います。

このファイルの中身はリモート(今の場合AWS)の状態を保存するファイルになります。この中にはアクセスキーやシークレットキーがふくまれているため、git 管理対象外にしておきましょう。このファイルの管理についてはのちほど 「remote state の管理」の節でご説明します。とりあえず以下のような .gitignore ファイルを追加しておきましょう。

2-2. S3 bucket の状態を変更する

さきほど作った S3 bucket はバージョニングが有効になっていますが、これを無効にしてみましょう。s3.tf を次のように修正します。

続いて terraform validate コマンドで tf ファイルのシンタックスを検証し、 terraform plan で AWS リソースに対してどうのような変更が行われるか確認しましょう。

Plan: 0 to add, 1 to change, 0 to destroy. とあるので、既存の S3 は削除されず、表示されたパラメータのみが変更されることがわかります。確認をしたら apply をすれば S3 の状態の変更は完了です。

2-3. S3 bucket を破棄する

さて、いままでチュートリアルとして S3 bucket を作成してきましたが、不要なので削除しておきましょう。terraform destroy コマンドを使えば OK ですが、この操作もやはり実行する前に確認しておきたいものです。そんな場合はまず terraform plan --destroy を実行してみましょう。これで terraform destroy 時の実行計画を見ることができます。

実行計画に問題がなさそうであれば、terraform destroy を実行してみましょう。

terraform destroy を実行すると本当にリソースを削除して良いのか聞かれます。yes と入力すると、ここまでに作った S3 bucket は削除されます。

2-4. tf ファイルをフォーマットする

terrform fmt でファイルをフォーマットできます

2-5. terraform 基本コマンドのまとめ

以上で terraform の基本的な 5 コマンドは理解できたかと思います。まとめると以下のようになります。

  • terraform validate: .tf ファイルのシンタックスを検証する
  • terraform plan: terraform がこれから行う実行計画を表示する。--destroy オプションで destroy 時の実行計画を表示できる。
  • terraform apply: plan を実行する。
  • terraform destroy: terraform で作ったリソースを破棄する
  • terraform fmt: tfファイルをフォーマットする

基本的には apply の前にかならず plan で実行計画を確認することを徹底してください。 destroy は実際にはほとんど使うことはないと思います。また、terraform.tfstate を git で管理したり、他人の目に触れるような状態にすることをお忘れなく。

3. remote state を管理する

terraform.tfstate ファイルはリモートの状態を管理するファイルです。apply が成功すると、どのようなリソースがどのようなパラメータで作成されたのかを細かく記録しています。

tfstate ファイルを誤って削除すると terraform はリモートにリソースが存在しないと認識して、tf ファイルに定義された構成を新規作成しようとしてしまいます。しがって何らかの形で、このファイルを管理する必要があるのですが、秘匿情報が多分に含まれているため単純に git で管理するわけにはいきません。

管理する方法は何通りかあるのですが、ここでは private な S3 bucket を使ってこのファイルを管理する方法をご紹介します。

3-1. tfsate管理用 S3 bucket の作成

S3 bucket の作成は前節でやったのでもうきっと理解できていると思います。復習がてらやってみましょう。remote_state.tf という名前で次のようなファイルを作ってみましょう。

terraform plan で実行計画を確認したのち、terraform apply で bucket を作成します。terraform 公式ドキュメントによると versioning を有効にすることが推奨されています。

3-2. tfstate管理設定を行う

無事 S3 bucket が作成されたら terraform remote config コマンドを使って tfstate ファイルの管理設定を行います。次のコマンドの bucketaccess_key などは自分のものに適宜変更してください。

ここで key というのは S3 上でどのような名前で tfstate ファイルを管理するかという指定になります。今コマンドが無事通るとカレントディレクトリにあった terraform.tfstate はきっと .terraform 下に移動するかと思います。

3-3. remote に tfstate を push する

さて、管理設定が無事おわったら S3 に tfstate ファイルを転送しておきましょう。

リモートへの terraform apply を行った場合は必ず terraform remote push を行いましょう。

3-4. remote から tfstate を pull する

普通にいかのような感じになります。複数人での開発で、他人が apply したあとの remote state を反映させたい場合などに使います。

4. より高度なリソース定義を行う

4-1. 変数を用いる

aws の access_keysecret_keyvariable.tf に直接書き込んでいますが、変数という機能を使えば、実行時に指定することができます。

このようにした上で、terraform plan を実行すると各パラメータとしてどの値をとるかを対話式に尋ねられます。

また、次のように変数のデフォルト値を指定しておくこともできます。

4-2. 環境変数を用いる

CLIから access_keysecret_key を毎回指定するのも面倒なので、環境変数を用いると楽そうです。terraform では TF_VAR_ というプレフィックスがついた環境変数を .tf ファイルの中で用いることができます。さっそく、これを用いて access_key, secret_key を環境変数から取ってくるように変更しましょう。

続いて variable.tf を以下のように変更しましょう

terraform plan を変数指定なしで利用できるようになっていれば、無事環境変数の利用ができているということになります。

4-3. 依存管理のあるリソース定義を行う

より複雑なリソースを構成するときには、リソース同士に依存関係が生じます。たとえば terraform で作成した IAM ユーザーにポリシーをアタッチしたいときに、リソース間に依存が生じていると思います。

いま、 IAM ユーザー cocoa さんを作成し IAMReadOnlyAccess ポリシーをアタッチしたいとします。その場合の .tf ファイルは以下のように記述すればOKです。

terraform plan を実行すると依存関係が解決されていることがわかるでしょう。

4-4. 設定ファイルを使う

複雑なリソースを管理するときには設定だけをまとめた設定ファイルが使えると便利そうです。 terraform には設定ファイルを使う仕組みも備わっています。今回は AWS のリージョン指定を設定ファイルに切り出しましょう。variable.tfregion 変数から default 値を削除してください。

そして config.tfvars という名前で次のように設定を記述しましょう。

あとは terraform planterraform apply 時に設定ファイルを指定してあげればOKです。設定ファイルの指定は -var-file= オプションを使います。

4-5. 出力を行う

terrform apply 後に作成されたリソースのARNが知りたい場合などは output という機能を使うとよいでしょう。たとえば先ほど作成した cocoa ユーザーのARNを出力させるには次のようにすれば OK です。

terraform plan, terraform apply を実行してみましょう

しっかりと ARN が出力されていることが確認できます。

5. モジュールと複数のステージへの対応

terraform はカレントディレクトリに置かれている .tf ファイルを実行するというとても単純なふるまいを持っています。しかし複数ディレクトリに構造化してファイルを保存したい場合や、複数のステージを作るためにパラメータだけ変えて呼び出したいなどさまざまに理由により、異なるディレクトリ下にあるものを呼び出したいことがあるでしょう。そのときに使えるのが、モジュールという機能です。

5-1. モジュールの利用の基礎

モジュールを試すためにまずは以下のようなディレクトリ構造を作りましょう。

modules に それぞれのリソースを定義していくことになります。今回はサンプルとして dev/prod 向きそれぞれの S3 bucket を作ってみましょう。まずは modules/s3/s3.tf の中身から。

続いて dev/modules.tf, prod/modules.tf というファイルにそれぞれ、modules/s3 以下のファイルを取り込んで実行するコードを書いてみましょう。modules という新たな構文を利用します。

最後に、dev/variable.tf, prod/variable.tf に対して、AWS を操作する設定値などを記述します。

これで準備が整いました。dev ディレクトリ下から実行すると dev 環境向けの構成、prod ディレクトリ下から実行すると prod 環境向けの構成を管理することができます。 dev 環境向けのリソースを実際に作ってみましょう。 dev ディレクトリに移動して、terraform get を実行して依存モジュールのコードを取り込みを前もってやっておく以外は、いままでと基本的には同じ操作で OK です。

5-2. 複数ステージへモジュールを用いたの対応例

このようなモジュールの機能を用いて dev や production など複数のステージ向けにデプロイできるように更生する場合、ディレクトリ構造として特に決まっているものはないのですが、優れたものとして以下のような形があるので、参考にしながら進めると良いと思います。

6. 既存のAWSリソースを terraform で管理する

6-1. terraforming の導入

terraforming は既存のAWSリソースにアクセスしてterraformのコードを生成してくれたり、tfstateを生成してくれたりするツールです。導入は Gemfile に次のように書いて、bundle install すればOKです。

6-2. 既存の IAM user を terraform で管理する

AWSアカウントを持っているほぼ全ての人は、すでに IAM user などのリソースを持っていると思います。従って、まずここを terraform で管理する形にしましょう。次のようにすると現在のIAM userリソースに応じたHCLが出力されます。

これをファイルに書き出しましょう。

またリモートの状態を手元の .tfstate ファイルに反映させるなければ、terraform はリソースを新規に作成しようとしてしまいます。そのために以下のようにしておきましょう。

terraforming iamu --tfstate --profile default --merge=.terraform/terraform.tfstate

出力をみて問題なさそうであれば、このコマンドに --overwrite オプションを付加して反映させます。こののちに terraform plan をして差分がでなければ、晴れて IAM user の管理を terraform に移行できたことになります。

terraform plan 時にもしも、 destroy されるリソースが表示されたとしたら、既存のリソースやシステムが破壊される可能性がありますので、特に慎重に操作してください。また、IAM policy などについては JSON の改行位置やインデントなどが差分として出やすいので、悩んだときはそのあたりが既存のポリシー設定と食い違っていないか確認することをお勧めします。

さて、terraforming はよく使われるほとんどの AWS リソースに対応しているため、まずはこれを使ってできるところまで terraform に移行すると良いでしょう。v0.7.0 では以下のようなものに対応しています。

6-3. terraform のコードを管理するリポジトリを作成する

個人アカウントのaws構成をopenなgithub repositoryに配置するのは、はばかられるので code commit リポジトリを作成しておくと良いでしょう。

code commit 上に作成したレポジトリにアクセスするためポリシーのアタッチ、ならびに公開鍵登録も terraform を使って行うことができます。

この状態で terraform plan, terraform apply をしてみます

すると以上のように作成された ssh_public_key_id が出力されるので、あとはこいつを ~/.ssh/config に反映させれば手元のマシンから作成した code commit レポジトリに疎通がとれるようになります。

6-4. terraform import

T.B.D

7. 構成管理方法の整理

7-1. 個人開発の場合

個人のAWSリソースを管理する場合は大きく分けて次の2つの方法があるかと思います

  • .tfstate ごと git で管理して、 code commit にぶちこむ
  • .tfstate は S3 で管理、コードは code commit で管理

7-2. チーム開発の場合

  • .tfstate はセキュリティ上の理由から S3 で管理することが望ましい
  • .tfstate やアクセスキーなどを含むものをコミットせず、GitHub Enterprise, code commit, GitHub private repository に push する

複数環境に対応する terraform のディレクトリ構成と tfstate の管理

terraform はディレクトリ内のすべての tf ファイルを実行対象とするので、環境ごとに変数を変えるなどの際には module という機能を使うと良い。このときのディレクトリ構成は terraform が公式でこれというものは定めていないので各々やっていく必要があるが、よさそうな構成は以下の2つの記事の内容だった。

後者のほうがよりシンプルで個人的には好き。さて、これらのディレクトリ構成をとった場合、 tfstate はそれぞれの環境ごとに作成される。この管理をどうするかという問題が発生する。

基本的には単純に terraform remote config コマンドをそれぞれのディレクトリに入った瞬間叩くという運用になるかと思いますが、ちとダルいので以下のようなシェルスクリプトを書くと良さげ。

それぞれ dev から実行すれば dev/terraform.tfstate を、 prod から実行すれば prod/terraform.tfstate を remote state として取り扱えるようになる。

その他

multiple provider 機能も使わねばならんかったのでリンクだけ貼っておく

terraformingを試す

AWSの管理にterraformを導入したいけれど、既存のリソースはもうすでに存在しちゃっているということは、まあよくあると思います。手で tf ファイルと tfstate ファイルをいじればなんとかやってやれないことはないですが、幸いなことにこれを支援してくれるツールが存在します。それが terraforming です。

terrraforming の導入

terraforming を取ってくる Gemfile 書いて bundle install すれば、おk。

terraforming の使い方

とても簡単。bundle exec terraforming [service_name] --profile=[$PROFILE]で既存のawsの構成通りのtfファイルのコードを生成してくれます。以下のような具合。

これを tf ファイルに追記すればよいのですが、 tfstate にこれらのリソースがあることが記されていないため、このまま plan, apply をすると既存のものを無視して構築を始めてしまいます。これを防ぐためには tfstate を適切に更新して、 plan で差分が出ない状況に持っていく必要があります。そこで terraforming iam --profile default --tfstate --merge=./terraform.tfstate とすると既存の tfstate に既存のAWSインフラの state を追記してもらえます。こわければ tfstate の backup を取っておいたほうが良いかと思います。

とても良いですねー。

terraformを試す

terraformのチュートリアルを見ながら、いろいろ試してみた記録その1。結構使い勝手はよさそうなので、こういうツールでちゃんとAWSのリソースを管理していきたい。

terraform の導入

導入は brew install terraform で OK

EC2インスタンスを立てる, 更新する, 破棄する

とりあえず簡単なところから。以下のファイルを example.tf という名前で作成する。

で、 terraform plan を実行するとこれからAWSに対して何を行うのかを表示してくれる。なにもないまっさらな状態であれば以下のような出力になるだろう。

terraform apply を実行すると、実際にリソースが作成される。さっきの example.tf を編集してたとえば t1.micro にして、 terraform plan をするとちゃんと instance_type に差分がでる旨の表示が出る。スタックの削除は terraform destroy で行ける。

リソースの依存性を扱う

以下のように、Elastic IPを設定する。Elastic IPに対するパラメタは instance しかない。そこには ${aws_instance.example.id} とあるがこれは、 EC2 インスタンスのidが埋め込まれる変数の役割を持つ。

もうすでに EC2 インスタンスは立ち上がっており、 aws_eip の部分だけ追記をして terraform plan を実行すると以下のようになり、この挙動がわかりやすい。

プロビジョニング

以下のように provisioner 内の command を設定することによりプロビジョニングを行える

まっさらな状態でこれを実行すると、file.txtがちゃんと生成される

変数

variables.tf なるファイルを作る

そして、example.tf の provider を以下のように変えてみよう

variables.tf で定義してある region についての挙動はもうおわかりだろう。問題は access_keysecret_key であるが、これは default が設定されていないので apply 時に渡す。たとえば terraform apply -var 'access_key=...' -var 'secret_key=...' のような具合だ。

また conf ファイルから読み込みたければ、たとえば dev.tfvars という名前で以下のようなファイルを作成し terraform apply -var-file ./dev.tfvars を実行すれば良い。

環境変数からの呼び出しは TF_VAR_access_key などという名前をつければいける。

出力

terraform apply を実行した結果のうち、重要な値の出力を得たい場合は以下のような形のコードを書けばよい

すると apply 時に以下のような出力が得られる

またapply後に出力だけ得たい場合は terraform output ip などとすれば良い。

管理ポリシーとインラインポリシーの違い

参考: http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html

管理ポリシー

  • AWS管理ポリシーとカスタマー管理ポリシーに分かれる
  • AWS管理ポリシーはよく見る 〜〜〜FullAccess とかそういうやつ
  • カスタマー管理ポリシーはそれを自分で作れる模様
  • 複数のユーザー/グループ/ロール(この3つを合わせてプリンシパルエンティティというらしい)にアタッチできるという特徴がある
  • ロールバックできる
  • バージョン管理してくれる
  • IAM内のARNを持つスタンドアロンな存在

インラインポリシー

  • 単一のユーザー/グループ/ロールにしかアタッチできない

インラインポリシーは、ポリシーとそれが適用されているプリンシパルエンティティとの厳密な 1 対 1 の関係を維持する必要がある場合に便利です。たとえば、ポリシー内のアクセス権限が意図したプリンシパルエンティティ以外のエンティティに間違って割り当てられないようにする必要がある場合などです。インラインポリシーを使用すると、ポリシーのアクセス権限が間違ったプリンシパルエンティティにアタッチされることはありません。また、AWS マネジメントコンソールを使用してプリンシパルエンティティを削除すると、プリンシパルエンティティに埋め込まれたポリシーもその一部として削除されます。

バージョン管理・ロールバック、強さあるし、カスタマー管理ポリシー強い

AWS SDK for Node.jsを用いたSQSの操作

AWS Lambda を使ってお手軽に SQS を操作するために、普段はあまり使わないが Node.js 経由で試してみることにした。本当はJavaのほうが慣れているし、好きなのですがいかんせん Lambda にいちいち jar をアップロードするのは非常に厳しい気持ちになるので、まあたまには…。

自分のためのメモ書きなので、各位はドキュメントを見るべきだと思います
http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SQS.html

SQS へのメッセージの送信

SQS メッセージの受信

SQS 受信メッセージの削除

Node.js 書くのかったるい…

AWS Lambda を用いた Amazon SNS のエンドポイント整理

 Amazon SNS の Application に紐付いているエンドポイントには Enabled という Attribute がついています。文字どおり、有効なエンドポイントかどうかを表すものです。Amazon SNS は賢いので APNSGCM からのフィードバックを受けて、プッシュトークンが無効になった場合に自動的に false にしてくれます。しかし、基本的には Enabledfalse になったエンドポイントは不要です。したがって、これらを自動的に削除するような仕組みがあったほうがよさそうです。そこで、この記事では AWS Lambda を用いて、それを実現する方法について説明します。

AWS Lambda で動かすスクリプト

 コード自体は非常に簡単で以下のような形です。AWS Lambda Function を素早く立ち上げるとしたら本来は pythonnode.js のほうが良いかと思いますが、今回の作りたいものに関してはそれほど即時性を求められるようなものではないと思うので、好きな言語(もちろん Lambda でうごくもの)で問題ないと思います。

 json4s とか typesafe config とか scala logging とか使ってます。よい塩梅に jar に固めて、 Lambda Function を作って、アップロードしてください。これで AWS Lambda 側の準備は完了です。

Amazon SNS 側の連携設定

Amazon SNS側の作業は次の2点になります。

  1. 先ほど作った AWS Lambda Function の実行をフックさせるためトピックを作成し、購読(Subscribe)させる
  2. エンドポイントの整理をしたい対象の Application の持つエンドポイントの状態変化をフックして、トピックに通知を送るように設定する

それぞれについて見ていきましょう。

トピックおよび、サブスクリプションの作成

 トピックの作成は通常どおり普通にやってあげれば大丈夫です。とりあえず適当に「endpoint-updated-topic」とでも名前をつけておきましょう。続いて作成したトピックを先ほど作成した Lambda Function に購読させましょう。以下のような形で Protocol で AWS Lambda を選択すれば Endpoint のプルダウンリストに先ほど作成した Lambda Function の ARN がでてくるでしょう。

スクリーンショット 2016-05-26 0.41.37

Application のイベント設定

 最後に Amazon SNS の Application に紐づくエンドポイントの Attributes が変化したイベントをトピックに通知させるように設定します。 Application 一覧の画面で設定対象のアイテムを選択し Actions から configure events を選択してください。

スクリーンショット 2016-05-26 0.46.00

 そして、次に表示されるダイアログの Endpoint Updated の項目に、先ほどつくったトピックの ARN を入力すれば、すべての作業は完了です。

スクリーンショット 2016-05-26 0.48.25

動作確認テスト

 設定が終わったら適当に Application へ Endpoint を追加してみて、Edit Endpoint Attributes から Enable を false にしてみてください。きっと自動的にエンドポイントが削除されるはずです。

スクリーンショット 2016-05-26 0.50.55

 Application エンドポイントの Attribute 変更以外にも、作成イベント、削除イベントなどをフックすることができるので、やり方次第では様々な連携を AWS Lambda を用いて行うことができると思います。

無効になったSNSのエンドポイントを削除してくれる AWS Lambda コードを書いた

無効になったSNSのエンドポイント、別に放っておいてもよいのですが、定期的にお掃除したほうがよさそうだったので、お掃除用のAWS Lambdaコードを書きました。Amazon SNSは、アプリケーション(SNSのデバイストークンが登録できるやつ)に紐付いているエンドポイントの状態が変化したときに通知してくれる機能があります。その状態変化通知を受け取るトピックを適当に作っておいて、AWS Lambda コードがそいつを購読するようにしてあげればよいことになります。

ソースコード