Google Cloud Functionsが13%。CNCF調査

サーバレスコンピューティング、もっとも利用されているのはAWS Lambdaで70%、Google Cloud Functionsが13%。CNCF調査. 2017年12月12日. Kubernetesなどの開発をホストするCloud Native Computing Foundationは、同団体のコミュニティに対してコンテナオーケストレーションやサーバレスコンピューティング … 続きを読む

Docker + Nginx + Let’s EncryptでHTTPS対応のプロキシサーバーを構築する

Docker上にNginxコンテナをプロキシサーバーとして構築し、Let’s EncryptでHTTPS対応しました。構築にあたって かなり苦戦した ので、そのノウハウを記事としてまとめました。

「Nginx」とは

Apacheなどの従来のWebサーバーは、クライアントの数が多くなるとサーバーがパンクする 「C10K問題(クライアント1万台問題)」 を抱えていました。「Nginx」はこの問題を解決するために誕生した、静的コンテンツを高速配信するWebサーバーです。2017年10月現在、そのシェアは Apacheとほぼ同等 となっています。

wpid-wss-share13.png

Webサーバー シェア
Micosoft IIS 49.44%
Apache 18.78%
Nginx 18.40%

「Let’s Encrypt」とは

「Let’s Encrypt」は すべてのWebサーバへの接続を暗号化する ことを目指し、SSL/TLSサーバ証明書を 無料 で発行する認証局(CA)です。シスコ、Akamai、電子フロンティア財団、モジラ財団などの大手企業・団体がスポンサーとして支援しています。


本稿が目指すシステム構成

本稿ではAmazon EC2、Dockerコンテナを使用して以下のようなシステムを構築することを目標とします。

DockerでNgixのプロキシサーバーを構築する.png

前提条件

  • 独自ドメインを取得していること(本稿で使用するドメインはexample.comとします)
  • IPv4パブリックIP(Elastic IP)がEC2インスタンスに設定されていること
  • EC2インスタンスにDocker、docker-composeがインストールされていること

事前に準備すること

DockerでHTTPS対応のプロキシサーバーを構築するにあたり、事前に以下の設定をしておく必要があります。

  • EC2のインバウンドルールで443ポートを開放する
  • DNSのAレコードを設定する
  • プロキシ用のネットワークを構築する

EC2のインバウンドルールで443ポートを開放する

インバウンドルールを以下のように設定し、443ポートを外部へ公開します。

タイプ プロトコル ポート範囲 ソース
HTTPS TCP 443 0.0.0.0/0
HTTPS TCP 443 ::/0

DNSのAレコードを設定する

DNSの設定方法は利用しているドメイン取得サービスによって異なります。例えばバリュードメインの場合、DNSの設定方法は「DNS情報・URL転送の設定 | VALUE-DOMAIN ユーザーガイド」に記載されています。

DNSのAレコードを以下のように設定します。xx.xx.xx.xxにはEC2インスタンスに割り当てられているIPv4パブリックIPを設定します。

a @ xx.xx.xx.xx
a www xx.xx.xx.xx

上記設定は以下を意味します。

  • example.com(サブドメイン無し)をIPアドレスxx.xx.xx.xxにポイントする
  • www.example.com をIPアドレスxx.xx.xx.xxにポイントする

プロキシ用のネットワークを構築する

プロキシサーバーとWebサーバー間のネットワークは外部との通信を行う必要がありません。そこで
プロキシサーバーとWebサーバー間の 内部ネットワーク を構築するため、EC2のインスタンスにログインし、以下のコマンドを入力します。

$ docker network create --internal sample_proxy_nw

上記コマンドは以下を意味します。

  • --internal: ネットワーク外との通信が行えないネットワークを作成します。
  • sample_proxy_nw: 任意のネットワーク名です。

以下のコマンドを入力し、ネットワークの設定情報がコンソールに出力されていることを確認しましょう。

$ docker network inspect sample_proxy_nw

Dockerコンテナの定義ファイルを作成する

事前準備が完了したら、Dockerコンテナの定義ファイルを作成しましょう。本稿におけるディレクトリ構成は以下のとおりです。

/path/to/dir/

.
├── docker-compose.yml // プロキシサーバーとWebサーバーのコンテナを定義するファイル
└── proxy
    ├── default.conf // プロキシサーバー上にあるNginxのデフォルト定義ファイル
    ├── Dockerfile // プロキシサーバーのイメージを構築するためのファイル
    └── entrypoint.sh // プロキシサーバーにSSL証明書を取得するためのファイル

以下では、各ファイルの内容を解説します。

./docker-compose.yml

docker-compose.ymlでは、以下のコンテナを定義しています。

  • proxy: プロキシサーバー(Nginxベース)
  • web1: Webサーバー(httpdベース)
  • web2: Webサーバー(httpdベース)
version: '3'
services:
  proxy:
    build: ./proxy
    tty: true
    image: sample_proxy
    container_name: sample_proxy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    ports:
      - "443:443"
    volumes:
      - '/srv/letsencrypt:/etc/letsencrypt'
    networks:
      - default
      - sample_proxy_nw
    depends_on:
      - "web1"
      - "web2"
    command: ["wait-for-it.sh", "sample_web1:80", "--", "./wait-for-it.sh", "sample_web2:80"]
  web1:
    image: httpd
    container_name: sample_web1
    tty: true
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - sample_proxy_nw
  web2:
    image: httpd
    container_name: sample_web2
    tty: true
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - sample_proxy_nw
networks:
  proxy_nw:
    external: true

上記コマンドは以下を意味します。

  • サービスproxyports: 外部からのHTTPSアクセスとproxyサーバーの内部ポートを疎通させるため、443:443を定義します。
  • サービスproxyvolumes: /srv/letsencrypt:/etc/letsencryptを定義します。/etc/letsencryptLet’s Encryptで取得した証明書が生成されるディレクトリ です。
  • networks: 上述の説明で生成したsample_proxy_nwを各サービス(proxy, web1, web2)に定義します。
  • depends_on: コンテナの起動順序を制御するオプションです。 Nginxのproxy_passに設定されているWebサーバーが起動していない状態でプロキシサーバーが起動した場合にエラーとなる ため、web1, web2を設定します。

./proxy/default.conf

./proxy/default.confはNginxのデフォルト定義ファイル(/etc/nginx/conf.d/default.conf)を書き換えるためのファイルです。

server{

    server_name example.com www.example.com;

    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location / {
        proxy_pass    http://sample_web1/;
    }

    location /example/ {
        proxy_pass    http://sample_web2/;
    }

}

