2013年4月7日日曜日

吉田さんインタビュー :CDPをもっと広げる取り組み [[JAWS DAYS 2013 Arakiroom]] #jawsug

2013年春、東京ビッグサイトへ集結せよ!という掛け声で、3月の15日、16日の二日間アマゾンウェブサービスのユーザグループであるJAWS-US (Japan AWS User Group)が全国から一同に会してユーザカンファレンスを行いました。当日のタイムスケジュール、資料、動画はこちらから参照できます。

荒木が進行した「荒木の部屋・AWSサポート出張所(松井の部屋)」についてはUstream中継の記録がいつでもご覧いただけます。本記事はそこでの会話内容、プレゼンテーション内容を元にしています。一連の記事はこちらで順次追加公開していきます。

2012年の秋に行われたAWSサミット東京で人生が変わった吉田さんの登場です。



広く活動されている吉田さんですが、CDPが現在、トップノッチの方のみに使われているだけで「みんなのCDPになっていない」ことが気になっているそうです。そこで中間層にリーチするための方法を面白おかしくCDPまわりに関わる人を増やすための取り組みを解説していただきました。

 

吉田さんはMilesと会って「大陸横断パターン」をお願いしたそうです。→そしてすぐに実行にうつされました。

この時間はYoutubeでもご覧いただけます。(USTより音はこちらのほうがいいかも)

松井さんインタビュー:AWSサポートと松井の部屋 [[JAWS DAYS 2013 Araki room]] #jawsug

2013年春、東京ビッグサイトへ集結せよ!という掛け声で、3月の15日、16日の二日間アマゾンウェブサービスのユーザグループであるJAWS-US (Japan AWS User Group)が全国から一同に会してユーザカンファレンスを行いました。当日のタイムスケジュール、資料、動画はこちらから参照できます。

荒木が進行した「荒木の部屋・AWSサポート出張所(松井の部屋)」についてはUstream中継の記録がいつでもご覧いただけます。本記事はそこでの会話内容、プレゼンテーション内容を元にしています。一連の記事はこちらで順次追加公開していきます。

今回は直前までどうしようか超考えた末、荒木はライトニングトーク&インタビュースペシャル、松井さんはAWSサポート出張所というのをJAWS-UGイベントでやることにしました。気がつけばこんなPOPをつくられ「やるしか無い!」「やったるで」という気持ちで迎えた当日でした。ちなみにPOPは当日のお昼に到着したので、私はPOPを見たのは荒木の部屋が終わってからでした。



先ずトップバッターとしてAWSサポートの重鎮であり、JAWS−UGでも初期から活躍している松井さん(blogも公開中)にお話を伺いました。今回の松井の部屋はサポートが表にでることによって、皆様からの生のフィードバックを得るためだそうです。



AWSサポートでは、チャットのサポートが始まりましたが、テキストベースでの結果を貼れるところがとてもいいところだそうです。

  • 即答できそうにない問題はWebベースでの質問を!
  • 困ったときのケースオープンはinstance-id, ELB名などを。急いでいる時ほど忘れずに!

松井さんの出ている場所はYoutubeでもご覧いただけます。

2013年1月8日火曜日

cdn.debian.net と ftp.jp.debian.org の動作に問題があればgithubにおねがい します。

Debianにおけるパッケージ流通はaptが基本的なものになっている。いまどき完全なスタンドアローンで動作しているような例もすくないので、なにかしらaptの御世話になっていることは多いかと思う。

昔のaptの実装ではhttp redirectができないので、http redirectに頼らない誘導方法になっている(現在のaptの実装ではhttp redirectができるので、http.debian.netというサービスが誕生している)。

check_serverの実装自体はRails3.2です。

動作チェック、文句、要望について

以下、内部の説明。

