かべぎわブログ

ブログです

AWSの月間利用料を取得するPythonを書いた

概要

PythonでAWSの月間利用料を取得するスクリプトをかきました。
今回のものは他のPythonスクリプトから読み込ませることも意識しています。

成果物

これです。 github.com

usage

Command line

python get_monthly_cost.py --help
usage: get_monthly_cost.py [-h] [--profile [PROFILE]] [--year [YEAR]]
                           [--month [MONTH]]

optional arguments:
  -h, --help           show this help message and exit
  --profile [PROFILE]  Use a specific profile from your credential file.
  --year [YEAR]        Sets the year for retrieving AWS costs.
  --month [MONTH]      Sets the month for retrieving AWS costs.
$ python get_monthly_cost.py
9.4029780888 USD
$ python get_monthly_cost.py --year 2020 --month 1
10.2359175577 USD

Programming

import get_monthly_cost
response = get_monthly_cost.cost().get()
# ('9.4029780888', 'USD')
import get_monthly_cost
response = get_monthly_cost.cost(2020,1).get()
# ('10.2359175577', 'USD')

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

  • 作者:小笠原 種高
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/11/07
  • メディア: 単行本(ソフトカバー)

CircleCIでLambda(Python)をsls deployする

概要

CircleCIでLambda(Python)をServerless Frameworkをつかってデプロイしてみます。
GitHubにCommitされるとCircleCIでsls deployしてAWSにデプロイするようなイメージ。

手順

手順です。

1. 事前準備

以下に役に立つページがあります。
手順5まですすめます。

www.kabegiwablog.com

2. CircleCIの設定ファイルを作成する

CircleCIの設定ファイルであるconfig.ymlを作成します。

mkdir .circleci
touch .circleci/config.yml

config.ymlの中身はこんなかんじ。
Serverless Frameworkをインストールして、serverless-python-requirementsをインストールして、sls deployするだけです。

version: 2
jobs:
  build:
    docker:
      - image: circleci/python:3.7.6-stretch-node-browsers
    working_directory: ~/repo
    steps:
      - checkout
      - run:
          name: Install Serverless CLI and dependencies
          command: |
            sudo npm install -g serverless
            npm install 
      - deploy: 
          name: Deploy
          command: |
            npm install --save serverless-python-requirements
            sls deploy 

3. CircleCIの設定

CircleCIからSetup Projectして、Commit契機でうごくようにしておきます。

4. CircleCIをうごかす

addしてcommitしてPushしてCircleCIをうごかします。

5. デプロイされる

デプロイできました。 f:id:kabegiwakun:20200202222554p:plain

おわりに

べんりですね

Serverless FrameworkでLambda(Python)をデプロイする

概要

Serverless FrameworkをつかってLambda(Python)をAWS環境にデプロイしてみます。

手順

手順です。

1. テンプレートを作成する

今回デプロイするAWS Lambda用のServerless Frameworkのテンプレートを作成します。

serverless create --template aws-python3 --name requests-test --path ./requests-test

できました。

ls -l ./requests-test
total 8
-rw-r--r--. 1 vagrant vagrant  497 Feb  2 07:16 handler.py
-rw-r--r--. 1 vagrant vagrant 3201 Feb  2 07:16 serverless.yml

2. Lambda(Python)のコードをかく

デプロイしたいLambdaのコードをかきます。
今回はhandler.pyを以下のように上書きしてしまいます。
requestsをつかってcurlするだけのPythonです。

import requests

def main(event, context):
    response = requests.get('https://www.kabegiwablog.com/')
    print(response)

if __name__ == '__main__':
  main('', '')

ローカルでちゃんと動作することがわかります。

 python3 ./handler.py 
<Response [200]>

3. 必要なパッケージをrequirements.txtにかく

このhandler.pyの実行に必要なパッケージをrequirements.txtに記載してあげます。

pip3 freeze | grep requests > ./requirements.txt

こんなかんじ。

$ cat requirements.txt 
requests==2.22.0

4. serverless.ymlを編集してあげる

serverless.ymlを以下のように編集してあげます。

service: requests-test

provider:
  name: aws
  runtime: python3.7
  region: ap-northeast-1

functions:
  requests-test-lambda:
    handler: handler.main

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true 

5. serverless-python-requirementsをインストールする

serverless-python-requirementsをインストールしてあげます。
これにより、requirements.txtで依存関係を自動的にバンドルしてくれます。

npm install --save serverless-python-requirements

6. AWS環境にデプロイする

いよいよデプロイです。
以下コマンドを実行してあげると、AWS環境にLambda関数がデプロイされます。
裏でCloudFormationがうごいています。