上記設定は以下を意味します。

  • server_name: ユーザーから要求されるHTTPリクエストのヘッダに含まれるHostフィールドとserver_nameが一致した場合、該当するサーバ設定を採用します。Nginxではキャッチオールサーバーとして_を定義することもできますが、 certbot-autoがサーバー情報を正しく取得することができない ため、上記のようにドメイン名を入力します。
  • location: ルートディレクトリ(example.com/)とサブディレクトリ(example.com/example/)にアクセスした際の振り分け先URIを設定します。proxy_passには、http://[コンテナ名]/を設定します。コンテナ名はdocker-compose.ymlのcontainer_nameで設定した名前となります。
    また、http://sample_web1/のように 末尾に/を入れる ことに注意しましょう。例えばlocation /example/において、プロキシパスの末尾に/が含まれていない(http://sample_web2)場合、振り分け先は http://sample_web2/example/となってしまいます。

./proxy/Dockerfile

FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
RUN apt-get update && apt-get install -y \
        wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh
ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto
RUN chmod a+x /usr/local/bin/certbot-auto
RUN certbot-auto --os-packages-only -n
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

上記設定は以下を意味します。

  • ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto: Let’s Encryptが発行するSSL/TLSサーバ証明書を自動で取得・更新するツール「 certbot-auto 」をダウンロードします。

./proxy/entrypoint.sh

#!/bin/bash
certbot-auto --nginx -d example.com -d www.example.com -m your-account@gmail.com --agree-tos -n
certbot-auto renew
/bin/bash

上記設定は以下を意味します。

  • --nginx: プロキシサーバーにNginxを使用する場合のオプションです。default.confの設定を自動的に書き換えます。(2017年12月現在、アルファ版のプラグイン)
  • -d example.com -d www.example.com: SSL/TLSサーバ証明書の取得を申請するドメイン名を指定します。
  • -m your-account@gmail.com: アカウントの登録や回復などに使用する電子メールアドレスを指定します。
  • --agree-tos: Let’s Encryptの利用規約に同意します。
  • -n: インタラクティブ設定をオフにします。
  • ./certbot-auto renew: 3ヶ月で失効する SSL/TLSサーバ証明書を自動で更新します。

以下のコマンドを入力してentrypoint.shに 実行権限を付与する ことを忘れないようにしましょう。

$ chmod +x entrypoint.sh

Dockerコンテナを起動する

それでは以下のコマンドを入力してDockerコンテナを起動しましょう。

docker-compose up -d

しばらく時間をおいてから、以下のコマンドを入力します。

docker-compose logs

以下のように出力されていれば成功です。

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://example,com and
https://www.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com
-------------------------------------------------------------------------------

HTTPSでアクセスする

ブラウザを起動し、実際に以下のURLにアクセスしてみましょう。

Chromeブラウザの場合はデベロッパーツール > Security > View certificateからSSL/TLSサーバ証明書を確認することができます。

「発行元: Let’s Encrypt Authority X3」となっているはずです。

続きを読む

CloudAutomatorでSQSを利用せずジョブの数珠つなぎを実現する

Cloud Automatorのアドベントカレンダー2017年の10日目を担当します。

Cloud Automatorとは

Cloud Automatorでは、AWSのリソースを操作するための内容を「ジョブ」と呼ばれる単位でWeb上の操作画面からGUIで登録し、日時指定やHTTPリクエストをトリガーにして実行させることが可能なサービスです。
https://cloudautomator.com/

ジョブの連続実行

これまでCloud Automatorでは、複数のジョブを連続して実行させるためには、AmazonSQSを利用して数珠つなぎ状態にする方法をサポートしていました。(マニュアル:「ジョブを数珠つなぎにして複数のジョブを連携する」参照)
しかしこれは、SQSを事前に準備する必要があり、少々手間でした。

スクリーンショット.png


2017年10月に、「Webhook後処理」という機能(マニュアル:「Webhook後処理」参照)がリリースされました。ざっくり言うと、ジョブの実行後にその結果を任意のURLにPOSTリクエストで受け取ることが可能になります。
今回はこの機能を利用して、 SQSを使わずに Cloud Automatorのジョブを連続実行させてみます。

スクリーンショット 2017-12-10 22.26.24.png

サンプル:EC2インスタンスのインスタンスタイプの変更

ここでは、先ほどのSQSを使ったインスタンスタイプを変更するための一連ジョブを、HTTPトリガーとWebhook後処理で置き換える例を示します。

例えばマネージメントコンソール上で、EC2のインスタンスタイプを手動で変更&起動したい場合は

  1. 該当のインスタンスを「停止」にする(→完全に停止するまでしばらく待つ)
  2. インスタンスタイプを変更する
  3. インスタンスを起動する

これらの操作が必要になりますが、ここで地味に面倒なのが、インスタンスが完全に停止するまで待たないと、インスタンスタイプが変更できないことです。Cloud Automatorを利用すると、これら一連の作業をジョブとして登録&連続実行させることで、不毛な停止待ち時間もすべてCloud Automatorがハンドリングしてくれます。

👉 STEP1: インスタンス起動ジョブを登録

連続するジョブを作成する際は、最後のジョブから登録していくと手間が少なくて済みます。(2017年12月現在)
まずは、 運用ジョブ > ジョブの追加 メニューから、新規にジョブを作成します。

step1.png

項目 設定値
トリガー HTTPトリガー
アクション EC2:インスタンスを起動
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
リソースの終了ステータスをチェックする ※ここはチェックしてもしなくてもどちらでもOK
後処理 ※必要に応じて(指定しなくてもOK)
ジョブ名 「インスタンス起動ジョブ」など任意の名前

このような形で登録します。

登録完了後は、 運用ジョブ > 運用ジョブ一覧 メニューから、先ほど作成したジョブの詳細画面を開いて、以下の情報をメモします。

step1_2.png

👉 STEP2: インスタンスタイプ変更ジョブの登録

次に、インスタンスタイプの変更ジョブを登録していきます。STEP1と同じように、ジョブの新規登録画面から、以下のように登録します。

項目 設定値
トリガー HTTPトリガー
アクション EC2:インスタンスタイプを変更
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
インスタンスタイプ ※変更したいタイプを指定
後処理 ※新規に後処理を作成して指定(後述)
ジョブ名 「インスタンスタイプ変更ジョブ」など任意の名前

🔰 後処理の指定
後処理の指定箇所で、「後処理を新たに作成する」ボタンを押して、作成画面を開きます。
step2_1.png

