Arukasハンズオン資料 - サービス連携編

# はじめに

この記事は、

Arukasハンズオン受講希望者の方を対象とした、**サービス連携方法についての説明**です！

目標：**Arukasで起動したアプリと各種サービスとの連携方法を把握すること！**
難易度：**中級、上級**
所要時間：**30～40分**

どちらかと言えば上級者向けということで、細かい説明は色々と省いてます！

## 用語説明

* **API**： *Application Program Interface*。APIを利用すると、プログラムから各種機能を呼び出せる。
* **環境変数**： システム環境をカスタマイズするための変数。各種設定に利用できる。
* **公開鍵**： 公開鍵暗号方式で使用される一対の鍵のペアのうち、一般に公開されるほうの鍵。

## ハンズオン概要

**外部サービス連携が必要なアプリを [Arukas](https://arukas.io/) にデプロイして、各種サービスとの連携方法を理解する！**

## 構成概要図

**このハンズオンでは、以下の構成を構築します。**

![Arukas_intro_and_infra_JTF_private.001.png](https://qiita-image-store.s3.amazonaws.com/0/123644/6522aa8a-53af-410c-b1fc-0ec5b4001702.png)

* keychain.io（公開鍵管理API）: https://github.com/progrium/keychain.io
* SendGrid（メール配送サービス）: https://sendgrid.com
* Amazon S3（クラウドストレージサービス）: https://aws.amazon.com/jp/s3/

利用ユーザーは keychain.io に任意の公開鍵を登録、または取得する等の公開鍵の管理操作することができます。

## 各サービスの詳細

**keychain.io** には、下記の機能が実装されてます。

* ssh公開鍵の登録
* 登録済みssh公開鍵の照会

**SendGrid** は、以下の役割を担当します。

* 公開鍵の登録確認メールを鍵管理者に送信。

**Amazon S3** は、以下の役割を担当します。

* 公開鍵をバケットに格納。

## keychain.io 本体に必要とされる設定

```
AWS_ACCESS_KEY_ID=****      # AWS の API アクセスキー
AWS_SECRET_ACCESS_KEY=****  # AWS の API シークレットアクセスキー
SENDGRID_USERNAME=****      # SendGrid のユーザー名
SENDGRID_PASSWORD=****      # SendGrid のパスワード
KEYCHAIN_BUCKET_NAME=****   # Amazon S3 バケット名
```

## 注意事項

* **ハンズオン時間中、このハンズオンについては『任意課題』として非サポートです！エラーと遭遇しても自己解決を心がけましょう！**

# ハンズオン開始！

## AWS 側での作業

**keychain.io から Amazon S3 への接続には、`API アクセスキー` と `API シークレットアクセスキー` と `バケット名` が必要です。**

1. [AWS マネジメントコンソール](https://aws.amazon.com/jp/console/) にログインする。
2. IAM(Identity & Access Management) を開く。
3. `AmazonS3FullAccess` 権限を持つ専用グループを IAM で作成する。
4. 専用グループ配下に専用ユーザーを作成して、`API アクセスキー` と `API シークレットアクセスキー`を新規発行してどこかにメモしておく。
5. Amazon S3 にバケットを新規作成する。作成した `バケット名` をどこかにメモしておく。

ここまでで AWS 側での作業は完了です！

## SendGrid 側での作業

**keychain.io から SendGrid への接続には、SendGrid の `ユーザー名` と `パスワード` が必要です。**

1. [SendGrid のサインアップページ](https://sendgrid.com/pricing/) から `Free Plan` を選択してサインアップ。
2. SendGrid の `ユーザー名(USERNAME)` と `パスワード(PASSWORD)`をメモしておく。
3. SendGridから確認メールが到着するのでメールを確認してサインアップを完了する。
4. さらに[SendGrid のログインページ](https://sendgrid.com/login) にログインして、必要事項を入力してログインを完了する。

ここまでで SendGrid 側での作業は完了です！

## Arukas 側での作業

**keychain.io をアプリ作成しましょう！**

![arukas_keychain.png](https://qiita-image-store.s3.amazonaws.com/0/123644/26333981-666a-044b-a21a-9689f57af739.png)

**次の項目を間違えずに入力してください！**

> **APP Name**（アプリの名前）**：** `keychain.io`
> **Image**（Dockerイメージ名）**：** `uzyexe/keychain:0.0.1`
> **Endpoint**（エンドポイント）**：** お好みで名前を英数字で入力してください。
> **Port**（アプリのポート番号）**：** `5000` `tcp`
> **ENV #1**（環境変数 #1）**：** `PORT` = `5000`
> **ENV #2**（環境変数 #2）**：** `AWS_ACCESS_KEY_ID` = `AWS の API アクセスキー`
> **ENV #3**（環境変数 #3）**：** `AWS_SECRET_ACCESS_KEY` = `AWS の API シークレットアクセスキー`
> **ENV #4**（環境変数 #4）**：** `SENDGRID_USERNAME` = `SendGrid のユーザー名`
> **ENV #5**（環境変数 #5）**：** `SENDGRID_PASSWORD` = `SendGrid のパスワード`
> **ENV #6**（環境変数 #6）**：** `KEYCHAIN_BUCKET_NAME` = `Amazon S3 のバケット名`

## 公開鍵の登録

**下記のような `curl` コマンドを実行すると、`keychain.io` に公開鍵を渡します。**

``` bash:command
curl -s -X PUT -F key="@$HOME/.ssh/id_rsa.pub" "https://${ARUKAS_ENDPOINT_URL}/${EMAIL}/default

# コマンド例
curl -s -X PUT -F key="@$HOME/.ssh/id_rsa.pub" "https://endpoint.arukascloud.io/foo@example.com/default
```

* `key=""` には、登録したい公開鍵の場所をパスをフルパスで記入。
* `$(ARUKAS_ENDPOINT_URL}` には、Arukas で発行したエンドポイントURLを記入。
* `${EMAIL}` には、利用可能なメールアドレスを記入。

※ 公開鍵を作成されていない人は、`ssh-keygen` コマンドで鍵を作成ください。

**上記コマンドの実行に成功すると、以下のメッセージが表示されます。**

``` bash:output
Key received, check email to confirm upload.
```

すぐに公開鍵を登録したメールアドレス宛に登録確認メールが到着するので、登録確認メール内にある登録確認用のURLをクリックして `Action completed` と表示されたら公開鍵の登録は完了です。

### 公開鍵登録時にエラーメッセージが表示された場合

**SendGrid 側のSSL証明書の不具合が原因で、以下のような SSL Error が表示されることがあります。**

``` bash:output
SSLError: [SSL: UNKNOWN_PROTOCOL] unknown protocol (_ssl.c:590)
```

この場合、curlコマンドの再試行を繰り返してください。

## 公開鍵の取得

**下記のような `curl` コマンドを実行すると、`keychain.io` から公開鍵を取得できます。**

``` bash:command
curl https://${ARUKAS_ENDPOINT_URL}/${EMAIL}/all

# コマンド例
curl https://endpoint.arukascloud.io/foo@example.com/all
```

* `$(ARUKAS_ENDPOINT_URL}` には、Arukas で発行したエンドポイントURLを記入。
* `${EMAIL}` には、利用可能なメールアドレスを記入。

**上記コマンドの実行に成功すると、以下のような公開鍵が表示されます。**

``` bash:output
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB....
```

### 公開鍵取得時のエラー

**下記のようなトレースバックが表示された場合には、`ENV` に設定した AWS 関連の設定に誤りがあります。**

```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/eventlet/wsgi.py", line 382, in handle_one_response
    result = self.application(self.environ, start_response)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "keychain/app.py", line 153, in all_keys
    keys_ = lookup_keys(email)
  File "keychain/app.py", line 55, in lookup_keys
    keys = s3keys(email)
  File "keychain/app.py", line 41, in s3keys
    b = s3.get_bucket(bucket_name)
  File "/usr/lib/python2.7/site-packages/boto/s3/connection.py", line 389, in get_bucket
    bucket.get_all_keys(headers, maxkeys=0)
  File "/usr/lib/python2.7/site-packages/boto/s3/bucket.py", line 367, in get_all_keys
    '', headers, **params)
  File "/usr/lib/python2.7/site-packages/boto/s3/bucket.py", line 334, in _get_all
    response.status, response.reason, body)
S3ResponseError: S3ResponseError: 403 Forbidden
```

# まとめ

* Arukas に keychain.io をホストできた！
* Dockerイメージ側で SendGrid や Amazon S3 に対応している場合は API キーを渡せば連携することができる。
* API アクセスキーやユーザー名、パスワードは ENV に設定するとアプリの環境変数として渡すことができる。


# サービス連携編 - 完

* **[前のハンズオンに戻る（Arukasハンズオン資料 - おまけ編）](http://qiita.com/uzyexe/items/e0c34959ed22b81e535a)**