$ sls deploy

Serverless: Generated requirements from /home/vagrant/requests_test/requirements.txt in /home/vagrant/requests_test/.serverless/requirements.txt...
Serverless: Installing requirements from /home/vagrant/.cache/serverless-python-requirements/f866cf90d6349902a899d904a8c7724b092b63ed16fa2530c859ec177d70c68e_slspyc/requirements.txt ...
Serverless: Using download cache directory /home/vagrant/.cache/serverless-python-requirements/downloadCacheslspyc
Serverless: Running ...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Injecting required Python packages to package...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service requests-test.zip file to S3 (1.92 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.........
Serverless: Stack update finished...
Service Information
service: requests-test
stage: dev
region: ap-northeast-1
stack: requests-test-dev
resources: 6
api keys:
  None
endpoints:
  None
functions:
  requests-test-lambda: requests-test-dev-requests-test-lambda
layers:
  None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.

7. 確認

できました。
f:id:kabegiwakun:20200202171836p:plain

8. ゴミ掃除

removeで全削除できます。

sls remove

おわりに

べんりな世の中になりましたね。

AWSによるサーバーレスアーキテクチャ

AWSによるサーバーレスアーキテクチャ

  • 作者:Peter Sbarski
  • 出版社/メーカー: 翔泳社
  • 発売日: 2018/03/14
  • メディア: 単行本(ソフトカバー)

CloudFrontでS3に307リダイレクトされるときの下人と対処法

概要

CloudFrontでオリジンをS3にしているときに、設定は間違っていないのにCloudFrontのURLからS3のURLにリダイレクトされてしまって、Access Deiniedってなってんーーーーーーーーーー??????ってなるときの原因と対処法です。

原因

基本的に全部以下に書いてある。
Amazon S3 での HTTP 307 エラーをトラブルシューティングする

Amazon S3 バケットを作成後、そのバケット名がすべての AWS リージョンに伝達されるまで、最大で 24 時間ほどかかる場合があります。その間に、S3 バケットと同じリージョンにないリージョンのエンドポイントにリクエストすると、「307 Temporary Redirect」レスポンスが返る場合があります。

対処法

これも書いてある。
Amazon S3 での HTTP 307 エラーをトラブルシューティングする

Amazon S3 オリジンで Amazon CloudFront ディストリビューションを使用する場合、CloudFront はリクエストをデフォルトの S3 エンドポイント (s3.amazonaws.com) に転送します。このエンドポイントは、us-east-1 リージョンにあります。バケットを作成後 24 時間以内に Amazon S3 にアクセスする必要がある場合は、バケットのリージョンのエンドポイントが含まれるように、このディストリビューションのオリジンドメイン名を変更します。たとえば、バケットが us-west-2 にある場合は、オリジンドメイン名を bucketname.s3.amazonaws.com から bucketname.s3-us-west-2.amazonaws.com に変更することができます。

実際にOrigin Domain Nameをkabegiwa-test-bucket.s3-ap-northeast-1.amazonaws.comといった形にして5分くらいでちゃんとCloudFront経由でやりたいことが実現できた。

おわりに

意外とハマった。

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

CloudFront経由でのみS3のコンテンツにアクセスさせる

概要

CloudFrontのオリジンアクセスアイデンティティを使用して、CloudFront経由でのみS3バケット内のコンテンツにアクセスさせてみます。

手順

CloudFrontのオリジンの設定で以下のように設定します。
RestrictBucketAccessをYesに、
Origin Access IdentityをCreate a New Identityに、
Grant Read Permissions on BucketをYes, Update Bucket Policyにします。
f:id:kabegiwakun:20200123215915p:plain

すると以下のようにオリジンに設定したバケットのバケットポリシーが自動で設定されます。
f:id:kabegiwakun:20200123220516p:plain

確認

S3バケットに直接アクセスすると以下のようにAccess Deiniedになります。
f:id:kabegiwakun:20200123221206p:plain

しかし、CloudFrontのDNS名経由ではアクセスすることができます。
f:id:kabegiwakun:20200123224342p:plain

おわりに

セキュアですね。

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

AWSCLIでAWSアカウントを作成する

概要

AWSCLIを利用してAWSアカウントをコマンド一撃で作成してみます。

前提

  • AWS Organizationsのマスターアカウントである
  • アカウント作成の権限がある

コマンド

これでいけます。
アカウント名とルートアカウントのメールアドレスを指定してあげるだけです。

aws organizations create-account --email myemail@example.com --account-name kabegiwablog

おわりに

べんりですね

ECS上でApacheを動かしてアクセスする

概要

ECS上でApacheを動かしてアクセスするだけのおはなしです。
具体的には以下のような構成です。

f:id:kabegiwakun:20200121220734p:plain

手順

ALBを作成する

ECSに接続するLBを事前に作成しておきます。
リスナーをHTTPSで
ターゲットグループはポートを8080にします。ヘルスチェックは/healthで作成します。

ECSクラスタを作成する

ふつうにつくればもんだいないです。

タスク定義を作成する

ネットワークモードをbridgeにし、コンテナをhttpdで作成します。
また、ポートマッピングでホストポート8080をコンテナポート80にマッピングしておきます。

サービスの設定

サービスの設定で、さきほど作成したタスク定義を起動するように設定する。

動作確認

https://ALBのドメイン名でアクセスする。
It works!!!

おわりに

ワインをのみながらかいている。

ALBにACM/SSL証明書を関連付ける

概要

ALBにACM/SSL証明書を関連付けてみます。
画像のような感じです。
基本的なかたちですね。
f:id:kabegiwakun:20200119104941p:plain
ユーザからALBまではHTTPSで、ALBからEC2までの内部通信はHTTPです。

手順

1. ACMで証明書を取得する

以下ですこしやりました。

www.kabegiwablog.com

2. EC2インスタンスの作成と設定

ALBからのアクセスを受けるEC2インスタンスを設定してあげます。
セキュリティグループはALBからの通信を受けられるような設定のものをアタッチしてあげます。

3. ALBの作成と設定

以下のようなかんじの設定でALBを作成してあげます。

3.1. ロードバランサーの設定

名前: すきななまえ スキーマ: インターネット向け
IPアドレスタイプ: ipv4

リスナー: HTTPS

VPC: すきなVPC
アベイラビリティゾーン: すきなAZ

3.2. セキュリティ設定の構成

証明書タイプ: ACM から証明書を選択する
証明書の名前: 手順1 で取得した証明書の名前

3.3. セキュリティグループの設定

セキュリティグループ: インバウンドに任意の場所からHTTPSが許可されたものを選択

3.4. ルーティングの設定

ターゲットグループ: 新しいターゲットグループ
名前: すきななまえ
ターゲットの種類: インスタンス
プロトコル: HTTP
ポート: 80

ヘルスチェックのプロトコル: HTTP
ヘルスチェックのパス: /

3.5. ターゲットの登録

手順2で作成したインスタンスを登録済みに追加する。

4. EC2インスタンスの設定をする(Apache)

インスタンスにssh接続し、以下を実行してApacheの設定をしてあげます。

4.1. Apacheのインストール

sudo yum install -y httpd

4.2. ファイルの設置

sudo mkdir -p /var/www/html
sudo bash -c "echo 'wawawa' > /var/www/html/index.html"

4.3 Apacheの起動

sudo systemctl start httpd

5. ちょっとした確認

この時点でALBからインスタンスにアクセスできるかどうかを確認してみます。

5.1. ターゲットグループのステータスの確認

ターゲットグループのステータスがhealthyかどうかを確認します。

5.2. ALBのDNS名からブラウザでアクセス

ALBのDNS名からブラウザでアクセスして確認してみます。

https://ALBのドメイン名です。
証明書のドメインとALBのドメインが違うため、警告がでますが、無視してさきにすすみます。
wawawaと表示されればOKです。

6. Route53の設定

ALBのDNS名をコピーし、Route53にCNAMEとして追加してあげます。

ホストゾーン: ACM取得したドメイン

タイプ: Aレコード
エイリアス先: 作成したALB

7. 最終確認

ブラウザからドメイン名でアクセスします。
HTTPSで通信ができているはずです!!!

おわりに

べんりですね

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

  • 作者:山本 陽平
  • 出版社/メーカー: 技術評論社
  • 発売日: 2010/04/08
  • メディア: 単行本(ソフトカバー)

お名前.comで取得したドメインの証明書をACMで取得する

概要

お名前.comで取得したドメインの証明書をACMで取得してみます。

手順

こんなかんじの手順です。

1. Route53 Hosted Zoneを作成

Route53でACMを取得するドメイン名でHosted Zoneを作成します。
作成されたときにできるNSレコードを控えておきます。
次の手順で使います。

2. お名前.comでネームサーバを変更

続いて、お名前.comの[ドメイン設定]-[ネームサーバーの変更]へ遷移し、ACMを取得するドメインを選択、先の手順で控えたNSレコードを入力します。
f:id:kabegiwakun:20200118184818p:plain
インターネットの環境により、反映完了まで24時間から72時間程度かかる場合があるらしい。

3. ACMで証明書を取得

マネジメントコンソールから[証明書のリクエスト]であとは画面にそってしすすみます。
検証方法はDNSによる検証で良いと思います。
画面にそってすすんでステップ5で[Route53でのレコードの作成]を選択してRoute53にCNAMEレコードを追加してあげます。

4. 完了

できました。
f:id:kabegiwakun:20200118185543p:plain

おわりに

かんたんですね。

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

  • 作者:小笠原 種高
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/11/07
  • メディア: 単行本(ソフトカバー)

EKSクラスタを作成してpodをたてるまで

概要

EKSクラスタを作成してpodをつくるまでのメモです。

手順

手順です。

EKSクラスタの作成

こんなかんじ
podはひとつだけ
作成に10分くらいかかる

$ eksctl create cluster --name test --nodes 1

kubectlで使えるようにconfigに追記させる。

$ eksctl utils write-kubeconfig --name test --kubeconfig ~/.kubeconfig

確認

クラスタができている。

$ eksctl get cluster
NAME    REGION
test    ap-northeast-1

fargateではないのでnodegroupがインスタンスで動作している。

$ eksctl get nodegroup --cluster test
CLUSTER NODEGROUP   CREATED         MIN SIZE    MAX SIZE    DESIRED CAPACITY    INSTANCE TYPE   IMAGE ID
test    ng-67463005 2020-01-02T04:08:54Z    1       1       1           m5.large    ami-02e124a380df41614

podの作成

podをつくります。

$ kubectl create -f sample-pod.yaml

podの設定ファイル

apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: linux
      image: centos

確認

podができている。

$ kubectl get pods
NAME         READY   STATUS             RESTARTS   AGE
sample-pod   0/1     CrashLoopBackOff   8          10m

おわりに

むずかしいですね

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)

  • 作者:青山 真也
  • 出版社/メーカー: インプレス
  • 発売日: 2018/09/21
  • メディア: 単行本(ソフトカバー)