ここで、サービスには Webhook を選択し、先ほどメモしておいた「インスタンス起動ジョブ」の、 HTTPトリガーのURL と、 HTTPヘッダーのAuth情報 を入力し、判別しやすい後処理名を入力して登録します。
step2_2.png

後処理作成後、今作成した後処理を「成功時」の後処理に指定します。
step2_3.png

以上の情報で「インスタンスタイプ変更」のジョブを作成します。
STEP1と同様に、作成したジョブの詳細画面を開き、 HTTPトリガーのURLHTTPヘッダーのAuth情報 を再度メモします。

👉 STEP3: インスタンス停止ジョブの作成

これで最後です。STEP2と同様に、ジョブの作成画面で次のように登録します。

項目 設定値
トリガー ※利用したいトリガーを指定
アクション EC2:インスタンスを停止
AWSアカウント ※CloudAutomatorに登録しているAWSアカウントを指定
インスタンス 該当のインスタンスを指定(タグの指定でもOK)
リソースの終了ステータスをチェックする ※ここは必ずチェックしてください
後処理 ※新規に後処理を作成して指定(後述)
ジョブ名 「インスタンス停止ジョブ」など任意の名前

【⚠️注意事項】
「リソースの終了ステータスをチェックする」にチェックを入れることで、インスタンスが完全に停止するのを待ってから、指定した後処理が実施されるようになります。チェックを入れないと、インスタンスが停止準備の状態のままインスタンスタイプ変更のジョブが実行されてしまい、ジョブがエラー終了してしまうのでご注意ください。

🔰 後処理の指定
STEP2と同様に、新規に後処理を作成します。
サービスには Webhook を選択し、先ほどメモしておいた「インスタンスタイプ変更ジョブ」の、 HTTPトリガーのURL と、 HTTPヘッダーのAuth情報 を入力し、判別しやすい後処理名を入力して登録し、ジョブ作成画面上「成功時」の後処理に、作成した後処理を指定してジョブを作成します。

以上で終了です。

まとめ

インスタンスタイプの変更処理などは、自動化しようとすると、インスタンスが完全に停止したことをハンドリングするのが地味に大変だったりしますが、これらはすべてCloud Automator側で判断してくれるため大変便利です。

Cloud Automator上で「インスタンスの停止・変更・再起動」を行うためには、SQSで各ジョブ間を繋ぐ方法しかありませんでしたが、Webhook後処理の登場によって、その作業がかなり簡略化できるようになりました。
・・・とは言っても、後処理を毎回作成するのも大変ではあります。そのため、これらの作業すらも不要になるような便利な機能のリリースが、今後予定されています。
詳しくはサービスのロードマップページを参照してください。
https://cloudautomator.com/roadmap/

続きを読む

G Suiteを利用してGAMでユーザーごとの利用できるAWSアカウントとロールを管理する

NIFTY Advent Calendar 2017 11日目の記事になります。

AWSのアカウント管理や認証をどうしていけばいいのか試行錯誤してました。
タイトルから個人的な結論が出ていますが、考えた順に書いていきます。

Microsoft ADで管理してMasterアカウントにログイン後、SubアカウントにSwitch Roleする

AWS_DirectoryService.png

IDaaSやADを自前で持っていない場合は、すべてがAWSで完結するからこれが綺麗だと思う。

AWS公式の提案手法

マルチアカウントにする意義と、そのためのアカウント間の構成を教えてくれるので、読んだことがない方は一度こちらを読んでおくことをオススメします。

上記の構成を実現するためのCloud Formationのサンプルなども提供されている。

OpenAMをIdpとしてAWSにSAML認証でログインする

OpenAM.png

すでにLDAPを持っていて、できるだけ内部で管理したい場合の構成。

OpenAMのグループに対して、利用できるアカウントとロールを付けていく管理がいいのだろうか。
OpenAMがまるで詳しくないので、次いきます。

G SuiteをIdpとしてAWSにSAML認証でログインする

IDaaSとしてはOneloginなど他にもありますが、G Suiteが試しやすかったので、こちらを採用。
G SuiteからSAML認証でAWSにログインするまでの手順は、こちらにまとまっているので、ここでは説明を割愛します。

MasterアカウントのIdpとして登録

G_Suite.png

OpenAMの代わりにIDaaSとしてG Suiteを利用した構成。

G SuiteのBusinessプラン以上でないと監査ログが取れないので、できればBussinessプランにしたい。Basicプランでも構成自体は実現できる。

SubアカウントのIdpとして登録

G_Suite2.png

G Suiteはひとつのアプリから、下記のどの構成もいけるのでMasterアカウントを経由する方法を取る必要はなさそう。

  • Single APP -> Single Account Single Role
  • Single APP -> Single Account Multi Role
  • Single APP -> Multi Account Multi Role

G SuiteユーザーのAWS Console Roleのrole属性に roleのarn,Idpのarn の形で記載する。roleは複数値入れられるように設定されているので、別のSubアカウントの権限も与えたい場合は、これを増やしていけばいい。

管理コンソール.png

G Suiteのアプリを選択すると、このようにSwith Roleの選択画面に飛ぶ。

Amazon Web Services Sign In.png

アカウントがIDなのはどうしようもなさそうだが、Role名を工夫すればどのサービスのアカウントか判別できそう。
Role名を統一したい場合は、Chromeの拡張機能とか作ってAWSアカウントIDと名前を置換するとか。
あとで困りそうだけどサービスごとにG Suiteのアプリを分けてしまう手もある。

各Subアカウントに対してIdpを設定する必要があるが、Cloud Formationでかなりの部分は吸収できるし、そもそもアカウントをそんなにぽんぽん増やすシーンも思いつかないので、その管理コストよりも利用者の日々の手間をワンステップ減らしたほうが利はあると思う。

GAMでG SuiteのユーザーにAWSの権限を与える

人が増えたり減ったり入れ替わりが起きるごとに、G SuiteのAWS Console Roleを変更するのは辛いので自動化を目指します。
GAMを使えばG Suite APIをCLIで簡単に操作できるので、これを使います。

インストールから基本的な使い方は、以下に詳しく書いてあるので割愛します。

今回修正がしたいのはCustom User Schema Fieldなのでマニュアルはこれ。

試しにさっきのユーザーを 54321 をなくして、 33333 をいうAWSアカウントIDに権限を付けてみます。
注意点としては追加削除という概念はなく、指定したものを上書きする形で指定します。

# gam update user username@example.com \
AWS_Console_Role.role multivalued arn:aws:iam::12345:role/CrossAccountManager-Administrator,arn:aws:iam::12345:saml-provider/G-Suite \
AWS_Console_Role.role multivalued arn:aws:iam::33333:role/CrossAccountManager-Developer,arn:aws:iam::33333:saml-provider/G-Suit
updating user username@example.com...