DNSサーバは dns.s.araki.net という名前で、dns_balanceが動作しています。

  • どのDNSを使うかはレイテンシベースのルーティングで3リージョンから選択している。
  • DNSであるdns_balanceは定期的にcheck_serverに対して最新のサーバ生死情報をELBのURL ( http://cdncheck1.araki.net/status/alive )に対してとりにいく。
  • 入手はJSONが使われる。この取得のためのプログラムは gae-surrogate.rbという名前

チェックサーバは、

  • チェック対象である世界中のDebianミラー200台をSQSに順次登録する。
  • チェックサーバの動作は http://cdncheck1.araki.net/view/index で確認できる。

チェックするためのコードはcheck-receive-forward.rbというファイル。

  • SQSからチェック対象ホストを1つ抜き出す。
  • チェックは対象ホストの http://対象サーバのアドレス/debian/project/trace/ftp-master.debian.org を確認し、最終ミラー時刻が8日以内であることを確認する。不達であったり遅延が大きい場合には"alive=0"として登録される。
  • チェック終了したらSQSから消す。
  • チェック結果はSimpleDBに登録

    地理情報の話やAS情報の話は又の機会に。

       

      2013年1月5日土曜日

      NEC IX2105でAmazon VPCにVPN接続する

      UNIVERGE IX2000/IX3000シリーズ : UNIVERGE IX2105 | NECをお借りしたので、VPCに対してVPN接続してみた。

      結果から言うと

      • あっさりつながる
      • 小さい
      • (ふんでも)壊れにくそう
      • (消費電力が小さいので)熱くならない。静か。

      というのは間違いなさそう。十分に速い線がないので、パフォーマンスについては言及できません。






       

      準備として、VPCをつくって、Customerゲートウェイを作成するまでをAWSのマネージメントコンソールで行います。

      1. AWS Management ConsoleのVPCページを開ける
      2. ”Start VPC Wizard”ボタンを押して作成開始
      3. “VPC with a Private Subnet Only and Hardware VPN Access”シナリオを選択
      4. IX2105につけるIPアドレスをいれる
      5. “Use dynamic routing (requires BGP)”を選択してVPCを作成
      6. VPN CONNECTIONS->VPN Connectionsから、作成されたVPN接続の設 定ファイルをダウンロードする。ベンダのところには対応していないのでGenericを入手する。

      すると、以下のようなファイルが入手できているはず。とりあえず、vpn-ix2105.txtとでもしておきます。


      Amazon Web Services
      Virtual Private Cloud

      VPN Connection Configuration
      ================================================================================
      AWS utilizes unique identifiers to manipulate the configuration of
      a VPN Connection. Each VPN Connection is assigned a VPN Connection Identifier
      and is associated with two other identifiers, namely the
      Customer Gateway Identifier and the Virtual Private Gateway Identifier.

      (以下続く)

      ファイルをひとつひとつ見てもいいのですが、さきに入れるべき情報を整理します。

      IPSecで使う鍵の入手


      $ grep '\-\ Pre-Shared Key' vpn-ix2105.txt
      - Pre-Shared Key : トンネル1の鍵
      - Pre-Shared Key : トンネル2の鍵

      設定に必要なAWS側のIPアドレスの入手


      $ grep "\-\ Virtual\ Private\ Gateway" vpn-ix2105.txt
      - Virtual Private Gateway : 27.0.1.16
      - Virtual Private Gateway : 169.254.252.25/30
      - Virtual Private Gateway : 27.0.1.144
      - Virtual Private Gateway : 169.254.252.29/30

      $ grep "\-\ Customer\ Gateway" vpn-ix2105.txt
      - Customer Gateway : IX2105につけるIPアドレス
      - Customer Gateway : 169.254.252.26/30
      - Customer Gateway ASN : 65000
      - Customer Gateway : IX2105につけるIPアドレス
      - Customer Gateway : 169.254.252.30/30
      - Customer Gateway ASN : 65000

      ここまで整理したら、IX2105にシリアルコンソールを挿して設定です。

      まずは初期化してしまいましょう。


      Router#
      Router# configure
      Enter configuration commands, one per line. End with CNTL/Z.
      Router(config)# erase startup-config
      Are you sure you want to erase the startup-configuration? (Yes or [No]): yes
      Router(config)# exit
      Router# default-console command-line
      % You must RELOAD the router for this configuration to take effect.
      Router#

      初期化後の設定はごちゃごちゃ解説するよりそのもの貼ったほうがわかりやすいので
      はっておきます!Good luck!


      !
      timezone +09 00
      !
      logging buffered 131072
      logging subsystem all warn
      logging timestamp datetime
      !
      !
      ip ufs-cache enable
      ip route default GigaEthernet0.1
      ip access-list sec-list permit ip src any dest any
      !
      !
      !
      ike proposal ike-prop encryption aes hash sha group 1024-bit
      !
      ike policy ike-policy1 peer 27.0.1.16 key bbbbbbaaaaaaaaaaaaamavO8waikpkWlL ike-prop
      ike keepalive ike-policy1 10 3
      !
      ike policy ike-policy2 peer 27.0.1.144 key cccccccccdddddddddddddda49yt ike-prop
      ike keepalive ike-policy2 10 3
      !
      ipsec autokey-proposal ipsec-prop esp-aes esp-sha lifetime time 3600
      !
      ipsec autokey-map ipsec-map1 sec-list peer 27.0.1.16 ipsec-prop pfs 1024-bit
      !
      ipsec autokey-map ipsec-map2 sec-list peer 27.0.1.144 ipsec-prop pfs 1024-bit
      !
      ppp profile pppoe
      authentication myname aa@bb.jp
      authentication password aa@bb.jp xxxxxxxxxxxxxxxxx
      !
      router bgp 65000
      neighbor 169.254.252.25 remote-as 10124
      neighbor 169.254.252.25 timers 10 30
      neighbor 169.254.252.25 receive-capability override
      neighbor 169.254.252.29 remote-as 10124
      neighbor 169.254.252.29 timers 10 30
      neighbor 169.254.252.29 receive-capability override
      address-family ipv4 unicast
      originate-default always
      !
      device GigaEthernet0
      !
      device GigaEthernet1
      !
      interface GigaEthernet0.0
      no ip address
      shutdown
      !
      interface GigaEthernet1.0
      description == admin net ==
      ip address 192.168.1.205/24
      no shutdown
      !
      interface GigaEthernet0.1
      description == flets ==
      encapsulation pppoe
      auto-connect
      ppp binding pppoe
      ip address ipcp
      ip napt enable
      ip napt static GigaEthernet0.1 udp 500
      ip napt static GigaEthernet0.1 50
      no shutdown
      !
      interface Loopback0.0
      no ip address
      !
      interface Null0.0
      no ip address
      !
      interface Tunnel0.0
      description == Tunnel 1 ==
      tunnel mode ipsec
      ip address 169.254.252.26/30
      ip tcp adjust-mss auto
      ipsec policy tunnel ipsec-map1 out
      no shutdown
      !
      interface Tunnel1.0
      description == Tunnel #2 ==
      tunnel mode ipsec
      ip address 169.254.252.30/30
      ip tcp adjust-mss auto
      ipsec policy tunnel ipsec-map2 out
      no shutdown

      速度については、所詮フレッツなので負荷をかけるには至りませんでした。
      iperfでの測定に限って言えばVPN経由のほうが速度がでるときもありました。

      いずれにせよ、省スペースでらくらく使えるルータとしてはアリだと思います。消費電力も小さいですし。

      2012年12月29日土曜日

      本年の出社おわり

      やることは沢山あるのだが、31日出社する気にはならんのでひとまず今年のしごとおさめということにする。

      昨年に引き続き今年もその月何してたか、当たり障りのないもののなかから、まとめてみる。

      1. DirectConnectの準備が忙しかった。毎週固定でやる重いミーティング3並列が3ヶ月目でかなり辛くなってくる。
      2. シアトルでのセールス大集合+トレーニングがとてもよかった。しかしこの時しこんだことは実現せず。大変だったのに。
      3. 4月以降の布石的な話を聞くことが増える。東京リージョン1年ってこういうこと。
      4. 新大阪出張案件に行くときに、新幹線にのってる芸能人を初めて見る。
      5. DirectConnectの具体的な導入の話が増えてくる
      6. JAWS−UG東京のデータベースナイトイベント!
      7. ゲーム以外での突発イベント系の話が増えてくる
      8. サンフランシスコ出張。HP辞めて以来、もう来ると思ってなかったし、HPのときはパロアルト直行だったので夏こんなに涼しいなんて知らなかった。
      9. 1年前からやってるデカイ案件がいよいよローンチ。で、大変だったがなんとか。
      10. 客先から客先の時間がまにあわずタクシーを使う、という経験を初めてやる。
      11. Re:Invent参加できなかった!
      12. ますますUS東海岸にしかないものが欲しくなる1年でした

      昨年にくらべれば、随分オフィスにいられる時間は長くなった。とはいえ、あいかわらず検証や実験の類の時間は土日や夜間になってしまうし、時差もあるしでキッチリ時間を切ることは無理なことは相変わらず。

      2012年12月24日月曜日

      CDPアンチパターンの14つめはバックアップのアンチパターン

      今年のクラウドデザインパターンの最大のイベントといえば、ラスベガスでの英語における発表だったでしょう。しかし、東京お台場で9月に行われたクラウドデザインパターンの発表もすばらしいものばかりでした。

      そこで、私はアンチパターンのワースト13を発表しました。そのプレゼンの中でも発表しましたが、アンチパターンの目的はただ笑うためにあるものではありません。

      • 失敗に陥るパターンを類型化し、事例の早期発見と対応策に関しての提案を目的とする。
      • 動作やプロセス、構造について、当初は妥当であったのに、最終的に悪い結果が繰り返されるパターン
      • リファクタリングするための方法が存在するパターン

      この3つの観点をわすれてはならないと思っています。

      13のアンチパータンの後ろに続くワーストは、バックアップにかかわるものばかりでした。特に、AWSでバックアップを考えるとき便利なのはAMI、EBSとスナップショット機能でしょう。

      • 「AMIを一切作らずに本番運用を行う」ことがしばしば見受けられます。これはAMI作りが難しいと思っている場合や、OSからの手順に固執した場合などに見られがちです。ある程度のところまでAMIの形でシステムを用意しておけば、システム構築やトラブル時の対応時間の短縮が可能です。
      • 逆に「AMI作成だけがバックアップ」だと思っているとすれば、それも問題です。AMI作成の最大の問題は、AMI作成を動作中に安全に行うことができないことです。また、EBSを使わない場合にはバックアップできないと思っているとすればさらに問題です。
      • 「スナップショットを使わない」ことも問題です。EBSによるバックアップは残念ながら完璧ではありません。AWSはEBSが壊れかねないことを表明しています。スナップショットを使えば、異なるアベイラビリティゾーンへの移動や、操作ミスによるファイル消失リスクを下げることもできます。
      • 「スナップショットを安全に使えない、使わない」のも時として問題です。EBSはあくまでボリュームでありそのファイルシステムやアプリケーションでキャッシュしている内容はわかりません。スナップショットをバックアップに使うのであれば、ボリュームへの書き込みを確実におこなわければなりません。

      繰り返しになりますが、AMI,EBS,スナップショットはAWSでのシステム運用に大きく貢献できる機能です。ぜひこれらの特性を理解して利用しましょう。

      さて、13のアンチパターンを見たことがないひとのために復習をしておきます。

      1. プロトタイプを作らずに机上だけで設計を行う
      2. トラフィック代金を心配しすぎる
      3. IPアドレスに頼りすぎる
      4. ひとつのアベイラビリティゾーンだけでシステムを作る
      5. EC2以外のサービスを使わない
      6. S3を共有ストレージ、ブロックストレージとして使う
      7. 事前のキャパシティプランニングに固執する
      8. AWSのセキュリティ機能を使わない
      9. 構築したシステムの見直しをしない
      10. 全機能を使おうとして消化不良に陥る
      11. リージョン選択を間違う
      12. CloudFrontを使わない
      13. 実際の負荷変化と違う負荷テストを行う

      中でも、机上の設計だけで本番のシステムを決めてしまうことだけは避けましょう!AWSはまだまだ発展していくシステムです。

      そして、逆説的ですが、CDPに固執することなく新たなアーキテクチャに挑戦していきましょう。

      [slideshare id=14541803&w=427&h=356]


      2012年12月6日木曜日

      VPCのメタパターンもしくは怠惰な私のVPC導入。

      皆様、昨日の松井さんの男気あふれる記事に度肝を抜かれた荒木でございます。毎度のことながら彼の軌跡は奇跡として語り継がれるといって間違いないでしょう。

      さて、VPC環境構築のメタパターンと予告しました。実際のところCloudformationの出番は無限です。その中でも最も強力なのは、ある状態を保存再現する機能です。VPCのように面倒な環境構築に有効です。

      時間のない人のために結論を。

      1. CloudFormationはある時点の状態再現に有効です。
      2. VPCに関しては再現を自動化するのは諦めて、(時としてつまらない)設計を再現するためにCloudFormationを使いましょう。
      3. 実はVPCIDを使えばClassicな環境からの移行は簡単!

      というわけで、CloudFormationこそがVPC導入のポイントかもしれません。

      これから述べる内容は

      1. ELB
      2. アプリケーションサーバ
      3. データベース(RDS)

      のどこにでもある三段構えのサービスを題材にしています。

      CloudFormationの意義

      AWSを使ったシステム構成工数に関しては多くの方が考える問題です。
      システムは机上での設計ではなく、試行錯誤を経てサービスを作るべきだとは思います。

      実際のシステムでは、構成変更時にはテストが欠かせません。
      また、テストの与える影響の測定や変更前への切り戻しを意識したシステム構成を求められることはまちがいありません。
      そのために同一のシステムを構成し、部分的な変更を加えた後にテストを行うのが理想的な体制でしょう!

      その一方で、この師走のなか、毎回同じことを繰り返す時間はない、というのが本当のところではないでしょうか。
      何度でも速やかに構成(クローニング)できるようにして、ある時点でのシステムにもどせれば、どんどんチャレンジすることができるはずです。

      そこで役に立つのがCloudFormationです。

      テンプレート作成には3つの方法があります。

      • テンプレートの文法をAWS CloudFormation User Guideを読み、いちから作成する方法
      • AWS CloudFormationサンプルテンプレート(http://aws.amazon.com/jp/cloudformation/aws-cloudformation-templates/) として集められたサンプルを流用する方法
      • CloudFormerを使って、既存のAWSリソースからCloudFormationテンプレートを作成する方法

      正直、最初の2つの方法は「部分的に変更を加えてきたシステム」において現実的な方法ではないでしょう。そこで3番目のCloudFormerの登場です。

      一旦、CloudFormer で作成した AWS CloudFormation テンプレートを使うと、AWS Management Consoleで数回クリックするだけで既存のシステムのコピーを起動可能です。

      準備:まずは、CloudFormer自体を用意する。

      https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#cstack=sn~AWSCloudFormer|turl~https://s3.amazonaws.com/cloudformation-samples-ap-northeast-1/AWSCloudFormer.templateをクリックして、早速使ってみましょう。

      起動すると、次のような画面があらわれるはずです。

      CF first

      CloudFormerはIAMのアカウントを使用するため、その確認のチェックはさくっと終わらせて前にすすみましょう。



      すると、こんな具合で最終的にシステムを作っていいかどうかの確認がはいります。もちろん躊躇せずにContinueしましょう。



      無事起動するとStatusがCREATE_COMPLETEに変わります。それまでは、Eventsでもみてニヤニヤしましょう。

      CloudFormerの使用

      CloudFormerを使用するには、CloudFormerの作成したURLにwebブラウザでアクセスします。そのURLはOutputsタブの中で確認します。



      するとこんな画面があらわれます。テンプレート作成対象リージョンを選択しましょう。



      あとは一本道です!

      含めるドメイン名を確認したり、EC2を確認したり、RDSを確認したり、セキュリティグループを確認したり。。

      数個の画面でチェックをつづけると、S3に保存するように促されます。保存されたテンプレートはJSON形式で、その頭のほうが確認できます。



      ここまできたら、このテンプレートをつかってたちあげてみましょう。Congratulationsがきたら、即座にLaunch Stackです。



      とはいえみなさん時間もないことですし、上がりそうだ!という雰囲気だけつかんでおきましょうか。



      とりあえず、作成したテンプレートの置き場だけは確認しておきましょう。このテンプレートがスタート地点になります。

      とはいえ、これで完璧か!といわれるとそんなことはありません。

      CloudFormerはまりポイント1:AMIは動作時インタンスのAMIである

      個人的にCloudFormerのハマリポイントはなんだと問われれば、AMI情報は動作時のインスタンスが起動した時点でのAMIであって、CloudFormerがAMIを作るわけではないところです。

          "instancei2d5f6a2d": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
      "AvailabilityZone": "ap-northeast-1b",
      "DisableApiTermination": "FALSE",
      "ImageId": "ami-c857e5c9",
      "InstanceType": "m1.small",
      (以下略)

      こんなテンプレートがあるときは、このAMIの内容を変更したならば、自分でつくりなおさなければなりません。あえてつくりなおさなければならないときは、マネージメントコンソールでインスタンスから右クリックして作りなおせばよいでしょう。

      CloudFormerはまりポイント2:Route53で指定している値は動作時ELBのCNAMEである

      こう言われてもピンとこないかもしれません。

          "dnscdpshoparakiin": {
      "Type": "AWS::Route53::RecordSet",
      "Properties": {
      "HostedZoneId": "/hostedzone/xxxxxxxxxxxx",
      "Name": "xxxxxxx.araki.in.",
      "Type": "CNAME",
      "TTL": "300",
      "Comment": "araki.in ",
      "ResourceRecords": [
      "xxxxxxx-444735762.ap-northeast-1.elb.amazonaws.com"
      ]
      }
      },

      この、ResourceRecordsの内容はそのものずばりELBのCNAMEを指定しています。
      このままでは、ELBの定義ではなく、ELBのエンドポイントそのものを指定しているため、作成したELBからFn::GetAttを使って値を得る形式に変更します。
      例えばこんな具合に。

      { "Fn::GetAtt" : [ "elbeccube", "DNSName" ] }

      CloudFormerはまりポイント3:RDSの内容は動作時である

      これもELBと同じですが、データが消えるという意味ではもっと問題がおおきいかもしれません。

      スナップショットを作成したら、DBSnapshotIdentifierパラメータで指定しましょう。

      CloudFormerはまりポイント4:手修正でフォーマットを破壊する

      ここまでうまく行っても、人間にはJSONやSGMLやXMLは無理だという説があります!

      もちろん慎重にやれとか、ダブルチェックしろとか、トリプルチェックしろ。。N重チェックというループに陥いるのもいとおかしというところですが、そんなくだらないチェックには機械にやらせましょう。

      そこで登場するのがcfn-validate-templateコマンドです。

      $ cfn-validate-template –template-file テンプレートファイル名

      で、テンプレートがValidと言われるまでこころのままに修正しましょう。

      今時の人なら、こんなコマンドよりもVisualなアプローチのほうがいいかもしれません。たとえばMacならVisualJSONをつかってみましょう。構造も一発で確認できます。

      クローニング実行

      それでは準備したCloudformationを実行してみましょう。
      クローニングの実行は、CloudFormationのタブ内、Create New Stackボタンを押すところからはじまります。



      つづいてStackNameとJSONファイルの在り処を指定します。



      後は、CloudFormation Stacksの画面から、Statusの変化と、Eventsの出力適宜Refreshしながら眺めて待ちましょう。

      CloudFormationではカバーできない部分のフォローにUserData

      CloudFormationによって骨格はほぼ完成したもののたとえば、アプリケーション固有の設定はカバーできません。
      ここで登場するのが、UserDataです。

            "instanceib3ba90b3": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
      "AvailabilityZone": "ap-northeast-1a",
      "DisableApiTermination": "FALSE",
      "ImageId": "ami-5259eb53",
      "UserData": { "Fn::Base64" : { "Fn::Join" : ["", [
      "#!/bin/bash \n",
      "sed -i \"s/yyyyyy.araki.in/",
      {"Ref":"SiteURL"},
      "/g\" /home/ec2-user/cdp/eccube/data/config/config.php\n",
      "#EOF"
      ]]}},

      この例では、/home/ec2-user/cdp/eccube/data/config/config.php に含まれる yyyyyy.araki.inをSiteURLというリファレンスに書き換えています。ある意味かなり力技ですが、UserDataの万能感は異常です。

      VPCに関しては再現を自動化するのは諦めて、(時としてつまらない)設計を再現するためにCloudFormationを使いましょう。

      とまあ、こんなことを書くのは、CloudFormerがVPCに対応していない試行錯誤したシステムの保存にフォーカスしていて、なおかつ、繰り返し単調な設計がつづくネットワーク再現に最適だからなのです。

      たとえば、こんなことやってられますか?

      1        VPCとして10.1.0.0/16を定義 

      2        ELB用にPublicサブネットを定義 

      2.1       ZoneAELBsubnet 10.1.10.0/24を定義

      2.2       ZoneBELB subnet 10.1.11.0/24を定義

      3        eccube用にPrivateサブネットを定義

      3.1       ZoneAeccubesubnet 10.1.20.0/24を定義

      3.2       ZoneBeccube subnet 10.1.21.0/24を定義

      4        RDS用にPrivateサブネットを定義

      4.1       ZoneARDSsubnet 10.1.30.0/24を定義

      4.2       ZoneBRDS subnet 10.1.31.0/24を定義

      5        インターネットゲートウェイを定義

      5.1       インターネットゲートウェイをVPCに関連づけ

      6        2Publicサブネットの経路表を定義

      6.1       Publicサブネットの経路表にデフォルトゲートウェイとしてインターネットゲートウェイを向ける

      6.2       ZoneAELBsubnetに対して経路表を関連づけ

      6.3       ZoneBELBsubnetに対して経路表を関連づけ

      7        2PublicサブネットにNACLを定義

      7.1       Inbound用にHTTPポートを許可

      7.2       Inbound用に1024から65535のダイナミックポートを許可

      7.3       Outbound用にHTTPポートを許可

      7.4       Outbound用に1024から65535のダイナミックポートを許可

      7.5       ZoneAELBsubnetに対してNACLを関連づけ

      7.6       ZoneBELBsubnetに対してNACLを関連づけ

      8        PrivateサブネットにNACLを定義

      8.1       Inbound用にVPC内部からの接続を許可

      8.2       Outbound用にVPC内部への接続を許可

      8.3       ZoneAeccubesubnetNACLを関連づけ

      8.4       ZoneBeccubesubnetNACLを関連づけ

      8.5       ZoneARDSsubnetNACLを関連づけ

      8.6       ZoneBRDSsubnetNACLを関連づけ

       

       



      あたまがクラクラしてきませんか? 正直私はこんな指示書を渡されて、マネージメントコンソールから設定しろと言われたらいやになります。正直いくららくらくページを稼げるといわれてもスクリーンショットなんてとってられません。

      一方で、こういう繰り返しはCloudFormationならばコピペ一発です。なんという楽でしょう。しかも失敗もへります!

      もっとも、コピペの結果はこんなダラダラとしたJSONになります。

      VPCの中へのサービス配置

      VPC内部のサブネット作成が完了したら、実際のサービス配置をはじめます。

      CloudFormationテンプレートの入れ子呼び出し

      まず最初のテクニックは、VPCサブネットを作成するために使ったCloudFormationテンプレートの呼び出しです。
      呼び出しは、AWS::CloudFormation::StackのPropertiesにTemplateURLとして与えます。

          "Resources" : {
      "vpcMake" : {
      "Type" : "AWS::CloudFormation::Stack",
      "Properties" : {
      "TemplateURL" : "https://s3-ap-northeast-1.amazonaws.com/arakisa
      /CloudFormation/eccube-vpc-05vpc.json",
      "TimeoutInMinutes" : "60"
      }
      },

      このテンプレートでは、呼び出し元となるCloudFormationテンプレートに実行結果の値を渡すために、Outputsを定義しています。

          "Outputs":{
      "ELBSubnetAId":{
      "Value":{"Ref": "ELBSubnetA"},
      "Description":"Id of ELBSubnetA"
      },
      "ELBSubnetBId":{
      "Value":{"Ref": "ELBSubnetB"},
      "Description":"Id of ELBSubnetB"
      },
      "ECSubnetAId":{
      "Value":{"Ref": "ECSubnetA"},
      "Description":"Id of ECSubnetA"
      },
      "ECSubnetBId":{
      "Value":{"Ref": "ECSubnetB"},
      "Description":"Id of ECSubnetB"
      },
      "RDSSubnetAId":{
      "Value":{"Ref": "RDSSubnetA"},
      "Description":"Id of RDSSubnetA"
      },
      "RDSSubnetBId":{
      "Value":{"Ref": "RDSSubnetB"},
      "Description":"Id of RDSSubnetB"
      },
      "VPCID":{
      "Value":{ "Ref" : "VPC" },
      "Description":"Id of VPC"
      }
      }

      たとえばこんな具合です。ネットワークに関連するIdをVPCID, ELBSubnetAId, ELBSubnetBId, ECSubnetAId, ECSubnetBId, RDSSubnetAId, RDSSubentBIdとして定義しています。

      呼び出し元で上のVPCIDを使うためには、

      { "Fn::GetAtt" :["vpcMake", "Outputs.VPCID"] }

      のように、Fn::GetAttを使っていつでも呼び出すことができます。

      呼び出し元テンプレートの修正

      親となるCloudFormationテンプレートでは、VPC環境に対応した修正が必要です。
      今回、VPC内で使用を定義するために特別なパラメータをあたえなければならないリソースタイプは

      • AWS::ElasticLoadBalancing::LoadBalancer
      • AWS::EC2::SecurityGroup
      • AWS::EC2::Instance
      • AWS::RDS::DBSubnetGroup
      • AWS::RDS::DBSecurityGroup

      という5つです。

      AWS::ElasticLoadBalancing::LoadBalancer

      ELBはVPCにおいては、配置するサブネットと、セキュリティグループを指定します。
      ELBを配置するサブネットの指定は、AWS::ElasticLoadBalancing::LoadBalancerの中で、Subnetsで指定し、セキュリティグループも同様にSecurityGroupsとして指定する。

              "elbeccube": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
      "Subnets": [
      { "Fn::GetAtt" :["vpcMake", "Outputs.ELBSubnetAId"] },
      { "Fn::GetAtt" :["vpcMake", "Outputs.ELBSubnetBId"] }
      ],
      "SecurityGroups" : [{"Ref" : "LoadBalancerSecurityGroup"}],
      ……(略)

      AWS::EC2::SecurityGroup

      セキュリティグループは、AWS::EC2::SecurityGroupを使って指定します。
      VPC内においては、セキュリティグループも、どのVPCに所属しているかをProperties中にVpcIdとして宣言します。

             "LoadBalancerSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
      "GroupDescription" : "Enable HTTP access on port 80",
      "VpcId" : { "Fn::GetAtt" :["vpcMake", "Outputs.VPCID"] },
      "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" } ],
      "SecurityGroupEgress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" } ]}},

      AWS::EC2::Instance

      EC2インスタンスもVPC内で起動させるためには、SubnetIdを指定します。

              "instanceib3ba90b3": {
      "Type": "AWS::EC2::Instance",
      "Properties": {
          "SubnetId": {"Fn::GetAtt":["vpcMake", "Outputs.ECSubnetAId"]},
      …… (略)

      AWS::RDS::DBSubnetGroup

      RDSが使用するサブネットにはSubnetIdを指定します。

             "MyDBSubnetGroup" : {
      "Type" : "AWS::RDS::DBSubnetGroup",
      "Properties" : {
      "DBSubnetGroupDescription" : "Subnets available for the RDS DB Instance",
      "SubnetIds" : [
      { "Fn::GetAtt" :["vpcMake", "Outputs.RDSSubnetAId"] },
      { "Fn::GetAtt" :["vpcMake", "Outputs.RDSSubnetBId"] }
      ]}},

      AWS::RDS::DBSecurityGroup

      RDSはさらにDBSecurityGroupも定義します。この例では、CIDRブロックを使っています。

              "dbsgdefault": {
      "Type": "AWS::RDS::DBSecurityGroup",
      "Properties":{
      "GroupDescription": "RDS security group in private",
      "EC2VpcId" : { "Fn::GetAtt" :["vpcMake", "Outputs.VPCID"] },
      "DBSecurityGroupIngress": [{
      "CIDRIP": "10.1.20.0/23"
      } ]}}

      以上の修正を加えたCloudFormationテンプレートを
      https://arakisa.s3.amazonaws.com/CloudFormation/eccube-vpc-06instance.json
      に置いておきます!ながーいのでニヤニヤする程度にとどめてくださいませ!

      結論

      1. CloudFormationはある時点の状態再現に有効です。
      2. VPCに関しては再現を自動化するのは諦めて、(時としてつまらない)設計を再現するためにCloudFormationを使いましょう。
      3. 実はVPCIDを使えばClassicな環境からの移行は簡単!

      というわけで、CloudFormationこそがVPC導入のポイントです。異論は大いにあるでしょうけれども、今あるシステムを移行するほうが新規に設計するよりは難しいとおもいます。そんな手助けに(主に試行錯誤のためですが)なると幸いです。