別のstateファイルの値を参照する

概要

リモートステートをつかって別のstateファイルの値を参照して見たいと思います。
これによって stateをまたいでいろいろできたりするのでstateの分離等もしやすくなるかもしれないしならないかもしれない。

EC2インスタンスを作成するstateと、それにEIPをアタッチするstateが別なんだけれどもアタッチができるよっていうのをやります。

前提

前提です。

バージョン

Terraformのバージョン等はこんなかんじ。

$ terraform --version
Terraform v0.12.18
+ provider.aws v2.43.0

EC2インスタンスをつくるstateのtfファイル

ひとつめのstateです。

provider "aws" {
  region = "ap-northeast-1"
}
terraform {
  backend "s3" {
    bucket = "mybucket"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}
resource "aws_instance" "example" {
  ami           = "ami-068a6cefc24c301d2"
  instance_type = "t3.micro"
  subnet_id     = aws_subnet.subnet.id
}
resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "subnet" {
  cidr_block = "10.0.1.0/24"
  vpc_id     = aws_vpc.main.id
}
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
}
output "instance_id" {
  value = aws_instance.example.id
}

EIPをアタッチするstateのtfファイル

2つめです。

provider "aws" {
  region = "ap-northeast-1"
}
data "terraform_remote_state" "remote_state" {
  backend = "s3"
  config = {
    bucket = "mybucket"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}
resource "aws_eip" "eip" {
  instance = data.terraform_remote_state.remote_state.outputs.instance_id
}

うごかしてみる

うごかしてみます

EC2インスタンスをつくるstateのtfファイル

こんなかんじになります。
参照される値はoutputで出力する必要があります。

$ terraform apply
~~~省略~~~
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

Outputs:

instance_id = i-02814f190bddac514

EIPをアタッチするstateのtfファイル

EIPがアタッチされていることがわかりますね

$ terraform apply
data.terraform_remote_state.remote_state: Refreshing state...
aws_eip.eip: Refreshing state... [id=eipalloc-08169d0c5eaa117f4]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_eip.eip is tainted, so must be replaced
-/+ resource "aws_eip" "eip" {
      + allocation_id     = (known after apply)
      + association_id    = (known after apply)
      ~ domain            = "vpc" -> (known after apply)
      ~ id                = "eipalloc-08169d0c5eaa117f4" -> (known after apply)
      + instance          = "i-02814f190bddac514"
      + network_interface = (known after apply)
      + private_dns       = (known after apply)
      + private_ip        = (known after apply)
      ~ public_dns        = "ec2-3-114-205-18.ap-northeast-1.compute.amazonaws.com" -> (known after apply)
      ~ public_ip         = "3.114.205.18" -> (known after apply)
      ~ public_ipv4_pool  = "amazon" -> (known after apply)
      - tags              = {} -> null
      ~ vpc               = true -> (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_eip.eip: Destroying... [id=eipalloc-08169d0c5eaa117f4]
aws_eip.eip: Destruction complete after 1s
aws_eip.eip: Creating...
aws_eip.eip: Creation complete after 1s [id=eipalloc-0bd8be7d66afa0c58]

Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

おわりに

べんりですね

Terraform: Up and Running: Writing Infrastructure as Code

Terraform: Up and Running: Writing Infrastructure as Code

  • 作者:Yevgeniy Brikman
  • 出版社/メーカー: O'Reilly Media
  • 発売日: 2017/04/04
  • メディア: ペーパーバック

tfstateファイルをS3バケットで管理する

概要

TerraformのtfstateファイルをS3バケットで管理してみます。
仕事でチームでやるときはだいたいこの設定でやると思う。

こんなかんじ

こんなかんじで設定してあげます。

terraform {
  backend "s3" {
    bucket = "mybucket"
    key = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}

terraform initするだけでtfstateファイルがS3バケットに格納されるようになります。

おわりに

tfstateファイルはGitで管理するよりこっちのほうが良いと思う。
pushとかpullしわすれたときの被害がでかいと思う。
その点、これは自動でやってくれるのでべんり。

Beanstalkで作成されたバケットができないときの対処法

概要

Elastic Beanstalkで作成されたS3バケットを削除しようとしたときに以下のようなエラーがでた。

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the DeleteBucket operation: Access Denied

権限は足りてるはずなのにおかしいなあと思ってすこしハマったのでメモ

原因

バケットポリシーに以下にようなポリシーが設定してあるため。
DeleteBucketをDenyしている。

{
    "Sid": "eb-58950a8c-feb6-11e2-89e0-0800277d041b",
    "Effect": "Deny",
    "Principal": {
        "AWS": "*"
    },
    "Action": "s3:DeleteBucket",
    "Resource": "arn:aws:s3:::elasticbeanstalk-ap-northeast-1-961262193080"
}

対処法

単純にバケットポリシーを削除してしまえばいい。

おわりに

意外とハマった

Amazon Web Servicesインフラサービス活用大全 システム構築/自動化、データストア、高信頼化 (impress top gear)

Amazon Web Servicesインフラサービス活用大全 システム構築/自動化、データストア、高信頼化 (impress top gear)

  • 作者:Michael Wittig,Andreas Wittig
  • 出版社/メーカー: インプレス
  • 発売日: 2019/09/05
  • メディア: 単行本(ソフトカバー)

TerraformでS3バケットを作成する(ランダムな数値列をサフィックスにして)

概要

Terraformでランダムな数値列をサフィックスにして、バケットの名前がかぶらないようにしつつ、バケットを作成してみます。

前提

terraformのバージョン等はこんなかんじ。

$ terraform --version
Terraform v0.12.18
+ provider.aws v2.43.0
+ provider.random v2.2.1

こんなかんじ

こんなかんじでできます。
randomプロバイダを利用します。

provider "random" {}

resource "random_integer" "suffix" {
    min = 10000000
    max = 99999999
}

resource "aws_s3_bucket" "bucket" {
    bucket = "kabegiwa-${random_integer.suffix.result}"
}

実行すると

こんなかんじでバケットが作成されます。

$ aws s3 ls
2019-12-28 18:51:25 kabegiwa-18721568

おわりに

べんりですね

Terraform: Up & Running: Writing Infrastructure As Code

Terraform: Up & Running: Writing Infrastructure As Code

  • 作者:Yevgeniy Brikman
  • 出版社/メーカー: Oreilly & Associates Inc
  • 発売日: 2019/10/08
  • メディア: ペーパーバック

TerraformでAWSのアカウント番号を利用する

概要

TerraformでAWSアカウント番号(アカウントID)を取得してみます。

前提

Terraformのバージョンはこんなかんじ。

$ terraform --version
Terraform v0.12.18
+ provider.aws v2.43.0

こんなかんじ

みんなだいすきcaller_identityです。

data "aws_caller_identity" "wawawa_id" {}

output "account_id" {
  value = data.aws_caller_identity.wawawa_id.account_id
}

おわりに

べんりですね。

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

  • 作者:前佛 雅人
  • 出版社/メーカー: インプレス
  • 発売日: 2015/10/22
  • メディア: Kindle版