管理コンソール2.png

ちゃんと更新できてますね。

自動化について

ユーザーごとに管理するのは大変なので、グループごとにアカウントとロールを管理して、そのマスターが更新されるかグループのメンバーが更新されたら、functionが起動してグループ内ユーザーのroleを更新してくれる的なものまでいければ完璧ですが、まだ試していないので今回はここまで。

続きを読む

Amazon ConnectとCloud Automatorを接続して、電話からAWSを操作してみる

2008年当時、私たちはAWSが出てきたので「サーバー購入禁止令」を引きましたが、今度はConnectのおかげて「電話購入禁止令」が出せそうです! このAmazon Connect、「コンタクトセンターのクラウドサービス」と銘打たれていますが、コンタクトセンターだけでなく様々なアプリケーションとの連携も可能です。今日は「Cloud … 続きを読む

consul-template & supervisorでプロセスの可視化

こちらはフロムスクラッチ Advent Calendar 2017の9日目の記事です。

はじめに

ポプテピピック

もうすぐ、ポプテピピック始まりますね。
どうも、jkkitakitaです。

概要

掲題通り、consul + supervisordで
プロセス監視、管理に関して、可視化した話します。

きっかけ

どうしても、新規サービス構築や保守運用しはじめて
色々なバッチ処理等のdaemon・プロセスが数十個とかに増えてくると
↓のような悩みがでてくるのではないでしょうか。

  1. 一時的に、daemonをstopしたい
  2. daemonがゾンビになってて、再起動したい
  3. daemonが起動しなかった場合の、daemonのログを見る
  4. daemonが動いているのかどうか、ぱっとよくわからない。
  5. ぱっとわからないから、なんか不安。 :scream:

個人的には
5.は、結構感じます。笑
安心したいです。笑

ツールとその特徴・選定理由

簡単に本記事で取り扱うツールのバージョン・特徴と
今回ツールを選んだ選定理由を記載します。

ツール 特徴 選定理由
supervisor
v3.3.1
1. プロセス管理ツール
2. 2004年から使われており、他でよく使われているdaemon化ツール(upstart, systemd)と比較して、十分枯れている。
3. 柔軟な「プロセス管理」ができる。
4. APIを利用して、プロセスのstart/stop/restart…などが他から実行できる。
1.今までupstartを使っていたが、柔軟な「プロセス管理」ができなかったため。

※ upstartは「プロセス管理」よりかは、「起動設定」の印象。

consul
v1.0.1
1. サービスディスカバリ、ヘルスチェック、KVS etc…
2. その他特徴は、他の記事参照。
https://www.slideshare.net/ssuser07ce9c/consul-58146464
1. AutoScalingするサーバー・サービスの死活監視

2. 単純に使ってみたかった。(笑)

3. 本投稿のconsul-templateを利用に必要だったから(サービスディスカバリ)

consul-template
v0.19.4
1. サーバー上で、consul-templateのdaemonを起動して使用
2. consulから値を取得して、設定ファイルの書き換え等を行うためのサービス
ex.) AutoScalingGroupでスケールアウトされたwebサーバーのnginx.confの自動書き換え
1. ansibleのようなpush型の構成管理ツールだと、AutoScalingGroupを使った場合のサーバー内の設定ファイルの書き換えが難しい。

2. user-data/cloud-initを使えば実現できるが、コード/管理が煩雑になる。保守性が低い。

cesi
versionなし
1. supervisordのダッシュボードツール
2. supervisordで管理されているdaemonを画面から一限管理できる
3. 画面から、start/stop/restartができる
4. 簡易的なユーザー管理による権限制御ができる
1. とにかく画面がほしかった。

2. 自前でも作れるが、公式ドキュメントに載っていたから

3. 他にもいくつかOSSダッシュボードあったが、一番UIがすっきりしていたから。(笑)

実際にやってみた

上記ツールを使って
daemonを可視化するために必要な設定をしてみました。
本記事は、全て、ansibleを使って設定していて
基本的なroleは
ansible-galaxyで、juwaiさんのroleを
お借りしています。
https://galaxy.ansible.com/list#/roles?page=1&page_size=10&tags=amazon&users=juwai&autocomplete=consul

supervisor

クライアント側(実際に管理したいdaemonが起動するサーバー)

supervisord.conf
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
;  - Shell expansion ("~" or "$HOME") is not supported.  Environment
;    variables can be expanded using this syntax: "%(ENV_HOME)s".
;  - Comments must have a leading space: "a=b ;comment" not "a=b;comment".

[unix_http_server]
file=/tmp/supervisor.sock   ; (the path to the socket file)
;chmod=0700                 ; socket file mode (default 0700)
;chown=nobody:nogroup       ; socket file uid:gid owner
;username=user              ; (default is no username (open server))
;password=123               ; (default is no password (open server))

[inet_http_server]         ; inet (TCP) server disabled by default
port=0.0.0.0:9001        ; (ip_address:port specifier, *:port for all iface)
username=hogehoge              ; (default is no username (open server))
password=fugafuga               ; (default is no password (open server))
;セキュリティ観点から、ここのportは絞る必要有。

[supervisord]
logfile=/tmp/supervisord.log        ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB               ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10                  ; (num of main logfile rotation backups;default 10)
loglevel=info                       ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid        ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024                         ; (min. avail startup file descriptors;default 1024)
minprocs=200                        ; (min. avail process descriptors;default 200)

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

