AWS でデータベースのお金を節約する変な方法

今回の記事はこんな方におすすめです。

- AWS でデータベースを使いたいけど RDS はお金がかかるのでできるだけお金をかけたくない
- データベースを使う用事があるが、 1 テーブルあたりのレコード数が多くても数～数十程度である
- データストアが Key-Value Store である
- AWS で変なことがしてみたい

今回は AWS の VPC および Lambda (月 100 万リクエストまで) が無料であることを利用します。
(DynamoDB が 25 GB まで無料じゃないか、というツッコミはご遠慮ください)

## 今回作成するテーブル

為替レート一覧

- USD-JPY: 110
- EUR-JPY: 130

といった具合です。

## 前提条件

AWS のアカウントを持っていること

AWS のアカウント作成方法については省略させていただきます。

## VPC を作成する

[VPC 一覧](https://console.aws.amazon.com/vpc/home#vpcs:) へ移動し `Create VPC` をクリックします。

Name にはテーブル名に指定しようとしていた名前を入力しましょう。今回は `exchange-rate` とします。

IPv4 CIDR block には、まだ使っていない CIDR block を入力します。

![create_vpc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/d4809a32-e7af-4fb3-e0d8-507f98d59f9a.png)

作成したら、 VPC ID を書き留めておきましょう。

## サンプルデータを投入する

![create_tags.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/2e6a8cf8-8e85-8704-f9e2-37c81d94b54f.png)

VPC のタグを次のように作成します：

- `USD-JPY`: `109.62`
- `EUR-JPY`: `129.00`
- `CAD-JPY`: `85.79`
- `AZN-GBP`: `0.42`
- `KRW-MNT`: `2.46`

## 為替レートを取得する Lambda function を作成する

Lambda の管理画面へ移動し、 `Create function` をクリックします。

以下のように指定します。

- Option: `Author from scratch`
- Function name: `getExchangeRate`
- Runtime: `Python 3.8`

![create_function.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/812655d3-d8d2-1315-799f-e564768ac96f.png)

Lambda function の詳細画面に遷移したら、 `Configuration` タブを選択し、 `Permissions` を選択し、ロール名をクリックします。

![lambda_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/2b4569dc-a8c1-3df4-a366-80131362e675.png)

`Permissions` タブを選択し `Attach policies` をクリックします。

`AmazonVPCReadOnlyAccess` を選択し、チェックを入れて `Attach policy` をクリックします。

再び Lambda function の詳細画面に戻り、 `Code` タブをクリックします。

ファイルツリーから `lambda_function.py` をダブルクリックします。

コードを以下のように編集します。 `Your VPC ID` を書き留めておいた VPC ID に置き換えてください。

```python
import boto3
import json

def lambda_handler(event, context):
    ec2 = boto3.resource('ec2')
    vpc = ec2.Vpc('Your VPC ID')

    rate = {}
    for tag in vpc.tags:
        if tag['Key'] == event['Key']:
            rate = tag
            break

    return {
        'statusCode': 200,
        'body': json.dumps(rate)
    }
```

boto3 を使用した VPC の取得については [こちらのマニュアル](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#vpc) をご覧ください。

### 作成した Lambda function をテストする

`Test` タブをクリックし、テストデータを以下のように作成します。これは 1 ユーロが日本円でいくらなのかを取得する例です。

```json
{
  "Key": "EUR-JPY"
}
```

`Test` ボタンをクリックして動作確認しましょう。以下のように結果が表示されれば成功しています！

![lambda_execution_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486784/41dcc092-819a-ab6e-85f2-185f428459e1.png)

## 為替レートを更新する Lambda function を作成する (練習)

為替レートの取得の時と同様に Lambda function を作成します。先ほどとの違いは以下の通りです。
詳しくは書きませんので、自分でやってみましょう。

### ロールに必要なポリシー

VPC のタグへの書き込みが必要になりますので `AmazonVPCFullAccess` ポリシーを追加するとよいでしょう。

### コード

`vpc.create_tags` 関数を使ってタグの登録または上書きができます。

```python
vpc.create_tags(
    DryRun=False,
    Tags=[
        {
            'Key': event['Key'],
            'Value': event['Value'],
        }
    ]
)
```

> [fixer.io](https://fixer.io/) 等の API から最新の為替レートを取得して更新すると、よりリアリティが増します。
> Python から API へリクエストを送信するには urllib やサードパーティ製の requests ライブラリを使用します。
> requests ライブラリの方が簡潔に書けますが、 Lambda には標準で搭載されていません。パッケージを Zip でアップロードすると使えるようになります。
> 余力があればやってみましょう。

### テスト

Lambda function が完成したら、テストデータを以下のように作成して（または fixer.io から最新値を取得して）動作確認しましょう。

```json
{
  "Key": "EUR-JPY",
  "Value": "129.07"
}
```

タグが更新されたことを確認するには、為替レートを取得するスクリプトの結果を確認するとよいでしょう。

おつかれさまでした！

## まとめ

今回は為替レートを VPC のタグで管理するという、いかにも変な方法をご紹介しました。
いくら変な方法と言っても、 RDS を使うお金がない、 DynamoDB は不慣れ、などの心配事がある場合には十分有効な手段になり得ます。
また、 Lambda から AWS のリソースを取得・操作する練習としても使えると思いますので、 AWS のサービスを使いこなすための一つの題材として取り扱ってみてはいかがでしょうか。