[include]
files=/etc/supervisor.d/*.conf

/etc/supervisor.d/配下に
起動するdaemonを設定します。

daemon.conf
[group:daemon]
programs=<daemon-name>
priority=999

[program:<daemon-name>]
command=sudo -u ec2-user -i /bin/bash -c 'cd /opt/<service> && <実行コマンド>'
user=ec2-user
group=ec2-user
directory=/opt/<service>
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stopasgroup=true
stopsignal=QUIT
stdout_logfile=/var/log/<service>/daemon.stdout.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
stderr_logfile=/var/log/<service>/daemon.stderr.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=10


[eventlistener:slack_notifier]
command=/usr/bin/process_state_event_listener.py
events=PROCESS_STATE
redirect_stderr=false
stopasgroup=true
stopsignal=QUIT
stdout_logfile=/var/log/<service>/event_listener.stdout.log
stdout_logfile_maxbytes=2MB
stdout_logfile_backups=10
stderr_logfile=/var/log/<service>/event_listener.stderr.log
stderr_logfile_maxbytes=2MB
stderr_logfile_backups=10
environment=SLACK_WEB_HOOK_URL="xxxxxxx"

eventlistener:slack_notifierは、下記投稿を参考に作成。
https://qiita.com/imunew/items/465521e30fae238cf7d0

[root@test02 ~]# supervisorctl status
daemon:<daemon-name>              RUNNING   pid 31513, uptime 13:19:20
slack_notifier                    RUNNING   pid 31511, uptime 13:19:20

server側(daemonの管理画面を表示するwebサーバー)

supervisord.conf
クライアント側と同様

consul

server側

[root@server01 consul_1.0.1]# pwd
/home/consul/consul_1.0.1

[root@server01 consul_1.0.1]# ll
total 16
drwxr-xr-x 2 consul consul 4096 Dec  3 04:49 bin
drwxr-xr-x 2 consul consul 4096 Dec  3 06:06 consul.d
drwxr-xr-x 4 consul consul 4096 Dec  3 04:50 data
drwxr-xr-x 2 consul consul 4096 Dec  3 04:50 logs

[root@server01 consul.d]# pwd
/home/consul/consul_1.0.1/consul.d

[root@server01 consul.d]# ll
total 16
-rw-r--r-- 1 consul consul 382 Dec  3 06:06 common.json
-rw-r--r-- 1 consul consul 117 Dec  3 04:49 connection.json
-rw-r--r-- 1 consul consul  84 Dec  3 04:49 server.json
-rw-r--r-- 1 consul consul 259 Dec  3 04:49 supervisord.json
/home/consul/consul_1.0.1/consul.d/common.json
{
  "datacenter": "dc1",
  "data_dir": "/home/consul/consul_1.0.1/data",
  "encrypt": "xxxxxxxxxxxxxxx", // consul keygenで発行した値を使用。
  "log_level": "info",
  "enable_syslog": true,
  "enable_debug": true,
  "node_name": "server01",
  "leave_on_terminate": false,
  "skip_leave_on_interrupt": true,
  "enable_script_checks": true, // ここtrueでないと、check script実行できない
  "rejoin_after_leave": true
}
/home/consul/consul_1.0.1/consul.d/connection.json
{
  "client_addr": "0.0.0.0",
  "bind_addr": "xxx.xxx.xxx.xxx", // 自身のprivate ip
  "ports": {
    "http": 8500,
    "server": 8300
  }
}
/home/consul/consul_1.0.1/consul.d/server.json
{
  "server": true, // server側なので、true
  "server_name": "server01",
  "bootstrap_expect": 1 // とりあえず、serverは1台クラスタにした
}
/home/consul/consul_1.0.1/consul.d/supervisord.json
{
  "services": [
    {
      "id": "supervisord-server01",
      "name": "supervisord",
      "tags" : [ "common" ],
      "checks": [{
        "script": "/etc/init.d/supervisord status | grep running",
        "interval": "10s"
      }]
    }
  ]
}

consul自体もsupervisordで起動します。

/etc/supervisor.d/consul.conf
[program:consul]
command=/home/consul/consul_1.0.1/bin/consul agent -config-dir=/home/consul/consul_1.0.1/consul.d -ui // -uiをつけて、uiも含めて起動。
user=consul
group=consul
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stdout_logfile=/home/consul/consul_1.0.1/logs/consul.stdout.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
stderr_logfile=/home/consul/consul_1.0.1/logs/consul.stderr.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=10

agent側(管理したいdaemonが起動するサーバー側)

/home/consul/consul_1.0.1/consul.d/common.json
{
  "datacenter": "dc1",
  "data_dir": "/home/consul/consul_1.0.1/data",
  "encrypt": "xxxxxxxxxxxxxxx", // server側と同じencrypt
  "log_level": "info",
  "enable_syslog": true,
  "enable_debug": true,
  "node_name": "agent01",
  "leave_on_terminate": false,
  "skip_leave_on_interrupt": true,
  "enable_script_checks": true,
  "rejoin_after_leave": true,
  "retry_join": ["provider=aws tag_key=Service tag_value=consulserver region=us-west-2 access_key_id=xxxxxxxxxxxxxx secret_access_key=xxxxxxxxxxxxxxx"
  // retry joinでserver側と接続。serverのcluster化も考慮して、provider=awsで、tag_keyを指定。
]
  }
/home/consul/consul_1.0.1/consul.d/connection.json
{
  "client_addr": "0.0.0.0",
  "bind_addr": "xxx.xxx.xxx.xxx", // 自身のprivate ip
  "ports": {
    "http": 8500,
    "server": 8300
  }
}
/home/consul/consul_1.0.1/consul.d/daemon.json
{
  "services": [
        {
      "id": "<daemon-name>-agent01",
      "name": "<daemon-name>",
      "tags" : [ "daemon" ],
      "checks": [{
        "script": "supervisorctl status daemon:<daemon-name> | grep RUNNING",
        "interval": "10s"
      }]
    }
  ]
}
/home/consul/consul_1.0.1/consul.d/supervisord.json
{
  "services": [
    {
      "id": "supervisord-agent01",
      "name": "supervisord",
      "tags" : [ "common" ],
      "checks": [{
        "script": "/etc/init.d/supervisord status | grep running",
        "interval": "10s"
      }]
    }
  ]
}

agent側もsupervisordで管理

/etc/supervisor.d/consul.conf
[program:consul]
command=/home/consul/consul_1.0.1/bin/consul agent -config-dir=/home/consul/consul_1.0.1/consul.d // -uiは不要
user=consul
group=consul
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stdout_logfile=/home/consul/consul_1.0.1/logs/consul.stdout.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
stderr_logfile=/home/consul/consul_1.0.1/logs/consul.stderr.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=10

cesi

image2.png

こちらのrepoから拝借させていただきました :bow:
基本的な設定は、README.mdに記載されている通り、セットアップします。

/etc/cesi.conf
[node:server01]
username = hogehoge
password = fugafuga
host = xxx.xxx.xxx.xxx // 対象nodeのprivate ip
port = 9001

[node:test01]
username = hogehoge
password = fugafuga
host = xxx.xxx.xxx.xxx // 対象nodeのprivate ip
port = 9001

[cesi]
database = /path/to/cesi-userinfo.db
activity_log = /path/to/cesi-activity.log
host = 0.0.0.0

(ansibleのroleにもしておく。)
cesiのコマンドも簡単にsupervisordで管理する様に設定します。

/etc/supervisor.d/cesi.conf
[program:cesi]
command=python /var/www/cesi/web.py
user=root
group=root
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stopasgroup=true
stopsignal=QUIT
stdout_logfile=/root/cesi.stdout.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
stderr_logfile=/root/cesi.stderr.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=10

スクリーンショット 2017-12-10 1.51.12.png

うん、いい感じに画面でてますね。
ただ、この画面の欠点としてnodeが増えるたびに、
都度、 /etc/cesi.confを書き換えては
webサーバーを再起動しなければならない欠点がありました。
なので
今生きているサーバーは何があるのかを把握する必要がありました。
 → まさにサービスディスカバリ。
そこで、設定ファイルの書き方もある一定柔軟にテンプレート化できる
consul-tamplteの登場です。

consul-template

ここも同様にして、ansibleで導入します。
https://github.com/juwai/ansible-role-consul-template
あとは、いい感じに公式ドキュメントをみながら、templateを書けばok。

[root@agent01 config]# ll
total 8
-rwxr-xr-x 1 root   root    220 Dec  4 05:16 consul-template.cfg
/home/consul/consul-template/config/consul-template.cfg
consul = "127.0.0.1:8500"
wait = "10s"

template {
  source = "/home/consul/consul-template/templates/cesi.conf.tmpl"
  destination = "/etc/cesi.conf"
  command = "supervisorctl restart cesi"
  command_timeout = "60s"
}
/home/consul/consul-template/templates/cesi.conf.tmpl
{{range service "supervisord"}}
[node:{{.Node}}]
username = hogehoge
password = fugafuga
host = {{.Address}}
port = 9001

{{end}}

[cesi]
database = /path/to/cesi-userinfo.db
activity_log = /path/to/cesi-activity.log
host = 0.0.0.0

上記のように、consul-tamplateの中で
{{.Node}}という値を入れていれば
consulでsupervisordのnode追加・更新をトリガーとして
consul-templateが起動し

  1. /etc/cesi.confの設定ファイルの更新
  2. cesiのwebserverの再起動

が実現でき、ダッシュボードにて、supervisordが、管理できるようになります。

また
consul-templateは、daemonとして起動しておくものなので
consul-templateもまた、supervisordで管理します。

/etc/supervisor.d/consul-template.conf
[program:consul-template]
command=/home/consul/consul-template/bin/consul-template -config /home/consul/consul-template/config/consul-template.cfg
user=root
group=root
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stdout_logfile=/home/consul/consul-template/logs/stdout.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=10
stderr_logfile=/home/consul/consul-template/logs/stderr.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=10

早速、実際サーバーを立ててみると…

スクリーンショット 2017-12-10 1.48.57.png

うん、いい感じにサーバーの台数が8->9台に増えてますね。
感覚的にも、増えるとほぼ同時に画面側も更新されてるので
結構いい感じです。(減らした時も同じ感じでした。)

めでたしめでたし。

やってみて、感じたこと

Good

  1. 各サーバーのプロセスの可視化できると確かに「なんか」安心する。
  2. サーバー入らずに、プロセスのstart/stop/restartできるのは、運用的にもセキュリティ的にも楽。
  3. supervisordは、探しても記事とかあまりない?気がするが、本当にプロセスを「管理」するのであれば、感覚的には、まぁまぁ使えるんじゃないかと感じた。
  4. consul-templateの柔軟性が高く、consulの設計次第でなんでもできる感じがよい。
  5. 遊び半分で作ってみたが、思ったより評判はよさげだった笑

Not Good

  1. supervisord自体のプロセス監視がうまいことできていない。
  2. まだまだsupervisordの設定周りを理解しきれていない。。。
     ※ ネットワーク/権限/セキュリティ周りのところが今後の課題。。usernameとかなんか一致してなくても、取れちゃってる・・・?笑
  3. consulもまだまだ使えていない。。。
  4. cesiもいい感じだが、挙動不審なところが若干ある。笑
    ※ 他のダッシュボードもレガシー感がすごくて、あまり、、、supervisordのもういい感じの画面がほしいな。
    http://supervisord.org/plugins.html#dashboards-and-tools-for-multiple-supervisor-instances

さいごに

プロセスって結構気づいたら落ちている気がしますが
(「いや、お前のツールに対する理解が浅いだけだろ!」っていうツッコミはやめてください笑)

単純にダッシュボードという形で
「可視化」して、人の目との接触回数が増えるだけでも
保守/運用性は高まる気がするので
やっぱりダッシュボード的なのはいいなと思いました^^

p.s.
色々と設定ファイルを記載していますが
「ん?ここおかしくないか?」というところがあれば
ぜひ、コメントお願いいたします :bow:

続きを読む

Developers.IO

【新機能】AWS Single Sign-On サービスを早速使ってみました!これを待ってた! | Developers.IO. はじめに こんにちは植木和樹@上越妙高オフィスです。本日AWSの新機能 AWS Single Sign-On (以下 AWS SSO)が発表されました! AWS Single Sign-On – Cloud SSO Service – AWS AWS Organizations, AWS … 続きを読む

`ionic start`の"aws"って何なの? – ionic-angular AWS Mobile Hub Starterを使ってみた

:christmas_tree: オープンストリーム Advent Calendar 2017 の 9 日目です :santa::christmas_tree:

ionic startの”aws”って何なの?

みなさんは ionic start でIonicのプロジェクトを始めるとき、”aws”の文字を見て気になったことはありませんか?:confused:

ionic start aws

そうです、これです。
“ionic-angular AWS Mobile Hub Starter” とありますね。

今回はこの “aws” で生成されるIonicプロジェクト(Starter)について見て・触れてみようと思います。

AWS Mobile Hubとは?

先ほどの通り ionic startの”aws”で生成されるプロジェクトは AWS Mobile Hub に関係するプロジェクトです。

AWS Mobile Hubとは、ブラウザの操作だけでAWSを用いたモバイルアプリ開発がすぐスタートできるサービスになります。

画面は英語表記ですが(2017/12現在)、AWSのサービス名を知らなくとも、
:grinning:「Facebookのアカウント一つでアプリが使えるようにしたい!」
:smiley_cat:「スマートフォンで通知を受け取るアプリを作りたい!」
など、実現したいことに従ってクリックするだけで、AWSのサービスが展開されて機能がすぐに実現できます。

「モバイルアプリケーションを最短の時間で構築する方法」とある通りですね!

AWS Mobile Hubの詳細はこちらになります。

AWS Mobile Hub(モバイルアプリケーションの構築、テスト、モニタリング)| AWS
https://aws.amazon.com/jp/mobile/

なお、Mobile Hubを実際に使った説明やサンプルは他の記事に譲ります。

プロジェクト開始直後を見てみる

blank を選んだときと比べ、プロジェクトのルートには cors-policy.xml, mobile-hub-project.zip が追加されています。

mobile-hub-project.zip は、このプロジェクトで使うAWSのリソースの設定が格納されています。
このプロジェクトのためにAWSをセットアップするために必要となります。

$ ls -l
-rw-r--r--    1 ysd  staff    3622 Dec  7 14:00 README.md
-rw-r--r--    1 ysd  staff    6173 Dec  7 23:02 config.xml
-rw-r--r--    1 ysd  staff     539 Dec  7 14:00 cors-policy.xml
-rw-r--r--    1 ysd  staff     113 Dec  7 23:02 ionic.config.json
-rw-r--r--    1 ysd  staff     775 Dec  7 14:00 mobile-hub-project.zip
drwxr-xr-x  470 ysd  staff   15980 Dec  7 23:02 node_modules
-rw-r--r--    1 ysd  staff  174985 Dec  7 23:02 package-lock.json
-rw-r--r--    1 ysd  staff    1125 Dec  7 23:01 package.json
drwxr-xr-x    7 ysd  staff     238 Dec  7 23:02 resources
drwxr-xr-x   10 ysd  staff     340 Dec  7 23:01 src
-rw-r--r--    1 ysd  staff     576 Dec  7 14:00 tsconfig.json
-rw-r--r--    1 ysd  staff     178 Dec  7 14:00 tslint.json

さらに src/assets の中にあらかじめAWSのJavaScript SDKが入っていました。

$ ls -l ./src/assets
total 10712
-rw-r--r--  1 ysd  staff    43875 Dec  7 14:00 amazon-cognito-identity.min.js
-rw-r--r--  1 ysd  staff   317909 Dec  7 14:00 amazon-cognito-identity.min.js.map
-rw-r--r--  1 ysd  staff   510404 Dec  7 14:00 aws-cognito-sdk.js
-rw-r--r--  1 ysd  staff   259601 Dec  7 14:00 aws-cognito-sdk.min.js
-rw-r--r--  1 ysd  staff   346715 Dec  7 14:00 aws-cognito-sdk.min.js.map
-rw-r--r--  1 ysd  staff  2658078 Dec  7 14:00 aws-sdk.js
-rw-r--r--  1 ysd  staff  1285371 Dec  7 14:00 aws-sdk.min.js
drwxr-xr-x  3 ysd  staff      102 Dec  7 23:01 icon
drwxr-xr-x  3 ysd  staff      102 Dec  7 23:01 imgs
-rw-r--r--  1 ysd  staff    51794 Dec  7 14:00 ionic-aws-logo.png

プロジェクトのルートに配置されるファイルと package.json で導入されるパッケージから、 https://github.com/ionic-team/starters/tree/master/ionic-angular/official/aws の内容が展開されるようです。

AWS Mobile Hub Starterを使ってみる

次に、プロジェクト同梱の README.md に従ってAWS Mobile Hub Starterを使ってみましょう。

pip, AWS CLIをインストールする

この後のステップでAWS CLIが必要になります。ターミナルを開いて次のコマンドを実行します。

$ pip install --upgrade pip
$ pip install awscli

Mobile Hub を始める

このサンプルで使うAWSのリソースをセットアップするために AWS Mobile Hub を使います。Mobile Hubでプロジェクトを作成し、このプロジェクトで使う/作成するAWSのリソースをまとめます。

Mobile Hubのコンソールを開くとプロジェクトの一覧が表示されます。ここで目につく Create や + Create Project を押したくなりますが、その隣の Import ボタンをクリックします。

Mobile Hub top

Importボタンを押すと、次のようにimportするプロジェクトの設定画面が表示されます。
ここで mobile-hub-project.zip を使います!

“Import your Mobile Hub project zip file” にある “You can also drag and drop your file here” にこの mobile-hub-project.zip をドラッグします。

Mobile Hub Import

AWS Mobile Hub Starterで使うAWSのリソースが mobile-hub-project.zip にあらかじめ記述されているため、このファイルからプロジェクトをインポートすることでAWSのリソースをセットアップできます。

その他の項目は次の通りになります。

  • Enter a name for your Mobile Hub project: Mobile Hubのプロジェクト名になります。 ionic start で設定したプロジェクト名でも可能です
  • Allow AWS Mobile Hub to administer resources on my behalf: Mobile HubでAWSのリソースをセットアップできるようにチェックを入れます
    • 既にMobile Hubを使っている場合は表示されないことがあります
  • Resources for your project will be created: リージョン名をクリックすると、Mobile HubでセットアップされるAWSのリソースのリージョンを指定することができます

設定例としてこのようになります :bulb:

Mobile Hub import sample.png

設定値を入力したら Import project ボタンをクリックします。
クリックするとAWSのリソースが一括で作成されます。1-2分ほどかかります。

完了するとMobile Hubのプロジェクトが開きます。

ここで作成されたAWSのリソースを見ると、
Amazon Pinpoint のプロジェクトが作成され…………(プッシュ通知などに使います)

Amazon Cognitoのユーザープールが作成され…………(ユーザーの認証などに使います)

Amazon Cognitoのフェデレーティッドアイデンティティが作成され…………(ユーザーの認証などに使います)

Amazon S3のバケットが3つ作成され…………(アプリの配布やユーザーデータの保存などに使います)

Amazon CloudFrontのディストリビューションが作成され…………(アプリの配布などに使います)

Amazon DynamoDBのテーブルが作成され…………

IAMロールが4つ作成されました。

通常はこのMobile Hubの画面で各項目を一つずつクリックして設定するところ、このAWS Mobile Hub Starterを使うことで一度に設定できます。

恐ろし… 一通りそろって便利ですね! ※この段階では無料利用枠に収まります。

料金 – AWS Mobile Hub | AWS
https://aws.amazon.com/jp/mobile/pricing/

AWS Mobile Hub Starterでセットアップされないリソース

先ほどの方法でMobile Hubがセットアップしないリソースは次の2つです。

  • Cloud Logic: Amazon API Gateway + AWS Lambda
  • Conversational Bots: Amazon Lex

Cloud Logicはモバイルアプリから送信されたデータを、サービス側で処理する……構造が実現できます。
一方のConversational Botsは、自動で会話できるチャットボットを作成するサービスになります。2017/12現在で米国英語のみの対応になりますが、アプリと会話して注文を受け付ける機能 :shopping_bags: などが実現できます。

Mobile Hubから aws-config.js をダウンロードする

しかし、設定はまだ終わっていません。 先ほど作成されたS3バケットが次の設定で重要になります。


(再掲)

hosting-mobilehub を含むS3バケットの名前を記録します。
そして、Ionicのプロジェクトに戻り、 BUCKET_NAME を先ほどのS3バケットの名前に置き換えて aws-config.js をダウンロードします。

aws s3 cp s3://BUCKET_NAME/aws-config.js src/assets

この例では次の通りになります。

$ aws s3 cp s3://myawsionic-hosting-mobilehub-1404708309/aws-config.js src/assets
download: s3://myawsionic-hosting-mobilehub-1404708309/aws-config.js to src/assets/aws-config.js

この、 aws-config.js はMobile Hubで作成されたAWSリソース達のARNが記録されています。
「モバイルアプリがアップロードしたファイルをどこのS3バケットに配置すべきか」などが決まります。

ユーザーがS3バケットにファイルをアップロードできるようにする

AWS Mobile Hub Starterの初期状態は、アプリを使っているユーザーがS3バケットにファイルをアップロードできる機能がありますが、この機能を使うためにはアップロード先のS3バケットで設定が必要になります。

userfiles を含むS3バケットを開きます。
次に、アクセス権限 -> CORSポリシー を開き、 README.md で説明された内容 もしくはプロジェクトルートにある cors-policy.xml の内容に差し替えて「保存」ボタンをクリックします。

userfiles S3 CORS setting

実行する

プロジェクトのルートで ionic serve を実行するとブラウザで動きを確認することができます。

ユーザーアカウントの登録

ionic serve 実行後に開くブラウザではログイン画面が表示されますが、AWSやIonic Proのアカウントを入力するわけではなく、このアプリ用のユーザーアカウントを登録します。

Login screen

“Create one.”のリンクをクリックし必要な項目を入力するとアカウントの登録ができますが、次のステップで確認コードがメールで送られてそれを入力する必要があるためメールアドレスが適当すぎると詰みます。
(詰んだ場合はブラウザをリロードするとログイン画面に戻ります)

email confirm screen

ユーザー登録完了後は特に何も表示されることなくログイン画面に遷移します。

ここで Amazon Cognitoのユーザープールを見るとユーザーが作成されていることや、確認コード入力の時点で詰んだことがわかります。

Cognito User Pool

タスクを追加する

ログインできると”Tasks”の画面が表示されます。

tasks screen

右上にある 「+」 ボタンをクリックして項目を追加できます。

input tasks screen

inputed tasks screen

項目を追加した後にAmazon DynamoDBを見ると、データベースに先ほどの内容が記録されていることが分かります。

DynamoDB Table Contents

ユーザーの写真を更新する

Settings -> Account を開き,「CHANGE PHOTO」をクリックするとユーザーの写真を更新することができます。

account edit screen

正しく更新されると即時反映されます。反映されない場合はS3バケットのCORSポリシーの設定を再度確認します。

ここでは userfiles を含むS3バケットを見るとユーザーの写真がアップロードされていることが分かります。 protected のディレクトリにあります。

結論(ionic startの”aws”って何だったの?)

AWSのサービスを用いたToDoアプリができるひな形になります。

Settings -> About this app を確認すると、実際に次のサービスが使われている旨が表示されます。

  • Cognito
  • DynamoDB
  • S3

言い換えると、AWS Mobile Hub StarterからIonicのプロジェクトをスタートすると、この3つのサービスがアプリ内ですぐに利用できます。

AWS Mobile Hub Starterを動かすだけで長くなりましたが、Ionicを使うと少し手を動かすだけで

  • ユーザー登録時に確認コードでメールアドレスの所在が保証でき
  • DynamoDBでクラウドに内容が保存できる
  • ToDoアプリ

が作れました! :smiley:

おわりに

……と言いたいのですが、動かしただけではAWS Mobile Hub Starterからどのようにアプリにしていくのか分かりにくいですね?

そこで、この先は AWS Mobile Hub Starterで用意されたAmazon PinpointとFirebaseを組み合わせてAndroidのプッシュ通知を受け取るサンプル を作ろうとしましたが、

AWSブログにて紹介されている方法でFirebaseの送信者IDを入れると、トークン取得の段階で次のエラーが出て正しく動作させることができませんでした。

console.error: Error with Push pluginError: AUTHENTICATION_FAILED

Push Notifications with Ionic and Amazon Pinpoint | AWS Mobile Blog
https://aws.amazon.com/jp/blogs/mobile/push-notifications-with-ionic-and-amazon-pinpoint/

その他の方法を調べましたが、Androidのビルド環境の問題なのかビルドができませんでした :confused:

Mobile HubでセットアップされるAWSの各サービスのドキュメントを読んでも、先ほどのAWSブログ以外にIonicを用いた実装例が見つかりませんでした。
そのため、「せっかく用意したPinpointでプッシュ通知を使ってみたい」「メールアドレスではなくFacebookとCognitoとIonicでユーザー登録を実現したい」など、IonicのAWS Mobile Hub Starterのコードで用意された範囲を超えるのは非常に難しい印象でした(個人の感想です)

紹介できなかったCloud Logicについても試してみたかったのですが、次回の機会に……

翌日 10 日目は @granoeste さんです!

セットアップしたAWSリソースのクリーンアップ

プロジェクトが不要な場合は、Mobile Hubコンソールのトップ画面から操作します :bulb:

削除したいプロジェクトの右上に「…」がありますので、カーソルを合わせて「Delete」をクリックします。

Mobile HubでセットアップされたAWSリソースが削除されアクセス拒否される旨の確認ダイアログが表示されるので、「Delete project」ボタンをクリックするとMobile Hubのプロジェクトが削除されます。

MobileHub project delete confirm dialog

しかし、完全にAWSリソースが削除されないため注意が必要です。

削除されるAWSリソース

  • Amazon Pinpoint のプロジェクト
  • Amazon Cognitoのフェデレーティッドアイデンティティ
  • Amazon S3のバケット(userdata, deployments)
  • プロジェクトに関わるIAMロール

削除されないAWSリソース

  • Amazon Cognitoのユーザープール
  • Amazon CloudFrontのディストリビューション
  • Amazon DynamoDBのテーブル
  • Amazon S3のバケット(hosting)
  • Mobile Hubのサービスが使うIAMロール

動作環境

今回の記事で使った環境はこちらになります :computer:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29

$ node -v
v8.1.4

$ npm -v
5.4.2

$ ionic --version
3.19.0

$ cordova --version
7.1.0

続きを読む