20200117のAWSに関する記事は19件です。

AWS Amplify フレームワークの使い方Part5〜GraphQL Transform @model編〜

はじめに

Amplifyでの肝の部分であるAPI(AppSync = GraphQL)のスキーマ設計についてまとめていきます。その第一弾として、まず基本的な@modelの解説から行っていきます。

定義

@modelは以下のように定義されています。

directive @model(
    queries: ModelQueryMap,
    mutations: ModelMutationMap,
    subscriptions: ModelSubscriptionMap
) on OBJECT
input ModelMutationMap { create: String, update: String, delete: String }
input ModelQueryMap { get: String, list: String }
input ModelSubscriptionMap {
    onCreate: [String]
    onUpdate: [String]
    onDelete: [String]
    level: ModelSubscriptionLevel
}
enum ModelSubscriptionLevel { off public on }

解説

@modelの宣言をすることで、DynamoDBにテーブルが作成することができ、AppSyncで呼び出しができるように設定してくれます。
graphlqlフォルダが自動生成され、その中にqueries.jsmutations.jssubscriptions.jsが作られることで、CRUDが簡単に行えるようになります。

基本設定

下記の例では、idをプライマリーキーとして、Postテーブルが作成されます。

type Post @model {
    id: ID!
    title: String!
    tags: [String!]!
}

PostデータのCRUDするために、queries.jsにはgetPostlistPostmutations.jsにはcreatePostupdatePostdeletePostsubscriptions.jsにはonCreatePostonUpdatePostonDeletePostがそれぞれ自動生成されます。

具体的な使用方法については、別記事でまとめていますので、下記の記事をご確認ください。
AWS Amplify フレームワークの使い方Part4〜API実践編〜

詳細設定

@modelのあとに、記述を追加することで自動生成されるCURDを制御することができます。
下記のように記述した場合は、mutations.jssubscriptions.js内に自動生成なしでqueries.js内にgetPostのみが生成されます。

type Post @model(queries: { get: "post" }, mutations: null, subscriptions: null) {
    id: ID!
    title: String!
    tags: [String!]!
}

おわりに

もう少し細かい事もできるようですが、現状試しているのはここまでになります。@modelさえ使えれば、簡単なアプリはできてしまうので、一度は触ってもらうとわかりやすいと思います。

参考

GraphQL Transform(公式ドキュメント)

関連記事

AWS amplify フレームワークの使い方Part1〜Auth設定編〜
AWS Amplify フレームワークの使い方Part2〜Auth実践編〜
AWS Amplify フレームワークの使い方Part3〜API設定編〜
AWS Amplify フレームワークの使い方Part4〜API実践編〜

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Python3]datetimeにタイムゾーンを指定する。

PCでコーディングしたプログラムをAWSのLambda関数で実行したら、datetime.now()で取得される時刻が違うことに気づきました。PCはJST時間、AWSはUTC時間のため9時間の差があることが原因です。
プログラムを変えずにPCでもAWSのLambda関数でも同じ結果を得るために、datetimeにタイムゾーンを指定する方法を調べました。

環境

  • Python 3.7.4

問題の事象

例えば次のプログラムを実行すると、PCで取得される現在時刻と、AWSのLambda関数で取得される現在時刻に9時間の差異が発生します。9時間の差異なので、Lambda関数で実行するときには+ timedelta(hours=+9)として9時間足せばいいのだけれど、それではPCからLambda関数に持っていくときにプログラムの修正が発生するので望ましくないため、プログラムを変更せずに同じ結果が得られるようにしたいと考えました。

lambda_function.py
from datetime import datetime, timezone, timedelta

def lambda_handler(event, context):
    print(datetime.now())
    #PCとAWSのLambda関数で取得される時刻に9時間の差異が発生
    return

if __name__ == "__main__":
    event = None
    context = None
    lambda_handler(event, context)

解決策

datetimeにタイムゾーンを指定することで解決できます。Python3では標準ライブラリのdatetimeだけで解決できます。具体的には、datetimeオブジェクトを生成する際にtimezoneを指定します。
ただし、timezonetimezoneサブクラスから生成する必要があるため、そこでちょっと戸惑いました。
timezone = "Asia/Tokyo"とかではないということです。
「Pythonでは、すべてがオブジェクト」とかたまに見かけますが、こういうことなんですかね。

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    print(datetime.now(JST)) #タイムゾーンを指定して現在時刻を取得

注意点

datetimeオブジェクトを使った引き算、足し算をしている場合は、タイムゾーンを揃えておかないとTypeErrorが発生します。

TypeError: can't subtract offset-naive and offset-aware datetimes

こんな感じにすればOK

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    datetime.datetime(2020, 1, 31, tzinfo=JST) - datetime.datetime.now(JST)
#tzinfoでタイムゾーンを設定

もうひとつの解決策

ここまで調べた後で、もう一つの解決策があることを発見しました。
AWSのLambda関数の環境変数を変更する方法です。いろんなやり方があるのですね。

AWSのLambdaのタイムゾーンをUTCからJST(東京)に変更

なお、

Python3のdatetimeはタイムゾーンを指定するだけで高速になる

そうです。

「awareなdatetime」と「nativeなdatetime」

datetimeを調べる過程で、「awareなdatetime」や「nativeなdatetime」という言葉が出てきて戸惑いましたが、大まかには、

  • datetimeオブジェクトにタイムゾーンを指定する方法は、「awareなdatetime」
  • 実行環境(PC、AWSのLambda関数)のタイムゾーンを合わせる方法は、「nativeなdatetime」

ということみたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Python3]datetimeにタイムゾーンを指定するawareな方法

PCでコーディングしたプログラムをAWSのLambda関数で実行したら、datetime.now()で取得される時刻が異なることに気づきました。PCはJST時間、AWSはUTC時間のため9時間の差があることが原因です。
プログラムを変えずにPCでもAWSのLambda関数でも同じ結果を得るために、datetimeにタイムゾーンを指定する方法を調べました。

環境

  • Python 3.7.4

問題の事象

例えば次のプログラムを実行すると、PCで取得される現在時刻と、AWSのLambda関数で取得される現在時刻に9時間の差異が発生します。9時間の差異なので、Lambda関数で実行するときには+ timedelta(hours=+9)として9時間足せばいいのだけれど、それではPCからLambda関数に持っていくときにプログラムの修正が発生するので望ましくないため、プログラムを変更せずに同じ結果が得られるようにしたいと考えました。

lambda_function.py
from datetime import datetime, timezone, timedelta

def lambda_handler(event, context):
    print(datetime.now())
    #PCとAWSのLambda関数で取得される時刻に9時間の差異が発生
    return

if __name__ == "__main__":
    event = None
    context = None
    lambda_handler(event, context)

解決策

datetimeにタイムゾーンを指定することで解決できます。Python3では標準ライブラリのdatetimeだけで解決できます。具体的には、datetimeオブジェクトを生成する際にtimezoneを指定します。
ただし、timezonetimezoneサブクラスから生成する必要があるため、そこでちょっと戸惑いました。
timezone = "Asia/Tokyo"とかではないということです。
「Pythonでは、すべてがオブジェクト」とかたまに見かけますが、こういうことなんですかね。

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    print(datetime.now(JST)) #タイムゾーンを指定して現在時刻を取得

注意点

datetimeオブジェクトを使った引き算、足し算をしている場合は、タイムゾーンを揃えておかないとTypeErrorが発生します。

TypeError: can't subtract offset-naive and offset-aware datetimes

こんな感じにすればOK

    JST = timezone(timedelta(hours=+9)) #timezoneの生成
    datetime.datetime(2020, 1, 31, tzinfo=JST) - datetime.datetime.now(JST)
    #tzinfoにタイムゾーンを設定

もうひとつの解決策

ここまで調べた後で、もう一つの解決策があることを発見しました。
AWSのLambda関数の環境変数を変更する方法です。いろんなやり方があるのですね。

AWSのLambdaのタイムゾーンをUTCからJST(東京)に変更

なお、

Python3のdatetimeはタイムゾーンを指定するだけで高速になる

そうです。

「awareなdatetime」と「nativeなdatetime」

datetimeを調べる過程で、「awareなdatetime」や「nativeなdatetime」という言葉が出てきて「なんのこっちゃ」と戸惑いましたが、大まかには、

  • datetimeオブジェクトにタイムゾーンを指定する方法は、「awareなdatetime」
  • 実行環境(PC、AWSのLambda関数)のタイムゾーンを合わせる方法は、「nativeなdatetime」

ということみたいです。

言葉だけだと少々理解しにくいですが、実際にプログラムを動かしてみて結果の差異を見ることで実感できました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Cloud9でRails6+Webpacker実行時に発生するエラーの修正(VM4276:1 GET https://localhost:3035/sockjs-node/info?t=111111111111 net::ERR_CONNECTION_REFUSED)

環境

  • Rails6
  • AWS Cloud9
  • Docker

エラー発生箇所

localで開発したRails6プロジェクトを、Cloud9で動かそうとしたらブラウザのコンソールでいきなり発生した

エラー内容

VM4276:1 GET https://localhost:3035/sockjs-node/info?t=111111111111 net::ERR_CONNECTION_REFUSED

修正方法

config/webpacker.ymlを変更する

# config/webpacker.yml
development:
  <<: *default
  compile: true

  # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
  check_yarn_integrity: false

  # Reference: https://webpack.js.org/configuration/dev-server/
  dev_server:
    https: false
    host: localhost
    port: 3035

    # この箇所にCloud9のURLを貼る(#{}は適宜変更して下さい)
    public: "https://#{C9_PID}.vfs.cloud9.#{AWS_REGION}.amazonaws.com:3035"

参考リンク

https://github.com/webpack/webpack-dev-server/issues/230

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Cloud9でPackerを実行する

「Packer」とは、TerraformでおなじみのHashiCorp社が出しているマシンイメージの作成ツールで、AWS、Azure、GCPなどマルチクラウドに対応している点が売りです。
AWSですと最近「EC2 Image Builder」というサービスが出ましたが、これに近いでしょう。

今回、Cloud9でPackerをインストール&実行して、AMIを作成してみました。

手順

1. Homebrewをインストール

以下リンク先の手順で一撃です。
「Cloud9にHomebrewをインストールする手順」
https://qiita.com/nasuvitz/items/5eec6ab9444cff8e9467

2. Packerをインストール

一撃です。

$ brew install packer

3. Packerテンプレートを書く

Amazon AMI Builder」を見ながらテンプレートを作ります。
サンプルとして最新のAmazon Linux 2のAMIに、Apacheを追加したAMIを作成します。
AWS CLIでpackertestというプロファイルを作ってから、以下を作成します。

template.json
{
    "builders": [
        {
            "profile": "packertest",
            "type": "amazon-ebs",
            "region": "ap-northeast-1",
            "ami_name": "packer-test-amzn2",
            "source_ami_filter": {
                "filters": {
                    "name": "amzn2-ami-hvm-*-x86_64-gp2"
                },
                "owners": [
                    "137112412989"
                ],
                "most_recent": true
            },
            "instance_type": "t3.micro",
            "ssh_username": "ec2-user",
            "launch_block_device_mappings": [
                {
                    "delete_on_termination": true,
                    "device_name": "/dev/sda1",
                    "volume_size": 10,
                    "volume_type": "gp2"
                }
            ]
        }
    ],
    "provisioners": [
        {
            "type": "shell",
            "inline": [
                "sudo yum -y install httpd",
                "sudo systemctl start httpd && sudo systemctl enable httpd"
            ]
        }
    ]
}

4. Packerテンプレートを実行

まずは正しく書けているか構文チェックします。
以下のように出力されればOKです。

$ packer validate template.json 
Template validated successfully.

構文チェックが済んだら、AMIを作成します。

$ packer build template.json 

amazon-ebs: output will be in this color.

==> amazon-ebs: Prevalidating any provided VPC information
==> amazon-ebs: Prevalidating AMI Name: packer-test-amzn2
    amazon-ebs: Found Image ID: ami-011facbea5ec0363b
==> amazon-ebs: Creating temporary keypair: packer_5e21a1bb-ab35-2328-38ac-9a12a73d9285
==> amazon-ebs: Creating temporary security group for this instance: packer_5e21a1bc-3ac8-8db3-8477-db550e3c7338
==> amazon-ebs: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs: Launching a source AWS instance...
==> amazon-ebs: Adding tags to source instance
    amazon-ebs: Adding tag: "Name": "Packer Builder"
    amazon-ebs: Instance ID: i-01775277fbda2e451
==> amazon-ebs: Waiting for instance (i-01775277fbda2e451) to become ready...
==> amazon-ebs: Using ssh communicator to connect: 3.115.22.XXX
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Provisioning with shell script: /tmp/packer-shell846982988
    amazon-ebs: Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
==> amazon-ebs: Existing lock /var/run/yum.pid: another copy is running as pid 2609.
==> amazon-ebs: Another app is currently holding the yum lock; waiting for it to exit...
==> amazon-ebs:   The other application is: yum
==> amazon-ebs:     Memory : 109 M RSS (400 MB VSZ)
==> amazon-ebs:     Started: Fri Jan 17 12:00:21 2020 - 00:06 ago
==> amazon-ebs:     State  : Running, pid: 2609
==> amazon-ebs: Existing lock /var/run/yum.pid: another copy is running as pid 2613.
==> amazon-ebs: Another app is currently holding the yum lock; waiting for it to exit...
==> amazon-ebs:   The other application is: yum
==> amazon-ebs:     Memory :  34 M RSS (251 MB VSZ)
==> amazon-ebs:     Started: Fri Jan 17 12:00:21 2020 - 00:08 ago
==> amazon-ebs:     State  : Running, pid: 2613
    amazon-ebs: Resolving Dependencies
    amazon-ebs: --> Running transaction check
    amazon-ebs: ---> Package awscli.noarch 0:1.16.102-1.amzn2.0.1 will be updated
    amazon-ebs: ---> Package awscli.noarch 0:1.16.300-1.amzn2.0.1 will be an update
    amazon-ebs: ---> Package ca-certificates.noarch 0:2018.2.22-70.0.amzn2.0.1 will be updated
    amazon-ebs: ---> Package ca-certificates.noarch 0:2019.2.32-76.amzn2.0.1 will be an update
    amazon-ebs: ---> Package cloud-init.noarch 0:18.5-2.amzn2 will be updated
    amazon-ebs: ---> Package cloud-init.noarch 0:19.3-2.amzn2 will be an update
    amazon-ebs: ---> Package ec2-net-utils.noarch 0:1.1-1.1.amzn2 will be updated
    amazon-ebs: ---> Package ec2-net-utils.noarch 0:1.2-2.1.amzn2 will be an update
    amazon-ebs: ---> Package glibc.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package glibc.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package glibc-all-langpacks.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package glibc-all-langpacks.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package glibc-common.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package glibc-common.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package glibc-locale-source.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package glibc-locale-source.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package glibc-minimal-langpack.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package glibc-minimal-langpack.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package irqbalance.x86_64 2:1.5.0-2.amzn2.0.1 will be updated
    amazon-ebs: ---> Package irqbalance.x86_64 2:1.5.0-4.amzn2.0.1 will be an update
    amazon-ebs: ---> Package kernel.x86_64 0:4.14.158-129.185.amzn2 will be installed
    amazon-ebs: ---> Package kernel-tools.x86_64 0:4.14.154-128.181.amzn2 will be updated
    amazon-ebs: ---> Package kernel-tools.x86_64 0:4.14.158-129.185.amzn2 will be an update
    amazon-ebs: ---> Package libcrypt.x86_64 0:2.26-32.amzn2.0.2 will be updated
    amazon-ebs: ---> Package libcrypt.x86_64 0:2.26-33.amzn2 will be an update
    amazon-ebs: ---> Package microcode_ctl.x86_64 2:2.1-47.amzn2.0.4 will be updated
    amazon-ebs: ---> Package microcode_ctl.x86_64 2:2.1-47.amzn2.0.5 will be an update
    amazon-ebs: ---> Package nss-softokn.x86_64 0:3.44.0-5.amzn2.0.2 will be updated
    amazon-ebs: ---> Package nss-softokn.x86_64 0:3.44.0-8.amzn2 will be an update
    amazon-ebs: ---> Package nss-softokn-freebl.x86_64 0:3.44.0-5.amzn2.0.2 will be updated
    amazon-ebs: ---> Package nss-softokn-freebl.x86_64 0:3.44.0-8.amzn2 will be an update
    amazon-ebs: ---> Package nss-util.x86_64 0:3.44.0-3.amzn2.0.2 will be updated
    amazon-ebs: ---> Package nss-util.x86_64 0:3.44.0-4.amzn2 will be an update
    amazon-ebs: ---> Package python.x86_64 0:2.7.16-4.amzn2 will be updated
    amazon-ebs: ---> Package python.x86_64 0:2.7.16-5.amzn2 will be an update
    amazon-ebs: ---> Package python-devel.x86_64 0:2.7.16-4.amzn2 will be updated
    amazon-ebs: ---> Package python-devel.x86_64 0:2.7.16-5.amzn2 will be an update
    amazon-ebs: ---> Package python-libs.x86_64 0:2.7.16-4.amzn2 will be updated
    amazon-ebs: ---> Package python-libs.x86_64 0:2.7.16-5.amzn2 will be an update
    amazon-ebs: ---> Package python2-botocore.noarch 0:1.12.92-2.amzn2.0.1 will be updated
    amazon-ebs: ---> Package python2-botocore.noarch 0:1.13.36-2.amzn2.0.1 will be an update
    amazon-ebs: ---> Package sysstat.x86_64 0:10.1.5-13.amzn2 will be updated
    amazon-ebs: ---> Package sysstat.x86_64 0:10.1.5-18.amzn2.0.1 will be an update
    amazon-ebs: ---> Package systemtap-runtime.x86_64 0:4.1-0.20190208git4e76869512d2.amzn2.0.2 will be updated
    amazon-ebs: ---> Package systemtap-runtime.x86_64 0:4.2-1.amzn2.0.1 will be an update
    amazon-ebs: ---> Package tcpdump.x86_64 14:4.9.2-3.amzn2 will be updated
    amazon-ebs: ---> Package tcpdump.x86_64 14:4.9.2-4.amzn2.1 will be an update
    amazon-ebs: --> Finished Dependency Resolution
    amazon-ebs:
    amazon-ebs: Dependencies Resolved
    amazon-ebs:
    amazon-ebs: ================================================================================
    amazon-ebs:  Package                  Arch     Version                   Repository    Size
    amazon-ebs: ================================================================================
    amazon-ebs: Installing:
    amazon-ebs:  kernel                   x86_64   4.14.158-129.185.amzn2    amzn2-core    20 M
    amazon-ebs: Updating:
    amazon-ebs:  awscli                   noarch   1.16.300-1.amzn2.0.1      amzn2-core   1.6 M
    amazon-ebs:  ca-certificates          noarch   2019.2.32-76.amzn2.0.1    amzn2-core   399 k
    amazon-ebs:  cloud-init               noarch   19.3-2.amzn2              amzn2-core   923 k
    amazon-ebs:  ec2-net-utils            noarch   1.2-2.1.amzn2             amzn2-core    15 k
    amazon-ebs:  glibc                    x86_64   2.26-33.amzn2             amzn2-core   3.3 M
    amazon-ebs:  glibc-all-langpacks      x86_64   2.26-33.amzn2             amzn2-core   7.0 M
    amazon-ebs:  glibc-common             x86_64   2.26-33.amzn2             amzn2-core   768 k
    amazon-ebs:  glibc-locale-source      x86_64   2.26-33.amzn2             amzn2-core   3.2 M
    amazon-ebs:  glibc-minimal-langpack   x86_64   2.26-33.amzn2             amzn2-core    27 k
    amazon-ebs:  irqbalance               x86_64   2:1.5.0-4.amzn2.0.1       amzn2-core    50 k
    amazon-ebs:  kernel-tools             x86_64   4.14.158-129.185.amzn2    amzn2-core   122 k
    amazon-ebs:  libcrypt                 x86_64   2.26-33.amzn2             amzn2-core    47 k
    amazon-ebs:  microcode_ctl            x86_64   2:2.1-47.amzn2.0.5        amzn2-core   157 k
    amazon-ebs:  nss-softokn              x86_64   3.44.0-8.amzn2            amzn2-core   327 k
    amazon-ebs:  nss-softokn-freebl       x86_64   3.44.0-8.amzn2            amzn2-core   225 k
    amazon-ebs:  nss-util                 x86_64   3.44.0-4.amzn2            amzn2-core    78 k
    amazon-ebs:  python                   x86_64   2.7.16-5.amzn2            amzn2-core    92 k
    amazon-ebs:  python-devel             x86_64   2.7.16-5.amzn2            amzn2-core   403 k
    amazon-ebs:  python-libs              x86_64   2.7.16-5.amzn2            amzn2-core   7.4 M
    amazon-ebs:  python2-botocore         noarch   1.13.36-2.amzn2.0.1       amzn2-core   3.8 M
    amazon-ebs:  sysstat                  x86_64   10.1.5-18.amzn2.0.1       amzn2-core   317 k
    amazon-ebs:  systemtap-runtime        x86_64   4.2-1.amzn2.0.1           amzn2-core   472 k
    amazon-ebs:  tcpdump                  x86_64   14:4.9.2-4.amzn2.1        amzn2-core   424 k
    amazon-ebs:
    amazon-ebs: Transaction Summary
    amazon-ebs: ================================================================================
    amazon-ebs: Install   1 Package
    amazon-ebs: Upgrade  23 Packages
    amazon-ebs:
    amazon-ebs: Total download size: 52 M
    amazon-ebs: Downloading packages:
    amazon-ebs: Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
    amazon-ebs: --------------------------------------------------------------------------------
    amazon-ebs: Total                                               48 MB/s |  52 MB  00:01
    amazon-ebs: Running transaction check
    amazon-ebs: Running transaction test
    amazon-ebs: Transaction test succeeded
    amazon-ebs: Running transaction
    amazon-ebs:   Updating   : glibc-common-2.26-33.amzn2.x86_64                           1/47
    amazon-ebs:   Updating   : glibc-minimal-langpack-2.26-33.amzn2.x86_64                 2/47
    amazon-ebs:   Updating   : glibc-2.26-33.amzn2.x86_64                                  3/47
    amazon-ebs:   Updating   : nss-util-3.44.0-4.amzn2.x86_64                              4/47
    amazon-ebs:   Updating   : nss-softokn-freebl-3.44.0-8.amzn2.x86_64                    5/47
    amazon-ebs:   Updating   : 2:microcode_ctl-2.1-47.amzn2.0.5.x86_64                     6/47
    amazon-ebs:   Updating   : libcrypt-2.26-33.amzn2.x86_64                               7/47
    amazon-ebs:   Updating   : python-libs-2.7.16-5.amzn2.x86_64                           8/47
    amazon-ebs:   Updating   : python-2.7.16-5.amzn2.x86_64                                9/47
    amazon-ebs:   Updating   : python-devel-2.7.16-5.amzn2.x86_64                         10/47
    amazon-ebs:   Updating   : python2-botocore-1.13.36-2.amzn2.0.1.noarch                11/47
    amazon-ebs:   Updating   : awscli-1.16.300-1.amzn2.0.1.noarch                         12/47
    amazon-ebs:   Updating   : cloud-init-19.3-2.amzn2.noarch                             13/47
    amazon-ebs:   Installing : kernel-4.14.158-129.185.amzn2.x86_64                       14/47
    amazon-ebs:   Updating   : nss-softokn-3.44.0-8.amzn2.x86_64                          15/47
    amazon-ebs:   Updating   : systemtap-runtime-4.2-1.amzn2.0.1.x86_64                   16/47
    amazon-ebs:   Updating   : sysstat-10.1.5-18.amzn2.0.1.x86_64                         17/47
    amazon-ebs:   Updating   : 2:irqbalance-1.5.0-4.amzn2.0.1.x86_64                      18/47
    amazon-ebs:   Updating   : glibc-all-langpacks-2.26-33.amzn2.x86_64                   19/47
    amazon-ebs:   Updating   : kernel-tools-4.14.158-129.185.amzn2.x86_64                 20/47
    amazon-ebs:   Updating   : 14:tcpdump-4.9.2-4.amzn2.1.x86_64                          21/47
    amazon-ebs:   Updating   : glibc-locale-source-2.26-33.amzn2.x86_64                   22/47
    amazon-ebs:   Updating   : ec2-net-utils-1.2-2.1.amzn2.noarch                         23/47
    amazon-ebs:   Updating   : ca-certificates-2019.2.32-76.amzn2.0.1.noarch              24/47
    amazon-ebs:   Cleanup    : cloud-init-18.5-2.amzn2.noarch                             25/47
    amazon-ebs:   Cleanup    : python-devel-2.7.16-4.amzn2.x86_64                         26/47
    amazon-ebs:   Cleanup    : glibc-locale-source-2.26-32.amzn2.0.2.x86_64               27/47
    amazon-ebs:   Cleanup    : awscli-1.16.102-1.amzn2.0.1.noarch                         28/47
    amazon-ebs:   Cleanup    : glibc-all-langpacks-2.26-32.amzn2.0.2.x86_64               29/47
    amazon-ebs:   Cleanup    : nss-softokn-3.44.0-5.amzn2.0.2.x86_64                      30/47
    amazon-ebs:   Cleanup    : nss-softokn-freebl-3.44.0-5.amzn2.0.2.x86_64               31/47
    amazon-ebs:   Cleanup    : systemtap-runtime-4.1-0.20190208git4e76869512d2.amzn2.0.   32/47
    amazon-ebs:   Cleanup    : python2-botocore-1.12.92-2.amzn2.0.1.noarch                33/47
    amazon-ebs:   Cleanup    : python-2.7.16-4.amzn2.x86_64                               34/47
    amazon-ebs:   Cleanup    : python-libs-2.7.16-4.amzn2.x86_64                          35/47
    amazon-ebs:   Cleanup    : libcrypt-2.26-32.amzn2.0.2.x86_64                          36/47
    amazon-ebs:   Cleanup    : nss-util-3.44.0-3.amzn2.0.2.x86_64                         37/47
    amazon-ebs:   Cleanup    : 14:tcpdump-4.9.2-3.amzn2.x86_64                            38/47
    amazon-ebs:   Cleanup    : kernel-tools-4.14.154-128.181.amzn2.x86_64                 39/47
    amazon-ebs:   Cleanup    : 2:irqbalance-1.5.0-2.amzn2.0.1.x86_64                      40/47
    amazon-ebs:   Cleanup    : 2:microcode_ctl-2.1-47.amzn2.0.4.x86_64                    41/47
    amazon-ebs:   Cleanup    : sysstat-10.1.5-13.amzn2.x86_64                             42/47
    amazon-ebs:   Cleanup    : ec2-net-utils-1.1-1.1.amzn2.noarch                         43/47
    amazon-ebs:   Cleanup    : ca-certificates-2018.2.22-70.0.amzn2.0.1.noarch            44/47
    amazon-ebs:   Cleanup    : glibc-common-2.26-32.amzn2.0.2.x86_64                      45/47
    amazon-ebs:   Cleanup    : glibc-minimal-langpack-2.26-32.amzn2.0.2.x86_64            46/47
    amazon-ebs:   Cleanup    : glibc-2.26-32.amzn2.0.2.x86_64                             47/47
    amazon-ebs: /sbin/dracut: line 655: warning: setlocale: LC_MESSAGES: cannot change locale (en_US.UTF-8): No such file or directory
    amazon-ebs: /sbin/dracut: line 656: warning: setlocale: LC_CTYPE: cannot change locale (en_US.UTF-8): No such file or directory
    amazon-ebs: /sbin/dracut: line 655: warning: setlocale: LC_MESSAGES: cannot change locale (en_US.UTF-8): No such file or directory
    amazon-ebs: /sbin/dracut: line 656: warning: setlocale: LC_CTYPE: cannot change locale (en_US.UTF-8): No such file or directory
    amazon-ebs:   Verifying  : sysstat-10.1.5-18.amzn2.0.1.x86_64                          1/47
    amazon-ebs:   Verifying  : 2:microcode_ctl-2.1-47.amzn2.0.5.x86_64                     2/47
    amazon-ebs:   Verifying  : 2:irqbalance-1.5.0-4.amzn2.0.1.x86_64                       3/47
    amazon-ebs:   Verifying  : glibc-2.26-33.amzn2.x86_64                                  4/47
    amazon-ebs:   Verifying  : glibc-all-langpacks-2.26-33.amzn2.x86_64                    5/47
    amazon-ebs:   Verifying  : nss-util-3.44.0-4.amzn2.x86_64                              6/47
    amazon-ebs:   Verifying  : kernel-tools-4.14.158-129.185.amzn2.x86_64                  7/47
    amazon-ebs:   Verifying  : glibc-common-2.26-33.amzn2.x86_64                           8/47
    amazon-ebs:   Verifying  : awscli-1.16.300-1.amzn2.0.1.noarch                          9/47
    amazon-ebs:   Verifying  : glibc-minimal-langpack-2.26-33.amzn2.x86_64                10/47
    amazon-ebs:   Verifying  : python-devel-2.7.16-5.amzn2.x86_64                         11/47
    amazon-ebs:   Verifying  : ca-certificates-2019.2.32-76.amzn2.0.1.noarch              12/47
    amazon-ebs:   Verifying  : python-2.7.16-5.amzn2.x86_64                               13/47
    amazon-ebs:   Verifying  : 14:tcpdump-4.9.2-4.amzn2.1.x86_64                          14/47
    amazon-ebs:   Verifying  : ec2-net-utils-1.2-2.1.amzn2.noarch                         15/47
    amazon-ebs:   Verifying  : systemtap-runtime-4.2-1.amzn2.0.1.x86_64                   16/47
    amazon-ebs:   Verifying  : python-libs-2.7.16-5.amzn2.x86_64                          17/47
    amazon-ebs:   Verifying  : python2-botocore-1.13.36-2.amzn2.0.1.noarch                18/47
    amazon-ebs:   Verifying  : glibc-locale-source-2.26-33.amzn2.x86_64                   19/47
    amazon-ebs:   Verifying  : cloud-init-19.3-2.amzn2.noarch                             20/47
    amazon-ebs:   Verifying  : kernel-4.14.158-129.185.amzn2.x86_64                       21/47
    amazon-ebs:   Verifying  : libcrypt-2.26-33.amzn2.x86_64                              22/47
    amazon-ebs:   Verifying  : nss-softokn-freebl-3.44.0-8.amzn2.x86_64                   23/47
    amazon-ebs:   Verifying  : nss-softokn-3.44.0-8.amzn2.x86_64                          24/47
    amazon-ebs:   Verifying  : kernel-tools-4.14.154-128.181.amzn2.x86_64                 25/47
    amazon-ebs:   Verifying  : sysstat-10.1.5-13.amzn2.x86_64                             26/47
    amazon-ebs:   Verifying  : glibc-common-2.26-32.amzn2.0.2.x86_64                      27/47
    amazon-ebs:   Verifying  : python-libs-2.7.16-4.amzn2.x86_64                          28/47
    amazon-ebs:   Verifying  : python-2.7.16-4.amzn2.x86_64                               29/47
    amazon-ebs:   Verifying  : cloud-init-18.5-2.amzn2.noarch                             30/47
    amazon-ebs:   Verifying  : glibc-all-langpacks-2.26-32.amzn2.0.2.x86_64               31/47
    amazon-ebs:   Verifying  : libcrypt-2.26-32.amzn2.0.2.x86_64                          32/47
    amazon-ebs:   Verifying  : glibc-minimal-langpack-2.26-32.amzn2.0.2.x86_64            33/47
    amazon-ebs:   Verifying  : ca-certificates-2018.2.22-70.0.amzn2.0.1.noarch            34/47
    amazon-ebs:   Verifying  : 2:irqbalance-1.5.0-2.amzn2.0.1.x86_64                      35/47
    amazon-ebs:   Verifying  : 14:tcpdump-4.9.2-3.amzn2.x86_64                            36/47
    amazon-ebs:   Verifying  : python2-botocore-1.12.92-2.amzn2.0.1.noarch                37/47
    amazon-ebs:   Verifying  : nss-softokn-freebl-3.44.0-5.amzn2.0.2.x86_64               38/47
    amazon-ebs:   Verifying  : nss-util-3.44.0-3.amzn2.0.2.x86_64                         39/47
    amazon-ebs:   Verifying  : 2:microcode_ctl-2.1-47.amzn2.0.4.x86_64                    40/47
    amazon-ebs:   Verifying  : ec2-net-utils-1.1-1.1.amzn2.noarch                         41/47
    amazon-ebs:   Verifying  : systemtap-runtime-4.1-0.20190208git4e76869512d2.amzn2.0.   42/47
    amazon-ebs:   Verifying  : nss-softokn-3.44.0-5.amzn2.0.2.x86_64                      43/47
    amazon-ebs:   Verifying  : glibc-2.26-32.amzn2.0.2.x86_64                             44/47
    amazon-ebs:   Verifying  : python-devel-2.7.16-4.amzn2.x86_64                         45/47
    amazon-ebs:   Verifying  : awscli-1.16.102-1.amzn2.0.1.noarch                         46/47
    amazon-ebs:   Verifying  : glibc-locale-source-2.26-32.amzn2.0.2.x86_64               47/47
    amazon-ebs:
    amazon-ebs: Installed:
    amazon-ebs:   kernel.x86_64 0:4.14.158-129.185.amzn2
    amazon-ebs:
    amazon-ebs: Updated:
    amazon-ebs:   awscli.noarch 0:1.16.300-1.amzn2.0.1
    amazon-ebs:   ca-certificates.noarch 0:2019.2.32-76.amzn2.0.1
    amazon-ebs:   cloud-init.noarch 0:19.3-2.amzn2
    amazon-ebs:   ec2-net-utils.noarch 0:1.2-2.1.amzn2
    amazon-ebs:   glibc.x86_64 0:2.26-33.amzn2
    amazon-ebs:   glibc-all-langpacks.x86_64 0:2.26-33.amzn2
    amazon-ebs:   glibc-common.x86_64 0:2.26-33.amzn2
    amazon-ebs:   glibc-locale-source.x86_64 0:2.26-33.amzn2
    amazon-ebs:   glibc-minimal-langpack.x86_64 0:2.26-33.amzn2
    amazon-ebs:   irqbalance.x86_64 2:1.5.0-4.amzn2.0.1
    amazon-ebs:   kernel-tools.x86_64 0:4.14.158-129.185.amzn2
    amazon-ebs:   libcrypt.x86_64 0:2.26-33.amzn2
    amazon-ebs:   microcode_ctl.x86_64 2:2.1-47.amzn2.0.5
    amazon-ebs:   nss-softokn.x86_64 0:3.44.0-8.amzn2
    amazon-ebs:   nss-softokn-freebl.x86_64 0:3.44.0-8.amzn2
    amazon-ebs:   nss-util.x86_64 0:3.44.0-4.amzn2
    amazon-ebs:   python.x86_64 0:2.7.16-5.amzn2
    amazon-ebs:   python-devel.x86_64 0:2.7.16-5.amzn2
    amazon-ebs:   python-libs.x86_64 0:2.7.16-5.amzn2
    amazon-ebs:   python2-botocore.noarch 0:1.13.36-2.amzn2.0.1
    amazon-ebs:   sysstat.x86_64 0:10.1.5-18.amzn2.0.1
    amazon-ebs:   systemtap-runtime.x86_64 0:4.2-1.amzn2.0.1
    amazon-ebs:   tcpdump.x86_64 14:4.9.2-4.amzn2.1
    amazon-ebs:
    amazon-ebs: Complete!
    amazon-ebs: Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
    amazon-ebs: Resolving Dependencies
    amazon-ebs: --> Running transaction check
    amazon-ebs: ---> Package httpd.x86_64 0:2.4.41-1.amzn2.0.1 will be installed
    amazon-ebs: --> Processing Dependency: httpd-tools = 2.4.41-1.amzn2.0.1 for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: httpd-filesystem = 2.4.41-1.amzn2.0.1 for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: system-logos-httpd for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: mod_http2 for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: httpd-filesystem for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: /etc/mime.types for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.41-1.amzn2.0.1.x86_64
    amazon-ebs: --> Running transaction check
    amazon-ebs: ---> Package apr.x86_64 0:1.6.3-5.amzn2.0.2 will be installed
    amazon-ebs: ---> Package apr-util.x86_64 0:1.6.1-5.amzn2.0.2 will be installed
    amazon-ebs: --> Processing Dependency: apr-util-bdb(x86-64) = 1.6.1-5.amzn2.0.2 for package: apr-util-1.6.1-5.amzn2.0.2.x86_64
    amazon-ebs: ---> Package generic-logos-httpd.noarch 0:18.0.0-4.amzn2 will be installed
    amazon-ebs: ---> Package httpd-filesystem.noarch 0:2.4.41-1.amzn2.0.1 will be installed
    amazon-ebs: ---> Package httpd-tools.x86_64 0:2.4.41-1.amzn2.0.1 will be installed
    amazon-ebs: ---> Package mailcap.noarch 0:2.1.41-2.amzn2 will be installed
    amazon-ebs: ---> Package mod_http2.x86_64 0:1.15.3-2.amzn2 will be installed
    amazon-ebs: --> Running transaction check
    amazon-ebs: ---> Package apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2 will be installed
    amazon-ebs: --> Finished Dependency Resolution
    amazon-ebs:
    amazon-ebs: Dependencies Resolved
    amazon-ebs:
    amazon-ebs: ================================================================================
    amazon-ebs:  Package                 Arch       Version                Repository      Size
    amazon-ebs: ================================================================================
    amazon-ebs: Installing:
    amazon-ebs:  httpd                   x86_64     2.4.41-1.amzn2.0.1     amzn2-core     1.3 M
    amazon-ebs: Installing for dependencies:
    amazon-ebs:  apr                     x86_64     1.6.3-5.amzn2.0.2      amzn2-core     118 k
    amazon-ebs:  apr-util                x86_64     1.6.1-5.amzn2.0.2      amzn2-core      99 k
    amazon-ebs:  apr-util-bdb            x86_64     1.6.1-5.amzn2.0.2      amzn2-core      19 k
    amazon-ebs:  generic-logos-httpd     noarch     18.0.0-4.amzn2         amzn2-core      19 k
    amazon-ebs:  httpd-filesystem        noarch     2.4.41-1.amzn2.0.1     amzn2-core      23 k
    amazon-ebs:  httpd-tools             x86_64     2.4.41-1.amzn2.0.1     amzn2-core      87 k
    amazon-ebs:  mailcap                 noarch     2.1.41-2.amzn2         amzn2-core      31 k
    amazon-ebs:  mod_http2               x86_64     1.15.3-2.amzn2         amzn2-core     146 k
    amazon-ebs:
    amazon-ebs: Transaction Summary
    amazon-ebs: ================================================================================
    amazon-ebs: Install  1 Package (+8 Dependent packages)
    amazon-ebs:
    amazon-ebs: Total download size: 1.8 M
    amazon-ebs: Installed size: 5.1 M
    amazon-ebs: Downloading packages:
    amazon-ebs: --------------------------------------------------------------------------------
    amazon-ebs: Total                                               11 MB/s | 1.8 MB  00:00
    amazon-ebs: Running transaction check
    amazon-ebs: Running transaction test
    amazon-ebs: Transaction test succeeded
    amazon-ebs: Running transaction
    amazon-ebs:   Installing : apr-1.6.3-5.amzn2.0.2.x86_64                                 1/9
    amazon-ebs:   Installing : apr-util-bdb-1.6.1-5.amzn2.0.2.x86_64                        2/9
    amazon-ebs:   Installing : apr-util-1.6.1-5.amzn2.0.2.x86_64                            3/9
    amazon-ebs:   Installing : httpd-tools-2.4.41-1.amzn2.0.1.x86_64                        4/9
    amazon-ebs:   Installing : generic-logos-httpd-18.0.0-4.amzn2.noarch                    5/9
    amazon-ebs:   Installing : mailcap-2.1.41-2.amzn2.noarch                                6/9
    amazon-ebs:   Installing : httpd-filesystem-2.4.41-1.amzn2.0.1.noarch                   7/9
    amazon-ebs:   Installing : mod_http2-1.15.3-2.amzn2.x86_64                              8/9
    amazon-ebs:   Installing : httpd-2.4.41-1.amzn2.0.1.x86_64                              9/9
    amazon-ebs:   Verifying  : apr-util-1.6.1-5.amzn2.0.2.x86_64                            1/9
    amazon-ebs:   Verifying  : apr-util-bdb-1.6.1-5.amzn2.0.2.x86_64                        2/9
    amazon-ebs:   Verifying  : httpd-2.4.41-1.amzn2.0.1.x86_64                              3/9
    amazon-ebs:   Verifying  : httpd-filesystem-2.4.41-1.amzn2.0.1.noarch                   4/9
    amazon-ebs:   Verifying  : mod_http2-1.15.3-2.amzn2.x86_64                              5/9
    amazon-ebs:   Verifying  : apr-1.6.3-5.amzn2.0.2.x86_64                                 6/9
    amazon-ebs:   Verifying  : mailcap-2.1.41-2.amzn2.noarch                                7/9
    amazon-ebs:   Verifying  : generic-logos-httpd-18.0.0-4.amzn2.noarch                    8/9
    amazon-ebs:   Verifying  : httpd-tools-2.4.41-1.amzn2.0.1.x86_64                        9/9
    amazon-ebs:
    amazon-ebs: Installed:
    amazon-ebs:   httpd.x86_64 0:2.4.41-1.amzn2.0.1
    amazon-ebs:
    amazon-ebs: Dependency Installed:
    amazon-ebs:   apr.x86_64 0:1.6.3-5.amzn2.0.2
    amazon-ebs:   apr-util.x86_64 0:1.6.1-5.amzn2.0.2
    amazon-ebs:   apr-util-bdb.x86_64 0:1.6.1-5.amzn2.0.2
    amazon-ebs:   generic-logos-httpd.noarch 0:18.0.0-4.amzn2
    amazon-ebs:   httpd-filesystem.noarch 0:2.4.41-1.amzn2.0.1
    amazon-ebs:   httpd-tools.x86_64 0:2.4.41-1.amzn2.0.1
    amazon-ebs:   mailcap.noarch 0:2.1.41-2.amzn2
    amazon-ebs:   mod_http2.x86_64 0:1.15.3-2.amzn2
    amazon-ebs:
    amazon-ebs: Complete!
==> amazon-ebs: Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
==> amazon-ebs: Stopping the source instance...
    amazon-ebs: Stopping instance
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating AMI packer-test-amzn2 from instance i-01775277fbda2e451
    amazon-ebs: AMI: ami-0c4844c78732a5179
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished.

==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-0c4844c78732a5179

実行中、Packer BuliderというEC2が起動し、このEC2のAMIが取られることで、新たなAMIが出来上がります。
image.png

出来上がったAMIを確認してみます。

image.png

Packerを使って、いとも簡単に、カスタムAMIを作成することができました。

サンプル実行時に気になるところ

  • 一瞬、SSHが全開放になっている
    • 「Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups」 という実行ログがあります。
    • Packerのssh communicatorが、Packer BuliderのEC2に接続するようです。
  • 一瞬、yumが競合している
    • 「Another app is currently holding the yum lock; waiting for it to exit...」という実行ログがあります。
    • Amazon Linux 2をAMIから初回起動するとき、最新セキュリティパッチが必ず当たるようになっていますので、その処理と競合したと思われます。
    • OSの初回起動時のセキュリティパッチ適用処理の方が先に実行され、その後、Packerで定義したprovisionersの処理が実行されるようです。

まとめ

Terraformと同じく、AWS、Azure、GCPなどマルチクラウドに対応する際に、非常に有効なツールです。
AWSだけならEC2 Image Builderの選択肢もありますが、Packerは操作が簡単であり、AWS専用でも選択肢に入ります。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スナップショットからRDSインスタンスを作成する方法

はじめに

"出来合いのDB"のスナップショットからクローンとなるRDSインスタンスを作る機会があったので、その手順をまとめてみました。

スナップショットの選択

  • AWSマネジメントコンソールのトップ画面から、[サービス]>[RDS]と進みます。
  • RDSの画面の左側のパネルで、[スナップショット]を選択します。

rds_01.png

  • スナップショット画面が開いたら、所望のスナップショットにチェックを入れます。
  • その後、スナップショット画面上部の[スナップショットのアクション]のリストをクリックして、[スナップショットの復元]を選択します。

rds_02.png

スナップショットの復元

DBインスタンスの復元画面で、以下の事項を設定します。
設定が完了したら、画面最下部の[DBインスタンスの作成]ボタンをクリックして、スナップショットからRDSインスタンスを作成します。

rds_03.png

インスタンスの仕様

  • DBエンジン
  • ライセンスモデル
    • ライセンス込み(ライセンス料はRDSの利用料に含まれている)
    • BYOL(自分のライセンス使用)
  • DBインスタンスのクラス
    • db.t3.micro~db.t3.2xlargeなど、20種類程度の中から選びます。
  • マルチAZ配置
  • ストレージタイプ
    • 汎用SSD/プロビジョンドIOPS/マグネティックの3種類から選びます。

設定

  • DBインスタンス識別子
    • RDSの画面では"DB インスタンス ID"の欄に表示されます。

ネットワーク&セキュリティ

  • VPC
  • サブネット
  • パブリックアクセシビリティ
  • アベイラビリティ―ゾーン
  • VPCセキュリティグループ
    • デフォルトは[新規のVPCセキュリティグループを作成]となっているので、このRDSインスタンス用に新しいセキュリティグループが作られます。
    • [既存のVPCセキュリティグループの選択]を選択すると、既存のセキュリティグループを選ぶことも可能です。

データベースの設定

  • データベースの名前
    • RDSの画面では"DB 名"の欄に表示されます。
  • データベースのポート
    • DBエンジンがOracleの場合、デフォルト値は1521となっています。
  • DBパラメータグループ
  • オプショングループ

バックアップ

  • タグをスナップショットへコピー

暗号化

ログのエクスポート

  • アラートログ/監査ログ/リスナーログ/トレースログの中から、CloudWatch Logsに発行するログを選択します。
    • 上記の中から複数個選択可能です。

メンテナンス

  • マイナーバージョン自動アップグレード
    • リリースと同時にDBエンジンのバージョンアップを自動的に行う場合は「はい」に設定します。

まとめ

  • スナップショットからの復元には数分~の時間を要するようです。
    • 当たり前の話ですが、復元が完了するまではRDSインスタンスの設定を変更できません。
  • DBを外部に公開する場合は、パブリックアクセシビリティを有効化するだけでなく、セキュリティグループにも気を付ける必要があります。
    • セキュリティグループで、インバウンドの欄に接続元となる信頼できるIPが設定されていることを必ず確認すること。
    • スナップショットからの復元時に新規のVPCセキュリティグループを作成 が選択されている場合、余計なセキュリティグループが出来てしまって、それを削除する手間がかかるかもしれません。
  • スナップショットからの復元は、新しいRDSインスタンスを作ることに等しいです。
    • こちらの記事にも書かれているように、「スナップショットを使って、ある時点まで既存のDBをロールバックする」のではなく、「スナップショットを使って、ある時点のDBインスタンスを新たに作る」ということになります。

参考URL

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS の NAT インスタンスを CloudFormation で作る

See: https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_NAT_Instance.html

NAT ゲートウェイだと楽なんだけど、あまり性能いらないのに高かったので NAT インスタンスを作成した。

NAT インスタンスでは "送信元/送信先チェック" を無効にしなきゃいけないんだけど、instance attribute の変更は CloudFormation でできないようなので、UserData で初回起動時にコマンド実行するようにした。

下記は Availability Zone ap-northeast-1a に作成する例。

# セキュリティグループ
SecurityGroupNat:
  Type: AWS::EC2::SecurityGroup
  Properties:
    SecurityGroupIngress:
      - CidrIp: (サブネットのアドレス範囲)
        Description: HTTP
        FromPort: 80
        IpProtocol: tcp
        ToPort: 80
      - CidrIp: (サブネットのアドレス範囲)
        Description: HTTPS
        FromPort: 443
        IpProtocol: tcp
        ToPort: 443
    SecurityGroupEgress:
      - CidrIp: 0.0.0.0/0
        Description: HTTP
        FromPort: 80
        IpProtocol: tcp
        ToPort: 80
      - CidrIp: 0.0.0.0/0
        Description: HTTPS
        FromPort: 443
        IpProtocol: tcp
        ToPort: 443
    VpcId: (VPC の ID)

# "送信元/送信先チェック" を無効にするコマンドを実行するための IAM プロファイル/ロール
NatInstanceProfile:
  DependsOn:
    - NatInstanceRole
  Type: AWS::IAM::InstanceProfile
  Properties:
    Roles:
      - !Ref NatInstanceRole

NatInstanceRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
    Policies:
      -
        PolicyDocument:
          {
            "Version": "2012-10-17",
            "Statement": [
              {
                "Sid": "VisualEditor0",
                "Effect": "Allow",
                "Action": "ec2:ModifyInstanceAttribute",
                "Resource": "*" # ModifyInstanceAttribute はリソースの制限はできないみたい...
              }
            ]
          }
        PolicyName: allow-modify-instance-attribute

# NAT インスタンス
NatInstance:
  Type: AWS::EC2::Instance
  Properties:
    AvailabilityZone: ap-northeast-1a
    IamInstanceProfile: !Ref NatInstanceProfile
    ImageId: ami-00d29e4cb217ae06b # マーケットプレイスで amzn-ami-vpc-nat で検索して選ぶ
    InstanceType: t3.nano
    NetworkInterfaces:
      - AssociatePublicIpAddress: "true"
        DeviceIndex: "0"
        GroupSet:
          - !Ref SecurityGroupNat
        SubnetId: (サブネットの ID)
    # "送信元/送信先チェック" を無効にするコマンドを初回起動時に実行
    UserData:
      'Fn::Base64': |
        #!/bin/bash
        INSTANCEID=$(curl -s -m 60 http://169.254.169.254/latest/meta-data/instance-id)
        aws --region ap-northeast-1 ec2 modify-instance-attribute --instance-id $INSTANCEID --source-dest-check "{\"Value\": false}"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ECSでdocker volumeマウントのownerを指定する

ECSでdocker volumeをマウントするとownerはrootになります。
指定したい場合は、タスク定義のボリューム定義で、dockerVolumeConfiguration.driverOpts を指定しましょう。
例えば、tmpfsとしてボリュームを作成してownerをuid=1000, gid=1000にしたいときは、

  "volumes": [
    {
      "name": "sharedtmp",
      "dockerVolumeConfiguration": {
        "autoprovision": true,
        "scope": "shared",
        "driverOpts": {
          "type": "tmpfs",
          "device": "tmpfs",
          "o": "uid=1000,gid=1000"
        }
      }
    }
  ]

こうすることで ボリューム作成の際に以下のようにオプションをつけて作成してくれます。

$ docker volume create --opt type=tmpfs --opt device=tmpfs --opt o=uid=1000,gid=1000 sharedtmp

ElasticBeanstalkからECSを使う場合も、Dockerrun.aws.jsonに同じように書くだけです。
以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Developer Associate サンプル問題の日本語訳

はじめに

本記事は、AWS Developer Associate(DVA)のサンプル問題の日本語訳(ほぼGoogle翻訳 + 一部意訳)です。
現在(2020/1/17時点)サンプル問題の日本語訳が公式HPから公開されていないので、自分用のメモとして記載します。翻訳や記載の誤りなどあれば、コメント/修正リクエストをいただけると幸いです。
また原文にはない個人的感想は区切って追記しています。

翻訳元は以下です。分からない問題がある場合は、原文のリンクを見てください。
AWS 認定開発者 – アソシエイト
(上記サイト内右の「サンプル問題をダウンロード」のリンク先)

1問目

企業がレガシーアプリケーションをAmazon EC2に移行しています。アプリケーションは、ソースコードに保存されているユーザー名とパスワードを使用して、MySQLデータベースに接続します。 データベースは、Amazon RDS for MySQL DBインスタンスに移行されます。 移行の一環として、会社はデータベース資格情報を保存して自動的にローテーションする安全な方法を実装したいと考えています。

A)データベース資格情報をAmazon Machine Image(AMI)の環境変数に保存します。 AMIを交換して資格情報をローテーションします。

B)データベース認証情報をAWS Systems Manager Parameter Storeに保存します。 資格情報を自動的にローテーションするようにパラメーターストアを構成します。

C)EC2インスタンスの環境変数にデータベース認証情報を保存します。 EC2インスタンスを再起動して資格情報をローテーションします。

D)データベース認証情報をAWS Secrets Managerに保存します。 資格情報を自動的にローテーションするようにSecrets Managerを構成する




正解:D

解説
AWS Secrets Managerは、データベース、アプリケーション、サービス、およびその他のITリソースへのアクセスに必要な認証情報の保護に役立ちます。 このサービスにより、ユーザーはライフサイクル全体でデータベースの資格情報、APIキー、およびその他の機密情報を簡単にローテーション、管理、および取得できます。
ユーザーとアプリケーションは、Secrets Manager APIを呼び出してシークレットを取得するため、機密情報をプレーンテキストでハードコーディングする必要がなくなります。 Secrets Managerは、Amazon RDS、Amazon Redshift、およびAmazon DocumentDBへ機密情報のローテーションを提供します。


全部の選択肢を一応できなくはないが最適な方法を選択させる問題。A、Cは少しEC2を触っていれば問題外だとわかりますが、BはParameter Storeが単体だと自動更新できないことを知らないと外せない。
参考
AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較


2問目

開発者は、ユーザーがコメントを投稿し、ほぼリアルタイムのフィードバックを受け取ることができるWebアプリケーションを設計しています。
これらの要件を満たすアーキテクチャはどれですか? (2つ選択してください)

A)AWS AppSyncスキーマと対応するAPIを作成します。 Amazon DynamoDBをデータストアとして使用します。

B)Amazon API GatewayでWebSocket APIを作成します。 AWS Lambda関数をバックエンドとして使用し、Amazon DynamoDBをデータストアとして使用します。

C)Amazon RDSを利用したAWS Elastic Beanstalkアプリケーションを作成します。 存続期間の長いTCP / IPソケットを許可するようにアプリケーションを構成します。

D)Amazon API GatewayでGraphQLエンドポイントを作成します。 Amazon DynamoDBをデータストアとして使用します。

E)Amazon CloudFrontでWebSocketを有効にします。 オリジンとしてAWS Lambda関数を使用し、データストアとしてAmazon Aurora DBクラスターを使用します。




正解:A、B

解説
AWS AppSyncは、ユーザーが1つ以上のデータソースのデータに安全にアクセス、操作、および結合するための柔軟なAPIを作成できるようにすることで、アプリケーション開発を簡素化します。 AWS AppSyncは、GraphQLを使用して、アプリケーションが必要な正確なデータを簡単に取得できるようにするマネージドサービスです。 AWS AppSyncを使用すると、ユーザーは、Amazon DynamoDBを含むさまざまなデータソース上で、リアルタイム更新が必要なアプリケーションを含むスケーラブルなアプリケーションを構築できます。 Amazon API Gatewayでは、ユーザーは、AWSサービス(AWS LambdaやDynamoDBなど)またはHTTPエンドポイントのステートフルフロントエンドとしてWebSocket APIを作成できます。 WebSocket APIは、クライアントアプリケーションから受信したメッセージのコンテンツに基づいてバックエンドを呼び出します。 要求を受信して応答するREST APIとは異なり、WebSocket APIはクライアントアプリケーションとバックエンド間の双方向通信をサポートします。

3問目

開発者がアプリケーションにサインアップおよびサインイン機能を追加しています。 アプリケーションは、ユーザーのサインインイベントを記録するために、カスタム分析ソリューションへのAPI呼び出しを行う必要があります。
これらの要件を満たすために、開発者はどのアクションの組み合わせを使用する必要がありますか? (2つ選択してください)

A)Amazon Cognitoを使用して、サインアップおよびサインイン機能を提供します。

B)AWS IAMを使用して、サインアップおよびサインイン機能を提供します。

C)AWS Configルールを設定して、認証後イベントによってトリガーされるAPI呼び出しを行います。

D)Amazon API Gatewayメソッドを呼び出して、認証後イベントによってトリガーされるAPI呼び出しを行います。

E)AWS Lambda関数を実行して、認証後イベントによってトリガーされるAPI呼び出しを行います。




正解:A、E

解説
Amazon Cognitoは、ユーザーのサインアップ、サインイン、およびアクセス制御をWebおよびモバイルアプリケーションにすばやく簡単に追加します。 ユーザーは、AWS Lambda関数を作成して、カスタム分析ソリューションへのAPI呼び出しを行うこともできます
次に、Amazon Cognitoの認証後トリガーでその機能をトリガーします。


Amazon Cognitoと認証後に任意の処理をLambdaで行えることを知っていれば解ける。


4問目

企業がAWSアカウントのREST APIにAmazon API Gatewayを使用しています。セキュリティチームは、別のAWSアカウントのIAMユーザーのみがAPIにアクセスできるようにしたいと考えています。
これらの要件を満たすために、セキュリティチームはどのアクションを組み合わせて実行する必要がありますか? (2つ選択してください)

A)IAMアクセス許可ポリシーを作成し、各IAMユーザーにアタッチします。 APIメソッド認証タイプをAWS_IAMに設定します。署名バージョン4を使用して、API要求に署名します。

B)Amazon Cognitoユーザープールを作成し、各IAMユーザーをプールに追加します。 APIのメソッド認証タイプをCOGNITO_USER_POOLSに設定します。 Amazon CognitoのIAM認証情報を使用して認証し、IDトークンをリクエストヘッダーに追加します。

C)Amazon Cognito IDプールを作成し、各IAMユーザーをプールに追加します。 APIのメソッド認証タイプをCOGNITO_USER_POOLSに設定します。 Amazon CognitoのIAM認証情報を使用して認証し、アクセストークンをリクエストヘッダーに追加します。

D)各IAMユーザーのみにアクセスを許可するAPIのリソースポリシーを作成します。

E)各IAMユーザーのみにアクセスを許可するAPIのAmazon Cognitoオーソライザーを作成します。 APIのメソッド認証タイプをCOGNITO_USER_POOLSに設定します。




正解:A、D

解説
リソースポリシーを使用して、署名バージョン4(SigV4)プロトコルを使用して、別のAWSアカウントのユーザーに1つのAWSアカウントへのAPIアクセスを許可できます。


Amazon CognitoがIAMユーザでなくアプリなどAWSアカウント以外のユーザ認証を行い、IAM Roleで認可を行う性質を理解していればB、C、Eは選択肢から外せる。
参考
Amazon CognitoとUser PoolsとIAMの位置付けと混乱


5問目

開発者は、テキストファイルを.pdfファイルに変換するアプリケーションを構築しています。 テキストファイルは、別のアプリケーションによってAmazon S3バケットに書き込まれます。 開発者は、Amazon S3に到着したファイルを読み取り、AWS Lambdaを使用して.pdfファイルに変換したいと考えています。開発者は、Amazon S3およびAmazon CloudWatch Logsへのアクセスを許可するIAMポリシーを作成しました。
Lambda関数に正しいアクセス許可があることを確認するために、開発者はどのアクションを実行する必要がありますか?

A)AWS IAMを使用してLambda実行ロールを作成します。 IAMポリシーをロールにアタッチします。 Lambda関数にLambda実行ロールを割り当てます。

B)AWS IAMを使用してLambda実行ユーザーを作成します。 IAMポリシーをユーザーにアタッチします。 Lambda実行ユーザーをLambda関数に割り当てます。

C)AWS IAMを使用してLambda実行ロールを作成します。 IAMポリシーをロールにアタッチします。 IAMロールをLambda関数の環境変数として保存します。

D)AWS IAMを使用してLambda実行ユーザーを作成します。 IAMポリシーをユーザーにアタッチします。 IAMユーザー認証情報をLambda関数の環境変数として保存します。




正解:A、D

解説
AWS Lambda関数の実行ロールは、AWSサービスとリソースにアクセスする許可を付与します。ユーザーは、関数が作成されるときにこのロールを提供し、Lambdaは関数が呼び出されるときにロールを引き受けます。


Lambdaとロールの関係を理解していればAだとわかる。消去法でいくとBとDはLambda実行ユーザをLambdaに割り当てるというよくわからない記述があるので×。CはIAMロールは環境変数に割り当てるという誤った記述があるので×。したがってAが残る。


6問目

会社には、地理的に複数の場所にAWSワークロードがあります。 開発者がus-west-1リージョンにAmazon Auroraデータベースを作成しました。 データベースは、お客様が管理するAWS KMSキーを使用して暗号化されます。 ここで、開発者はus-east-1リージョンに同じ暗号化データベースを作成したいと考えています。
開発者はこのタスクを達成するためにどのアプローチを取るべきですか。

A)us-west-1リージョンにデータベースのスナップショットを作成します。 スナップショットをus-east-1リージョンにコピーし、us-east-1リージョンでKMSキーを指定します。 コピーしたスナップショットからデータベースを復元します。

B)us-west-1リージョンにデータベースの暗号化されていないスナップショットを作成します。 スナップショットをuseast-1リージョンにコピーします。 コピーしたスナップショットからデータベースを復元し、us-east-1リージョンのKMSキーを使用して暗号化を有効にします。

C)データベースの暗号化を無効にします。 us-west-1リージョンにデータベースのスナップショットを作成します。 スナップショットをus-east-1リージョンにコピーします。 コピーしたスナップショットからデータベースを復元します。

D)us-east-1リージョンで、us-west1リージョンからデータベースの最新の自動バックアップを復元することを選択します。 us-east-1リージョンでKMSキーを使用して暗号化を有効にします。




正解:A

解説
ユーザーが暗号化されたスナップショットをコピーする場合、スナップショットのコピーも暗号化する必要があります。 ユーザーがリージョン間で暗号化されたスナップショットをコピーする場合、KMSキーはリージョン固有であるため、ユーザーはソーススナップショットに使用されるのと同じAWS KMS暗号化キーをコピーに使用できません。 代わりに、ユーザーは宛先リージョンで有効なKMSキーを指定する必要があります。

7問目

開発者は、Memcached用Amazon ElastiCacheを企業の既存のレコードストレージアプリケーションに追加して、データベースの負荷を軽減し、パフォーマンスを向上させています。
開発者は、一般的なレコード処理パターンの分析に基づいて、遅延読み込みを使用することにしました。
どの擬似コードの例が遅延読み込みを正しく実装していますか?

A)

record_value = db.query("UPDATE Records SET Details = {1} WHERE ID == {0}", record_key,
record_value)
cache.set (record_key, record_value)

B)

record_value = cache.get(record_key)
if (record_value == NULL)
 record_value = db.query("SELECT Details FROM Records WHERE ID == {0}", record_key)
 cache.set (record_key, record_value)

C)

record_value = cache.get (record_key)
db.query("UPDATE Records SET Details = {1} WHERE ID == {0}", record_key, record_value)

D)

record_value = db.query("SELECT Details FROM Records WHERE ID == {0}", record_key)
if (record_value != NULL)
 cache.set (record_key, record_value)




正解:B

解説
遅延読み込みは、レコードの読み込みが必要になるまで遅延されるという概念です。遅延読み込みは最初にキャッシュをチェックします。 レコードが存在しない場合、遅延読み込みはデータベースからレコードを取得し、キャッシュに保存します。


この問題に答えるだけならElasticCacheの仕様を把握してなくても消去法で解答できる。AとCはUPDATEなのでそもそも読み込みではないので×。Dはキャッシュアクセスでなく先にQuery実行をしているので×。したがって残ったBが正解。Bは最初にキャッシュへアクセスしている。


8問目

開発者は、一連のAmazon EC2インスタンスで実行されるアプリケーションのパフォーマンスを追跡したいと考えています。 開発者は、平均および最大リクエスト遅延など、フリート全体の統計を表示および追跡したいと考えています。 開発者は、平均応答時間がしきい値を超えた場合にすぐに通知されることを望んでいます。 これらの要件を満たすソリューションはどれですか?

A)各インスタンスでcronジョブを設定して、応答時間を測定し、Amazon S3バケットに保存されているログファイルを毎分更新します。 Amazon S3イベント通知を使用して、ログファイルを読み取り、新しいエントリーをAmazon Elasticsearch Service(Amazon ES)クラスターに書き込むAWS Lambda関数をトリガーします。 Kibanaダッシュボードで結果を視覚化します。応答時間がしきい値を超えたときにAmazon SNSトピックにアラートを送信するようにAmazon ESを構成します。

B)応答時間をシステムログに書き込むようにアプリケーションを構成します。ログを継続的に読み取り、応答時間をAmazon EventBridgeに送信するようにAmazon Inspectorエージェントをインストールして構成します。 EventBridgeコンソールでメトリックグラフを表示します。応答時間メトリックの平均がしきい値を超えたときにAmazon SNS通知を送信するように、EventBridgeカスタムルールを構成します。

C)応答時間をログファイルに書き込むようにアプリケーションを構成します。インスタンスにAmazon CloudWatchエージェントをインストールして設定し、アプリケーションログをCloudWatch Logsにストリーミングします。ログから応答時間のメトリックフィルターを作成します。 CloudWatchコンソールでメトリックスグラフを表示します。応答時間メトリクスの平均がしきい値を超えたときにAmazon SNS通知を送信するには、CloudWatchアラームを作成します。

D)インスタンスにAWS Systems Managerエージェントをインストールおよび設定して、応答時間を監視し、カスタムメトリックスとしてAmazon CloudWatchに送信します。 Amazon QuickSightでメトリックスグラフを表示します。応答時間メトリクスの平均がしきい値を超えたときにAmazon SNS通知を送信するには、CloudWatchアラームを作成します。




正解:C

解説
Amazon CloudWatch Agentは、ログとメトリックスをCloudWatchにストリーミングするように設定できます。 メトリックスフィルターは、CloudWatch Logsに保存されたログから作成できます。

9問目

開発者はアプリケーションをローカルでテストしており、AWS Lambdaにデプロイしています。 パッケージのサイズ制限を維持するために、依存関係は展開ファイルに含まれていませんでした。 アプリケーションをリモートでテストする場合、依存関係がないため、関数は実行されません。
どのアプローチで問題が解決しますか?

A)Lambdaコンソールエディターを使用してコードを更新し、不足している依存関係を含めます。

B)不足している依存関係を持つ追加の.zipファイルを作成し、元のLambdaデプロイメントパッケージにファイルを含めます。

C)Lambda関数の環境変数で欠落している依存関係への参照を追加します。

D)欠落している依存関係を含むLambda関数にレイヤーをアタッチします。




正解:D

解説
ユーザーは、AWS Lambda関数を設定して、追加のコードとコンテンツをレイヤーの形で取り込むことができます(AWS Lambda Layer)。 レイヤーは、ライブラリ、カスタムランタイム、またはその他の依存関係を含む.zipアーカイブです。 レイヤーを使用すると、ユーザーはライブラリを展開パッケージに含める必要なく、Lambda関数でライブラリを使用できます。


AWS Lambda Layerを知っていれば解ける問題。知らなければほぼ解けなそう


10問目

開発者は、Amazon API Gatewayを使用するウェブアプリケーションを構築しています。 開発者は
開発および本番(devおよびprod)ワークロード用に異なる環境を維持します。 APIは、開発用と製品用の2つのエイリアスを持つAWS Lambda関数によってサポートされます。
最小限の構成でこれをどのように実現できますか?

A)環境ごとにREST APIを作成し、対応するLambda関数のdevおよびprodエイリアスとAPIを統合します。次に、2つのAPIをそれぞれのステージにデプロイし、ステージURLを使用してアクセスします。

B)REST APIを1つ作成し、エイリアスの代わりにステージ変数を使用してLambda関数と統合します。次に、APIを2つの異なるステージ(devとprod)にデプロイし、各ステージで値として異なるエイリアスを使用してステージ変数を作成します。さまざまなステージURLを使用してAPIにアクセスします。

C)REST APIを1つ作成し、Lambda関数のdevエイリアスと統合して、それをdev環境にデプロイします。カナリアがLambda prodエイリアスと統合されるprodのカナリアリリース展開を設定します。

D)REST APIを1つ作成し、Lambda関数のprodエイリアスと統合して、prod環境にデプロイします。カナリアがLambda devエイリアスと統合されるdevのカナリアリリース展開を設定します。




正解:B

解説
Amazon API Gatewayの展開ステージを使用すると、ユーザーは、アルファ、ベータ、本番など、各APIの複数のリリースステージを管理できます。 構成可能なステージ変数を使用して、APIデプロイメントステージはさまざまなバックエンドのエンドポイントを使用できます。 ユーザーはAPI Gatewayステージ変数を使用して、複数のバージョンとエイリアスを持つ単一のAWS Lambdaを参照できます。

余談

原文のままのただの翻訳なので解説は基本答えになった選択肢で使用しているサービスの概要を書いてあることが大半です。どうやって問題の答えを出すかは解説のリンク先やサービスの概要を把握して解答するか、ありえない説明を省く消去法しかなさそうです。普通のテストと同じですね。
自分はAmazon Cognitoの理解が甘かったので復習する予定です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CircleCIでbranchへのpushはテスト環境にデプロイする設定をしてみたがS3とCloudFrontの接続でちょっとミスした話

目的

前回、GitHubへpushしたリソースをCircleCIを使ってS3へデプロイする構成を作ってみました。
今回はよりリアルな製品開発をイメージしてテスト環境と本番環境が分かれていることを想定し、branchへのコミットをテスト環境、masterへのコミットを本番環境へデプロイするようにs3とCiecleCIの設定を行いました。

その中でS3の設定でミスに気づきましたので、対処方法含め共有します。

構成図

利用サービスやアーキテクトは前回と同じです。テストと本番の2環境となります。
Arch5-test.png

Arch4-test.png

環境構築

CircleCIのyaml設定

前回の設定値に「テスト環境のbucket名」とmasterへpushしなかった場合の処理を記載しました。
本来であればbranchへのpushを明示すべきですが、elseで処理してます。

config.yml
version: 2
jobs:
  build:
    working_directory: ~/repo
    environment:
      - AWS_S3_BUCKET_NAME: my-bcuket
      - AWS_S3_BUCKET_NAME_TEST: my-bcuket-test
      - AWS_S3_BUCKET_EXCLUDE: .*/*
    docker:
      - image: innovatorjapan/awscli:latest
    steps:
      - checkout
      - run:
          name: Deploy to Master or Branch.
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
              aws s3 sync ~/repo s3://${AWS_S3_BUCKET_NAME}/ --exact-timestamps --delete  --exclude "${AWS_S3_BUCKET_EXCLUDE}"
            else
              aws s3 sync ~/repo s3://${AWS_S3_BUCKET_NAME_TEST}/ --exact-timestamps --delete  --exclude "${AWS_S3_BUCKET_EXCLUDE}"
            fi

S3バケット作成

AWS_S3_BUCKET_NAME_TEST: で命名したbucketを作成します。
S3バケットの作成には「既存のバケットから設定をコピー」というオプションがあるので、前回作成した本番用バケットから設定をコピーしましたが、後述の理由で再作成となりました。
s3_2.PNG

S3のアクセスログは今回は省略しました。
s3_3.PNG

作成後、バケットポリシーの設定をコピーします。最終的にはここがエラーの原因だと気づきました。

bucket.policy
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bcuket-test/*"
        },
        {
            "Sid": "forCircleCi",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/CircleCI"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::webpage-my-bcuket-test",
                "arn:aws:s3:::webpage-my-bcuket-test/*"
            ]
        }
    ]
}

CloudFront

前回作成した環境と同様にS3をオリジンとして設定します。
CFConf4.png

Route53レコードセット追加

レコードセットの作成からテスト環境のドメインを登録します。
R53conf3.png

接続できない

S3のAccess denyページが表示されてしまいました。
設定ドメインからS3のエラーページが見えたので、Route53とCloudfront間の設定は正しい、S3とCloudfront間の問題と気づきました。

原因

CloudFront Origin Access Identityの値がなぜかCloudfrontから自動Updateされず、コピー元の設定が残ってしまいました。
おそらくパケットポリシーにCircleCiの許可設定など標準外の値が入っていたためだと推測しております。

bucket.policy
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXX" #←これ
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bcuket-test/*"
        },
        {
            "Sid": "forCircleCi",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::XXXXXXXXXXXX:user/CircleCI"
            },
            "Action": [
                "s3:PutObject",
                "s3:ListBucket",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::webpage-my-bcuket-test",
                "arn:aws:s3:::webpage-my-bcuket-test/*"
            ]
        }
    ]
}

対策

上記原因に気づくのに遅れ、S3バケットの作成をやりなおした結果無事テストページにアクセスできました。
Diffチェックを行えばもう少し早めに気づくことができ、S3の設定をコピーした後のパケットポリシーで、CloudFront Origin Access Identityの値を手動で変更すればアクセスできたと推察しております。

所感

接続トラブルの際はパラメータは一つ一つ検証する必要があります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda用に.NET Coreで書いたAPIサーバをDockerでローカルでも実行させてみた

AWS Lambda用に.NET Coreで書いたAPIサーバをDockerでローカルでも実行させてみた

はじめに

.NET CoreもC#も未経験の筆者が、AWS上で.NET Core Webアプリケーションを作成する必要に駆られたので、お試しでデプロイとローカルデバグ用の開発環境を構築してみました。
備忘録を兼ねてメモを残します (テック記事は人のためならず)。

これはアカンとか、何書いているのププみたいなことがあればご指摘いただけますと、たいへんありがたいです。

Introduction

今回の要件は以下の通りです。

  • 開発は.NET Core (この記事執筆時点では2.1)
  • 開発言語はC#
  • 動作環境はAWS Serverless Architecture (APIGateway + Lambda + DynamoDB etc.)

なお、開発環境としてはVisual Studio 2019を使用しています。
なお、機能として、"ASP.NETとWeb開発"と".NET Coreクロスプラットフォームの開発"をインストールしています。

準備

プロジェクトを開始する前に、以下の準備を行います。

AWS toolkit for Visual Studio 2017 and 2019

拡張機能としてVisual Studio Marketplaceから、"AWS toolkit for Visual Studio 2017 and 2019"をインストールします。

"拡張機能"メニュー → "拡張機能の管理" → "AWS toolkit for Visual Studio 2017 and 2019"を検索してインストール

AWS Explorer

Visual StudioでAWS Explorerを起動し、今回の環境を実行するAWSへのアクセス情報Profileを作成します。

"表示"メニュー → "AWS Explorer" → "New Account Profile"ボタン

Profileの各項目は以下のように入力します。

Profile Name
default
Storage Location
Shared Credentials File
Access Key ID
今回の作業に必要な権限を持つユーザーのAccess Key
Secret Access Key
同じくユーザーのSecret Access Key
Account Number
AWSアカウントID

aws configure

Power Shellなどを起動し、aws configureコマンドを実行して、AWSへの接続情報を入力します。

PS C:\Users\hogehoge> aws configure
AWS Access Key ID
上記のprofileと同じAccess Key
AWS Secret Access Key
上記のprofileと同じSecret Access Key
Default region name
ap-northeast-1
Default output format
json

Docker Desktop

dockerを使用しますので、Docker Desktopをインストールします。

Docker Desktopを実行する場合は、コントロールパネルで、Windowsの機能として"Hyper-V"と"Windows ハイパーバイザープラットフォーム"を有効にする必要があります。なお、"Hyper-V"を使用するため"VirtualBox"アプリケーションは使用できなくなってしまいます(残念)。

REST API用ツール

テスト用に、REST APIにアクセスするためのツールやブラウザのextensionがあると便利です。

ソリューション作成

Visual Studioを使って、冒頭の要件に合うプロジェクトを作っていきます。
今回は、プロジェクトテンプレート"AWS Serverless Application with Tests (.NET Core - C#)"内の"Blog API using DynamoDB"をテンプレートとして使用します。

また、ローカル環境上でDockerコンテナとして動作するASP.NET Coreアプリケーションも同時に作成します。これにより、AWS環境がなくてもデバグが可能になります(今回はSAM(Serverless Application Model)のlocal環境機能は使用しません)。

structure.png

ソリューション(Serverless Applicationプロジェクト)新規作成

Visual Studioを起動し、新しいプロジェクトの作成ダイアログを起動します。

"ファイル"メニュー → "新規作成" → "プロジェクト"

テンプレートとして、"AWS Serverless Application with Tests (.NET Core - C#)"を選択します。
なお、今回は、プロジェクト名とソリューション名を"Hoge"にし、Blueprintとして"Blog API using DynamoDB"を選択します。

すると、ソリューションには、Serverless Application用プロジェクト"Hoge"と、そのテスト用プロジェクト"Hoge.Tests"が作成されているはずです。

共通プロジェクト

.NET Coreを使用したServerless Applicationと、ローカルのDockerで動作させるためのASP.NET Coreアプリケーションの両方で共通で使用するたの.NET Core Library用のプロジェクトを作成します。

再び、新規プロジェクトを作成しますが、今度は、プロジェクトテンプレートとして"クラス ライブラリ(.NET Core)"を選択します。

ソリューションエクスプローラで、ソリューション"Hoge"を右クリック → "追加" → "新しいプロジェクト"

プロジェクト名を"HogeLib"にして、プロジェクトを作成します。
プロジェクトを作成したら、対象のフレームワークを".NET Core 2.1"に変更します。

ソリューションエクスプローラで、"HogeLib"プロジェクトを右クリック → "プロパティ" → "対象のフレームワーク"を変更

参照関係の修正

"Hoge"プロジェクトから"HogeLib"を参照できるように、設定を追加します。

ソリューションエクスプローラで、"Hoge"を右クリック → "追加" → "参照"

参照するプロジェクトとして"HogeLib"のチェックボックスを有効にしてから、"OK"を押します。

共通コードの作成

今回の共通コードの作成は、HogeプロジェクトのBlog.csモデルクラスを、HogeLibプロジェクトに移動させるだけにします。
本来であれば、ロジックも移動させるのですが、説明と修正を簡単にするために、今回はモデルクラスのみの移動とします。

モデルクラスの移動は以下のように行いました (JetBrains社のRiderがあれば簡単なんですが・・・)。

  • HogeLib/Class1.csはもう必要無いので削除
  • HogeLibプロジェクト下に新しいフォルダー"Models"を作成
  • Hoge/Blog.csをHogeLib/Modelsフォルダの下にMove
  • HogeLib/Models/Blog.csのnamespaceを"Hoge"から"HogeLib.Models"に変更
  • Hoge/Functions.csに"using HogeLib.Models"を追加
  • Hoge.Tests/FunctionTest.csに"using HogeLib.Models"を追加

Regionの変更

"Blog API using DynamoDB"BluePrintで生成されたコードはそのままではRegionの関係で動かないので、コードを修正します。

Hoge\Functions.cs
//this.DDBContext = new DynamoDBContext(new AmazonDynamoDBClient(), config);
this.DDBContext = new DynamoDBContext(new AmazonDynamoDBClient(RegionEndpoint.APNortheast1), config);
Hoge.Tests\FunctionTest.cs
//this.DDBClient = new AmazonDynamoDBClient(RegionEndpoint.USWest2);
this.DDBClient = new AmazonDynamoDBClient(RegionEndpoint.APNortheast1);

Publish

これで、Serverless Application用の修正は完了しましたので、ひとまずAWSにPublishします。

ソリューションエクスプローラで、"Hoge"を右クリック → "Publish to AWS Lambda..."

ダイアログの各項目は、以下のように設定します。
なお、Publishに使用するS3バケットは、予めAWSコンソールで作成しておくか、ダイアログ上の"New..."ボタンで作成します。

Account profile to use
default
Region
Asia Pacific (Tokyo)
Build Settings Configuration
Release
Framework
netcoreapp2.1
Stack Name
HogeStackFoo (Fooは他の人と被らないようにするための適当な文字列。同一AWSアカウント内で衝突しないように)
S3 Bucket
hogestackfoo (Fooは他の人と被らないようにするための適当な文字列。なお上記のstackと同じである必要は無い。S3の命名規則に注意)
BlogTableName
Hoge-Blog-Foo (Fooは他の人と被らないようにするための適当な文字列。同一AWSアカウント内で衝突しないように)
ReadCapacity
1 (テスト用なので小さくてok)
ShouldCreateTable
true
WriteCapacity
1 (テスト用なので小さくてok)

しばらくして、進行状況画面のStatusが"CREATE_IN_PROGRESS"から"CREATE_COMPLETE"になればPublish完了です。

なお、BlogTableNameを空にしておくと自動的に適当な名前をつけてくれるのですが、この後、Mock Lambda Test Toolでテーブル名を指定する必要があるので、ここでは明示的に名前を付けています。

Mock Lambda Test Tool

AWS上のlambdaを直接デバグするためのツール"Mock Lambda Test Tool"用の設定を変更します。
変更箇所は、環境変数BlogTableに、一つ前のフェーズでBlogTableNameに指定した名前を設定したことです。

Hoge\Properties\launchSettings.json
{
  "profiles": {
    "Mock Lambda Test Tool": {
      "commandName": "Executable",
      "commandLineArgs": "--port 5050",
      "workingDirectory": ".\\bin\\Debug\\netcoreapp2.1",
      "executablePath": "C:\\Users\\%USERNAME%\\.dotnet\\tools\\dotnet-lambda-test-tool-2.1.exe",
      "environmentVariables": {
        "BlogTable": "Hoge-Blog-Foo"
      }
    }
  }
}

ASP.NET Core用プロジェクトの追加

ローカルのdocker環境で動作させるためのASP.NET Coreアプリケーション用のプロジェクトを追加します。

プロジェクトテンプレートとして"ASP.NET Core Web アプリケーション (C#)"を選択します。

ソリューションエクスプローラで、ソリューション"Hoge"を右クリック → "追加" → "新しいプロジェクト"

プロジェクト名を"HogeWebApi"にします。その他の項目は以下のように設定します。

SDK
.NET Core ASP.NET Core 2.1
プロジェクトテンプレート
API
認証
認証なし
HTTPS用の構成
無効(チェックを外す)
Dockerサポートを有効にする
有効(チェックする)
OS
Linux

HogeWebApiからHogeLibを参照するようにします。

ソリューションエクスプローラで、"HogeWebApi"を右クリック → "追加" → "参照"

参照するプロジェクトとして"HogeLib"のチェックボックスを有効にしてから、"OK"を押します。

次に、NuGetパッケージとしてAWSSDK.DynamoDBv2"をインストールします。

ソリューションエクスプローラで、"HogeWebApi"を右クリック → "NuGetパッケージの管理"

ASP.NET Core用のクロスプラットフォーム用WebサーバであるKestrel用にユーザーシークレットを作成する必要があるので、以下の操作でユーザーシックレット用のファイルを作成しておきます(中身は空のままでかまいません)。

ソリューションエクスプローラで、"HogeWebApi"を右クリック → "ユーザーシークレットの管理"

また、今回"wwwroot"ディレクトリは使わないので、削除してしまいます。

docker-composeプロジェクトの追加

HogeWebApi ASP.NET Coreアプリケーションを動作させるためのオーケストレーション用プロジェクトとしてdocker-composeプロジェクトを手動で作成します。

エクスプローラ、PowerShellなどでHogeソリューションプロジェクトの直下に、"DockerCompose"というディレクトリを作成します。
そして、DockerCompose下に以下のVisual Studioのプロジェクトファイル(docker-compose.dcproj)をエディタ等で作成します。

DockerCompose\docker-compose.dcproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" Sdk="Microsoft.Docker.Sdk">
  <PropertyGroup Label="Globals">
    <ProjectVersion>2.1</ProjectVersion>
    <DockerTargetOS>Linux</DockerTargetOS>
    <ProjectGuid>7530e2b9-bdab-44ab-87df-c6e6fc69b1b2</ProjectGuid>
    <DockerLaunchAction>None</DockerLaunchAction>
    <DockerServiceName>hogewebapi</DockerServiceName>
  </PropertyGroup>
</Project>

このプロジェクトファイルをソリューション"Hoge"に追加します。

ソリューションエクスプローラで、ソリューション"Hoge"を右クリック → "追加" → "既存のプロジェクト"

docker-composeプロジェクトの作成

まず、localで動作するdynamodbのDockerコンテナを作成します。
docker-composeプロジェクトに"localdynamodb"フォルダを作成します。

ソリューションエクスプローラで、"docker-compose"を右クリック → "追加" → "新しいフォルダー" → "localdynamodb"にリネーム

localdynamodbフォルダの下に以下の二つのファイルをエディタ等で作成します。

FROM openjdk:8-jre

RUN mkdir /var/dynamodb_local
WORKDIR /var/dynamodb_local

RUN curl -fsSL https://s3-ap-northeast-1.amazonaws.com/dynamodb-local-tokyo/dynamodb_local_latest.tar.gz -o dynamodb.tar.gz \
  && tar xzf dynamodb.tar.gz \
  && rm dynamodb.tar.gz

COPY entrypoint.sh /bin/
RUN chmod 755 /bin/entrypoint.sh

ENTRYPOINT ["/bin/entrypoint.sh"]

EXPOSE 8000
DockerCompose\localdynamodb\entrypoint.sh
#!/bin/sh

set -- java "$@"
set -- "$@" -Djava.library.path=/var/dynamodb_local/DynamoDBLocal_lib
set -- "$@" -jar /var/dynamodb_local/DynamoDBLocal.jar
set -- "$@" -sharedDb
set -- "$@" -dbPath /data
set -- "$@" -port 8000
exec "$@"

localdynamodbフォルダにこの二つのファイルを追加します。

ソリューションエクスプローラで、フォルダ"localdynamodb"を右クリック → "追加" → "既存の項目" → 今回作成した"Dockerfile"と"entrypoint.sh"を指定

docker-compose用設定ファイルを作成します。
エディタ等でDockerComposeフォルダ下に以下のファイルを作成します。

DockerCompose\docker-compose.yml
version: '3.4'

services:
  hogewebapi:
    image: ${DOCKER_REGISTRY-}hogewebapi
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
    build:
      context: ..
      dockerfile: HogeWebApi/Dockerfile
    container_name: hogewebapi
    ports:
      - "80"
      - "443"
    volumes:
      - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
    networks:
      - private_net

  localdynamodb:
    build:
      context: ./localdynamodb
    container_name: localdynamodb
    ports:
      - "8000"
    volumes:
      - dynamodb-data:/data
    networks:
      - private_net

networks:
  private_net:

volumes:
  dynamodb-data:

docker-compose.ymlファイルをdocker-composeプロジェクトに追加します。

ソリューションエクスプローラで、"docker-compose"を右クリック → "追加" → "既存の項目" → 今回作成した"docker-compose.yml"を指定

ASP.NET Coreアプリケーション用コントローラの作成

ASP.NET Coreアプリケーション用のコントローラを作成します。
コントローラの内容はAWS Serverlessアプリケーション用のBlog処理と同じ内容になります。

まず、テンプレートで作成されたサンプル用コントローラを削除します。

HogeWebApi\Controllers\ValuesController.csを削除

次にBlog用コントローラを追加します。
コントローラーの種類は"APIコントローラー - 空"を選択します。コントローラー名は"BlogController"にします。

ソリューションエクスプローラで、"HogeWebApi"のフォルダ"Controllers"を右クリック → "追加" → "コントローラー" → "APIコントローラー -空"

BlogController.csの内容は以下のようになります。
なお、処理内容は、lambda用の.NET CORE アプリケーションのものとほぼ同様です (Hoge\Functions.cs)。

HogeWebApi/Controllers/BlogController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

using HogeLib.Models;

using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.Model;

namespace HogeWebApi.Controllers {
    [Route("blog")]
    [ApiController]
    public class BlogController : ControllerBase {
        IDynamoDBContext DDBContext {
            get; set;
        }

        /// <summary>
        /// Default constructor that Controller will invoke.
        /// </summary>
        public BlogController() {
            // Check to see if a table name was passed in through environment variables and if so 
            // add the table mapping.
            var tableName = "Hoge_Blog";
            AWSConfigsDynamoDB.Context.TypeMappings[typeof(Blog)] = new Amazon.Util.TypeMapping(typeof(Blog), tableName);

            AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig { ServiceURL = "http://localdynamodb:8000" };
            AmazonDynamoDBClient client = new AmazonDynamoDBClient("dummy", "dummy", clientConfig);

            try {
                // DynamoDB内にテーブルが無ければ新規作成する。もちろん本番用Controllerでこんなことをしてはいけない
                Task<CreateTableResponse> response = client.CreateTableAsync(
                    tableName,
                    new List<KeySchemaElement> {
                        new KeySchemaElement("Id", KeyType.HASH)
                    },
                     new List<AttributeDefinition> {
                        new AttributeDefinition("Id", ScalarAttributeType.S)
                    },
                    new ProvisionedThroughput {
                        ReadCapacityUnits = 1,
                        WriteCapacityUnits = 1
                    },
                    new System.Threading.CancellationToken()
                );
                response.Wait();
            } catch (Exception _) {
                // すでにあるならなにもしない
            }

            var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2 };
            this.DDBContext = new DynamoDBContext(client, config);
        }

        // GET: blog
        [HttpGet]
        public async Task<IEnumerable<Blog>> GetAsync() {
            var search = this.DDBContext.ScanAsync<Blog>(null);
            var blogs = await search.GetNextSetAsync();

            return blogs;
        }

        // GET: blog/blogId
        [HttpGet("{blogId}", Name = "Get")]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public async Task<ActionResult<Blog>> GetAsync(string blogId) {
            if (string.IsNullOrEmpty(blogId)) {
                return BadRequest();
            }

            var blog = await DDBContext.LoadAsync<Blog>(blogId);
            if (blog == null) {
                return NotFound();
            }

            return blog;
        }

        // PUT: blog
        [HttpPut]
        [ProducesResponseType(StatusCodes.Status202Accepted)]
        public async Task<ActionResult> PutAsync([FromBody] Blog blog) {
            blog.Id = Guid.NewGuid().ToString();
            blog.CreatedTimestamp = DateTime.Now;

            await DDBContext.SaveAsync<Blog>(blog);

            return Accepted();
        }

        // DELETE: blog/blogId
        [HttpDelete("{blogId}")]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status202Accepted)]
        public async Task<ActionResult> DeleteAsync(string blogId) {
            if (string.IsNullOrEmpty(blogId)) {
                return BadRequest();
            }

            await this.DDBContext.DeleteAsync<Blog>(blogId);

            return Accepted();
        }
    }
}

BlogController用にlaunchSettings.jsonを変更します。

HogeWebApi\Properties\launchSettings.json

  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:60100",
      "sslPort": 0
    }
  },
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "blog",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "HogeWebApi": {
      "commandName": "Project",
      "launchBrowser": true,
      "launchUrl": "blog",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "http://localhost:5000"
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/blog",
      "publishAllPorts": true
    }
  }
}

実行してみる

これで準備ができました。Ready Perfectly。
これにより、以下のことが行えるようになります。

  • AWSにデプロイして、API Gateway経由で.NET Core on Lambdaを呼び出せるようになる
  • Testプロジェクトを実行することができる
  • Mock Lambda Test Toolを使って、Lambdaのデバグが行える
  • ローカルにDockerによるASP.NET Core環境を構築して、直接デバグすることができる

AWSデプロイ

開発中に一旦デプロイしていますが、もう一度デプロイ方法を記載しておきます。

ソリューションエクスプローラで、"Hoge"を右クリック → "Publish to AWS Lambda..."

デプロイすると、状況表示画面に"AWS Serverless URL"が表示されます。
見逃してしまった場合は、ブラウザでAWSコンソールのAPI Gatewayメニューで確認するか、AWS ExplorerのAWS CloudFormationのStackをダブルクリックします。

Serverless URLを確認したら、お好みのREST Clientツールで、以下のアドレスに"GET"メソッドでアクセスしてみます。

GET https://<<なんらかの文字列>>.execute-api.ap-northeast-1.amazonaws.com/Prod

初回起動時には、DynamoDBに何のデータも登録されていないので、空のJSON配列が返ってくるはずです。

[]

次にデータを登録してみます。同じURLにPUTしてみます。
また、本文には登録するデータを表すJsonを指定します。

PUT https://<<なんらかの文字列>>.execute-api.ap-northeast-1.amazonaws.com/Prod
Content-Type: text/json; charset=UTF-8

{"Name":"作者","Content":"中身"}

登録したデータのidがplain textで返ってくるはずです。

ここで、もう一度"GET"してみると、データが登録されているのが分かります。

[
  {
    "Id": "9612b9af-a4bc-45f6-a366-a33a7c03ec3d",
    "Name": "作者",
    "Content": "中身",
    "CreatedTimestamp": "2020-01-17T01:31:56.002+00:00"
  }
]

テスト

最初に、プロジェクトテンプレート"AWS Serverless Application with Tests (.NET Core - C#)"内の"Blog API using DynamoDB"をテンプレートとして作成していますので、自動的にテストケースが登録されているはずです。

それでは、テストを実行してみます。

ソリューションエクスプローラで、"Hoge.Tests"を右クリック → "テストの実行"

BlogTestAsyncが成功になっていれば、テストOKです。
すでにテスト済みになっていて、もう一度テストしたい場合には、ビルドメニューから"Hoge.Tests"をリビルドしてみてからテスト実行してください。

もちろん、テストをデバグモードで実行すると、テストコードや、そこから呼び出される本体コードをデバグすることができます。

Mock Lambda Test Tool

Visual Studio上でMock Lambda Test Toolを使用することで、直接Lambdaをテスト/デバグすることができます。

Mock Lambda Test Toolを起動すると、デフォルトブラウザに"localhost:5050"へのアクセスが行われて、AWS .NET Mock Lambda Test Tool (Preview)が表示されます。

試しに、Visual Studio上でFunctions.csを開き、関数GetBlogsAsync (GetBlogAsyncでは無い) にブレークポイントを張ります。
そして、AWS .NET Mock Lambda Test Toolに以下のように入力して、Execute Functionを実行します。

Config File
aws-lambda-tools-defaults.json
Function
GetBlogs
AWS Credential Profile
default
AWS Region
ap-northeast-1
Example Requests
API Gateway AWS Proxy
リクエストの中身
Get Blogsはリクエストを参照していないので、そのままでOKです。AddBlogなどをテストする場合は、適宜書き換えてください

実行すると、ブレークポイントで停止するはずです。
そのまま処理を続行すると、Responseとして、AWS デプロイの項目で登録した内容が表示されているはずです。
また、Log Outputには、GetBlogsAsync内のcontext.Loggerに出力したログ内容が表示されています。

Docker

Dockerを実行する場合は、docker-composeをスタートアッププロジェクトに設定します。

ソリューションエクスプローラで、"docker-compose"を右クリック → "スタートアッププロジェクトに設定"

docker-composeをビルド (なにかうまく行かないときはリビルドも試して・・)して、デバグを開始します。

なお、コンテナとして、hogewebapiとlocaldynamodbコンテナが起動しているはずです。
コンテナウィンドウでhogewebapiをクリックして、コンテナーポート80に対応するホストポートを調べます (327xxぐらい)。
または、PowerShellなどを使って、dockerコマンドでポートを調べてもかまいません。

PS C:\Users\hogehoge> docker ps
CONTAINER ID        IMAGE                                             COMMAND                CREATED             STATUS              PORTS                                           NAMES
932693b5dd9f        dockercompose15818753263670802938_localdynamodb   "/bin/entrypoint.sh"   20 minutes ago      Up 20 minutes       0.0.0.0:32778->8000/tcp                         localdynamodb
375a9952a4b6        hogewebapi:dev                                    "tail -f /dev/null"    20 minutes ago      Up 16 minutes       0.0.0.0:32780->80/tcp, 0.0.0.0:32779->443/tcp   hogewebapi
PS C:\Users\hogehoge>

お好みのREST Clientツールで、ローカルで起動しているASP.NET Coreアプリケーションにアクセスしてみます。

GET http://localhost:32780/blog

初回起動時には、DynamoDBに何のデータも登録されていないので、空のJSON配列が返ってくるはずです。

次にデータを登録してみます。同じURLにPUTしてみます。
また、本文には登録するデータを表すJsonを指定します。

PUT http://localhost:32780/blog
Content-Type: text/json; charset=UTF-8

{"Name":"作者2","Content":"中身2"}

登録に成功すると、202 Acceptedが返ってくるはずです。

ここで、もう一度"GET"してみると、データが登録されているのが分かります。

[
  {
    "id": "7cc5b03d-639d-40e8-8692-22b99e779c02",
    "name": "作者2",
    "content": "中身2",
    "createdTimestamp": "2020-01-17T03:16:42.561+00:00"
  }
]

もちろん、ブレークポイントを使ってデバグをすることもできます。
例えば、HogeWebApi/Controllerse/BlogController.csの各メソッドで試すことができます。

おまけ(GitHub)

作成したプロジェクトをGitHubに保存しておきます。

拡張機能としてVisual Studio Marketplaceから、"GitHub Extension for Visual Studio"をインストールします。

"拡張機能"メニュー → "拡張機能の管理" → "GitHub Extension for Visual Studio"を検索してインストール

次に表示メニューからチームエクスプローラーを選択し、GitHubに接続します。

"表示"メニュー → "チームエクスプローラー" → "GitHub" → GitHubアカウントでサインイン

必要であれば、Git設定を変更します(ユーザー名、メールアドレス、既定のリポジトリの場所 (今回作成したHogeソリューションの一つ上を指定))。
そして、ソリューション"Hoge"を右クリックして、"ソリューションをソース管理に追加"を選びます。
すると、「現在のソリューションには、ソリューションフォルダー外にあるなんとかかんとか統合してください。」とかいうダイアログが表示されますが、無視して"OK"ボタンを押してください。

チームエクスプローラーから"同期"を選んで、リポジトリ名などを入力すれば、GitHubへのPushが始まります。

こうしてできたリポジトリがこちらになります。

https://github.com/dynamitecoolguy/Hoge

修正履歴

まだありません

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go×CloudWatchでファイル取得状況をカスタムメトリクス化する

今回はAWS-SDKを用いて、大量のデータを取得するEC2インスタンスの1時間当たりのファイル取得量をCloudWatchでカスタムメトリクス化して取得状況を監視するシステムを作成したので、一部をご紹介します。

AWS関連の部分以外はGoの標準パッケージのみで作るシンプルなものになっています。

Goでファイル取得数を計算する

下記のプログラムで現在のファイル取得数と経過時間を計算します。
コード自体はとてもシンプルです。

package calculator

import (
    "fmt"
    "io/ioutil"
    "math"
    "os"
    "path/filepath"
    "sort"
)

func GetFetchSpeed() (float64, error) {
    dir := `取得したいディレクトリ`
//ディレクトリからファイルを取得
    files, err := ioutil.ReadDir(filepath.Dir(dir))
    if err != nil {
        return 0, err
    }
//編集日時順にファイルをソートします。
    sort.Slice(files, func(i, j int) bool {
        return files[i].ModTime().Unix() < files[j].ModTime().Unix()
    })

    firstFile, err := os.Stat(dir + files[0].Name())
   if err != nil {
        return 0, err
    }

    lastFile, _ := os.Stat(dir + files[len(files)-1].Name())
    if err != nil {
        return 0, err
    }
//最初のファイルを取得してからの経過時間を計算
    elapsedTime := lastFile.ModTime().Sub(firstFile.ModTime())
    if elapsedTime < 0 {
        elapsedTime *= -1
    }
//1時間ごとのファイル取得数
    elapsedMinute := math.Trunc(elapsedTime.Minutes())
    fetchedPerHour := len(files) / int(elapsedMinute) * 60

    return float64(fetchedPerHour), nil
}



取得した情報をCloudWatchでメトリクス化する。

package metrics

import (
    "fmt"
    "io/ioutil"
    "net/http"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/cloudwatch"
)

func getInstanceID() string {
//このアドレスにアクセスするとEC2インスタンスのインスタンスIDを取得することができます。
    resp, err := http.Get("http://169.254.169.254/latest/meta-data/instance-id")
    if err != nil {
        fmt.Println(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
    }
    return string(body)
}

//メトリクスを作成します
func CreateMetrics(value float64) {
    cw := cloudwatch.New(session.New(), &aws.Config{Region: aws.String("ap-northeast-1")})

    dimensionParam := &cloudwatch.Dimension{
        Name:  aws.String("InstanceId"),
        Value: aws.String(getInstanceID()),
    }

    metricDataParam := &cloudwatch.MetricDatum{
        Dimensions: []*cloudwatch.Dimension{dimensionParam},
        MetricName: aws.String("Files per 1Hour"),
        Unit:       aws.String("Count"),
        Value:      aws.Float64(value),
    }

    putMetricsDataInput := &cloudwatch.PutMetricDataInput{
        MetricData: []*cloudwatch.MetricDatum{metricDataParam},
//メトリクスの名前空間
        Namespace:  aws.String("EC2"),
    }
    cw.PutMetricData(putMetricsDataInput)
}


この二つのパッケージをmain.goで実行します。

func main() {
    value, err := calculator.GetFetchSpeed()
    if err != nil {
        fmt.Printf("Error while calculatoring speed:%s\n", err)
    }
    if value > 0 {
        metrics.CreateMetrics(value)
    }
}

以上になります。

このメトリクス化する仕組みを用いればいろんなものを可視化することができるので、監視や運用に役立つかと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nginx経由でRailsをAWS環境で起動できないエラー時にまず確かめたいこと、使えるコマンド。

表題の内容に関して、チェックすべきポイントを
備忘録として以下に記す。

そもそもURLは正しいか?

Nginx導入の際に、unicorn.rb内の記述を変更していると思うので、
改めてブラウザからElastic IPでアクセスしてみる。

データベースは起動しているか?

Mysql使用時は以下を実行して確認。

ターミナル
[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>] $ sudo service mysqld start
#上記実行後running...と表示されていればOK

Railsは起動しているか?

unicorn使用時には以下を実行して確認。

ターミナル
[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>] $ bundle exec unicorn_rails -c config/unicorn.rb -E production -D #エラー文が表示されなければOK

master failed to start, check stderr log for details #このようなエラー文がでた場合は以下を実行して詳細を確認する。

[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ less log/unicorn.stderr.log #実行すると上から古い順にエラーのログが表示されるので、原因を探す。

I, [2016-12-21T04:01:19.135154 #18813]  INFO -- : Refreshing Gem list
I, [2016-12-21T04:01:20.732521 #18813]  INFO -- : listening on addr=0.0.0.0:3000 fd=10
E, [2016-12-21T04:01:20.734067 #18813] ERROR -- : Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)  #このようにエラーの履歴がいくつか表示されるので、未解決のものを下から潰していく
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/mysql2_adapter.rb:29:in `rescue in mysql2_connection'
/home/ec2-user/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/mysql2_adapter.rb:12:in `mysql2_connection'
#以下略

unicornのプロセスは停止されているか?

まず以下を実行してunicornのプロセスを確認。

ターミナル
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn #左記を実行すると以下にプロセスが表示される。

ec2-user 17877  0.4 18.1 588472 182840 ?       Sl   01:55   0:02 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 17881  0.0 17.3 589088 175164 ?       Sl   01:55   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 17911  0.0  0.2 110532  2180 pts/0    S+   02:05   0:00 grep --color=auto unicorn

上記のように停止されていないことが確認された場合
unicorn_rails masterの行のプロセスID(PID)を確認する。
左から2列目、5桁の数字がPIDで、今回の場合は17877となる。

その後以下の通りにkillコマンドを実行する。

ターミナル
kill 17877

再度プロセスの確認を行い、以下のように config/unicorn.rb の記述がある行が削除されていれば成功。

ターミナル
[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>]$ ps aux | grep unicorn
ec2-user 17911  0.0  0.2 110532  2180 pts/0    S+   02:05   0:00 grep --color=auto unicorn

Nginx内の記述を確認してみる。

確認するための記述は以下。

ターミナル
[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>]$ sudo vim /開きたいファイルのURI

アプリケーション名や、Elastic IP、その他記述に誤りがないか確認する。

※vimの操作に関しては、以下にとても参考になる記事のリンクを載せました。
https://qiita.com/knife0125/items/5e91176c8401acd6bb0a

現状の理解

ターミナルでの作業はなかなか理解が難しい。
特にvimを使用する場面は理解が浅いので今後学習を強化していきたい。

誤り等ございましたらご指摘のほどよろしくお願いいたします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

これだけでOK! AWS 認定ソリューションアーキテクト のメモ

オリジナルアプリをデプロイする時に、「これだけでOK! AWS 認定ソリューションアーキテクト」をudemyをメモ程度に残す。大事なところだけメモしますので、流し読み推奨。

セクション1 まずは知ってみる

コースの概要

AWSの概要を7分で話す。まだちんぷんかんぷん。

1.小テスト

実際のテストを3問見れる。質問の意味が分からず、一旦3問とも飛ばした。
文章形式になっているのでサーバ構築経験がないと答えづらいとのこと。

2.AWSアカウント登録

丁寧に登録方法を紹介。しっかりと画像がついているのでわかりやすい。
クレカ登録。一部有料枠が必要なので。基本的にはお金がかからないようにして下さる。
AWS課金は怖いと聞くので、注意しよう。

3.AWSでサーバーを構築してみる①

サーバーを買ってきて構築すること → オンプレミス
(クラウドの対義語)

AWSは、サーバーを立ち上げるのに数分で無料で今すぐにでも利用できるのが大きな特徴とのこと。
要は、クラウド上でサーバーを作るのは手軽で早いよ!といったところか。

windowsがベースで進む。

EC2の体験に進む。地域の変更で「東京へ」

インスタンスタイプの設定で、「メモリ」「CPU」「ストレージ」「ネットワークパフォーマンス」等を選べる。目的に応じて変えよう。

ステップ 2: インスタンスタイプの選択
ステップ 3: インスタンスの詳細の設定
→ 変更なし
ステップ 4: ストレージの追加
→ 変更なし
ステップ 5: タグの追加(インスタンスタイプの名前、用途、権限を分けることができる)
→ name を 設定し sample などの名前を振る
ステップ 6: セキュリティグループの設定(アクセス制御)
→ 変更なし
確認ボタン
キーペアの作成
→ 適宜名前を決めダウンロード

0.0.0.0/0 はフルオープンで誰でもアクセスできる。IPが決まっていたら制御できる。フルオープンなので、「全世界に開かれていますよーと警告が出る」
スクリーンショット 2020-01-17 9.47.38.png

インスタンスを作成するとpendingになり、数分経つとrunnningになる。
オンプレミスだとサーバー構築に時間がかかるけど、数分でサーバーを構築できる。というのは理解できた。

ECSインスタンス操作は、MacかWindowsかで操作方法が変わる。windowsはTeraTermを使うとのこと。Macのため割愛。

  1. 【MACの方向け】AWSでサーバーを構築してみる②

ダウンロードした pem を sshフォルダにいれる。

chmod 400 udemy-sample.pem等で 自分だけアクセスできるようにする。その後、下記のように接続。

ssh -i "udemy-sample.pem" ec2-user@ec2-3-112-225-37.ap-northeast-1.compute.amazonaws.com

ssh → ssh接続するコマンド
i → 秘密鍵ファイルを指定
"udemy-sample.pem" ec2-user@hogehoge → 秘密鍵を指定+ログインユーザー名@パブリックIPアドレス(hogehoge)を指定してアクセス。

スクリーンショット 2020-01-17 10.17.48.png
接続ボタン押して、表示される ssh -i 省略 を押すと動画より早くアクセスできた。

5 .sshの基礎

sshとは、 「リモートマシンの操作ツール」

SSH → クライアントとリモートマシンの間の通信を暗号化するプロトコル
SSHコマンド → SSH方式によってリモートマシン上でコマンドを実行するコマンド
SSHクライアント → SShによるリモートマシン操作を支援するコマンドプロンプトのソフトフェア

基本書式

ssh[オプション]ホスト名[コマンド]
を使って操作していく。

オプション一覧

『 -i 』:秘密鍵ファイル(identifyファイル)を指定
『 -l 』:ログインユーザ名を指定
『 -p 』:ポート番号を指定
『 -x 』:X11の転送を有効化
『 -1 』:SSHのプロトコルバージョン1を使用
『 -2 』:SSHのプロトコルバージョン2を使用
『 -4 』:IPv4を使用

コマンド一覧

『 ls 』:フォルダ/ファイル一覧を表示
『 cd 』:フォルダの場所を移動
『 pwd 』:現在のフォルダ位置を表示
『 cp 』:フォルダ/ファイルをコピー
『 mv 』:フォルダ/ファイルを移動
『 rm 』:フォルダ/ファイルを削除
『 mkdir 』:フォルダを作成

コマンドは分かる人は多いがオプションはどうだろう。

セクション2 Day1 対応の実施

6. Day1対応の実施

・ルートアカウントの利用を停止
→普段使うことはないので管理者権限を使う

・多要素認証を有効化する
→ 認証の仕組みがデフォルトだと無効なので、有効化する必要がある。会社で使うときはなおさら。

・AWS Cloud Trailを有効化する
→アクセスログを取っていく仕組み。セキュリティ上使う必要あり。

・AWSの請求レポートを有効化する
→ 請求レポート

ダッシュボードからIAMを検索。
スクリーンショット 2020-01-17 10.33.16.png
ルートアカウントの MFA を有効化→ MFAを有効化する。(省略)
google authenticatorを使って二段階認証。すごい(小並感)

7.個々のIAMのユーザーの作成

プログラムによるアクセス
AMSマネジメントコンソールへのアクセス
共にチェック。

スクリーンショット 2020-01-17 10.39.14.png

個々の IAM ユーザーの作成

IAMで検索→ 個々の IAM ユーザーの作成 → ユーザーの管理 → admin(adminアクセスにアタッチ) → タグ(role admin) で設定

スクリーンショット 2020-01-17 10.43.31.png

スクリーンショット 2020-01-17 10.43.46.png

ユーザー別に作成

先程のadminをクリック → アクセス権限の追加 → 既存のポリシーを直接アタック → AdministratorAccess にチェック → IAMユーザーが完成スクリーンショット 2020-01-17 10.50.00.png

パスワードポリシー

パスワードを任意の制約で設定。特に追加はしなかった。

スクリーンショット 2020-01-17 10.51.27.png

8. Day1 対応の実施③

ログの取得。S3を登録する、

9. Day1 対応の実施 ④

請求のアラート設定。

マイ請求ダッシュボードにいき、IAM ユーザー/ロールによる請求情報へのアクセス(オリアプの際は使わないと判断しスルーしました)
スクリーンショット 2020-01-17 11.15.51.png

Costexplolerにいき起動後、アラートを受け取るをチェック、
スクリーンショット 2020-01-17 11.22.50.png

ダッシュボードから CloudWatchを検索 → リージョンをバージニア北部に変更→ 左上の「請求」をクリック→ アラームを作成 → Currencyを JP に変更

スクリーンショット 2020-01-17 11.28.15.png

新しいトピックの選択→ アラート名、アドレスの登録、アラートの選択。

作成ボタンを押し、リージョンを東京に戻す。

完了。

ここまで終えて

設定量が多かった。ユーザーごとに管理を分けるというのが新鮮だった。

セクション3 AWSの仕組み

・オンプレサーバーではなくクラウドなので、時間もコストも少なく運用可能。
・ブロックパーツのように自分の好きなパーツを組みあせて構成を実現する仕組み
・アンマネージド型とマネージド型がある
aws-for-26-638.jpg

・リージョン→ 東京や香港やムンバイなど地理的に離れた領域。AWSのデータセンターがある大まかな場所のようなもの(日本には東京と大阪にある)
・アベイラビリティーゾーン(AZ)→ 各リージョンの中にあるデータセンターのようなもの→ リージョン内でAZは繋がっている。(低レイテンシー) 。AZは1つの複数の物理的なデータセンターで繋がっている。よって1つのAZ内のみでAWSを使っているとサービス停止とかでリスク高い。そのため、複数AZで分けるのが信頼性の高いシステム構成。

・エッジロケーション → キャッシュデータを利用する際に更に小さなエンドポイントとなる拠点

・AWSの操作

1.AWSマネジメントコンソール 
2.インスタンス操作 (SSH等)
3.AWS (CLI操作)

アソシエイト試験概要

AWSの操作ができるかじゃなくて、アーキテクチャ設計ができるか?が結構重要とのこと。

細かい点は省略

AWSの全体像

範囲など説明のため省略

セクションIAM

13.IAMの概要

執筆中です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者が5分で出来る簡単サーバレスAPIを構築してみる【Lambda】

はじめに

今回は機械学習ではないのですが、自分がAWSの試験を受けるにあたり、IT初心者としてサーバレスについてイメージが難しいところがありました。
サーバーへの考慮がいらない、サーバーのメンテナンスや管理をしなくていいと言われていますが、実際使い勝手などが分かりにくい。

少しでも理解できるようになるために、1杯のコーヒーよりもコストが低いAPIの作成を実践してみました!

image.png
AWS Black Belt 公式より抜粋

AWSのサーバレスサービス

サーバレスとは言いますが、サーバが存在していないわけでは無いのです。
あくまでもAWS側がサポートしてくれて、サーバを意識せずに、アプリケーションを作成したり運用できるサービスのことを指しています。

1. DynamoDB でテーブルを作る

データベースのidの番号から、名前を引っ張ってこれるような簡単なAPIを作っていきます。
まずは、データベースの DynamoDB にテーブルを作成していきます。
2020-01-10_09h21_19.png
テーブル名を入力して[デフォルト設定の使用]にチェックマークをつけて作成をクリック。
2020-01-10_09h23_00.png
数秒待つとテーブルが作成されます。出来上がったテーブルをクリックして、右の[項目]のタブから[項目の作成]をクリック。
2020-01-10_09h24_57.png
「id string:」の VALUE の項目にまず1という番号を入力して、+ボタンをクリックし、[Append]を選択してさらに[String]を選択します。
2020-01-10_09h30_30.png
FIELD という項目には[name]を入力し、 string の項目には適当な名前を入力します。
2020-01-10_10h41_06.png
同じ手順で三人分名前を登録しました。
2020-01-14_15h21_14.png

2. Lambda関数を作る

次は Lambda のコンソールへ行き、関数の作成に入ります。
2020-01-10_10h43_01.png
[一から作成]を選択している状態でまずは関数名を入力。
2020-01-10_10h45_58.png
ランタイムで関数の言語を選択します。今回使うのは[Node.js 10.x] 。
実行ロールの選択または作成を選択し、DynamoDB のアクセス権限をつけます。そして作成をクリック。
2020-01-10_10h48_47.png
次に DynamoDB からidの番号で名前を引っ張ってくるシンプルなコードを書いていきます。
2020-01-10_10h49_26.png
コードはこちら。

Node.js
 'use strict';
 const AWS = require('aws-sdk');
 const dynamo = new AWS.DynamoDB.DocumentClient();
 const createResponse = (statusCode, body) => ({ statusCode, body });
 
 exports.handler = (event, context, callback) => {
#テーブル名を指定
    let params = {
        TableName: 'test' ,
        Key: {
            id: event.pathParameters.id
        }
    };

    let dbGet = (params) => { return dynamo.get(params).promise() };

    dbGet(params).then( (data) => {
        if (!data.Item) {
            callback(null,createResponse(404, "ITEM NOT FOUND"));
            return;
        }
        callback(null, createResponse(200, JSON.stringify(data.Item)));
    }).catch( (err) => {
        callback(null, createResponse(500, err));
    });
};

index.js のデフォルトのコードを削除して書き直します。右の[保存]をクリックして更新します。
2020-01-10_16h46_21.png

3. API をデプロイする

API Gateway のコンソールへ行き、API の作成に入ります。
2020-01-10_17h09_16.png
リソースの横にある、アクションのプルダウンから[リソースの作成]を選択。
image.png
リソース名を入力して[リソースの作成]をクリック。
2020-01-10_17h14_36.png
作ったリソースにさらに子リソース[id]を追加し、「{}」で囲みます。idの番号で指定できるようにするためです。
2020-01-10_17h16_53.png
アクションのプルダウンから、次は[メソッドの作成]を選択します。
2020-01-10_17h25_17.png
プルダウンから[GET]を選択したら、横にチェックマークが出るのでクリック。
2020-01-10_17h27_46.png
セットアップ画面が出てくるので、先程作った Lambda 関数の名前を入力し紐付けます。
2020-01-10_17h30_01.png

2020-01-10_18h02_17.png
最後にアクションのプルダウンから[APIのデプロイ]を選択します。
2020-01-14_09h20_06.png
デプロイされるステージは[新しいステージ]を選択。[prod]を入力し[デプロイ]をクリックします。
2020-01-14_09h22_13.png
出来上がったAPIを確認するために、URLをコピーしておきます。
image.png

4.確認しよう

先程コピーしたURLの最後に、API で作ったリソースを指定します。
今回は「/users/{id}」でしたので、id のところは Dynamo で登録したidの番号を指定します。
(私が登録したのは1か2か3)
Dynamo で登録した「 id : 1 」の「 Jill 」を引き出せました!
image.png

所感

APIを形成するには、本来ならもっと細かく、インフラの構築から始めるようなものだと想像してましたが
データベースに登録して、Lambda でコードを書いて、API に紐付けただけで完了できました!
実に簡単で早い!これなら確かに、API やアプリの中身を構築することだけに集中して作業ができそうですね。
環境構築や障害対策のことを考えながら、アプリを運用するのはコストもかかるし、開発だけに集中するのはなかなか難しいところであると思います。
一日のリクエスト数、集中する時間が限られているものであれば、コスト面で最適だと思います。

公式リンク

AWS Lambda 開発者ガイド
参考にしたAWSの公式サミット動画

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #22 (顧客イネーブルメントサービス)

Amazon Web Services (AWS)のサービスで正式名称や略称はともかく、読み方がわからずに困ることがよくあるのでまとめてみました。

Amazon Web Services (AWS) - Cloud Computing Services
https://aws.amazon.com/

全サービスを並べたチートシートもあるよ!

Amazon Web Services (AWS)サービスの正式名称・略称・読み方チートシート - Qiita
https://qiita.com/kai_kou/items/cb29d261c8acc49fd22a

まとめルールについては下記を参考ください。

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita
https://qiita.com/kai_kou/items/a6795dbab7e707b0d1a6

間違いや、こんな呼び方あるよーなどありましたらコメントお願いします!

Customer Enablement Services - 顧客イネーブルメントサービス

AWS Managed Services

AWS Professional Services

AWS Support

AWS Training and Certification

AWS IQ

他のまとめ

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #2 (ストレージ) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #3 (データベース) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #4 (開発者用ツール) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #5 (セキュリティ、アイデンティティ、コンプライアンス) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #6 (暗号化と PKI) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #7 (機械学習) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #8 (マネジメントとガバナンス) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #9 (移行と転送) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #10 (モバイル) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #11 (ネットワーキングとコンテンツ配信) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #12 (メディアサービス) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #13 (エンドユーザーコンピューティング) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #14 (分析) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #15 (アプリケーション統合) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #16 (ビジネスアプリケーション) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #17 (サテライト) - Qiita

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #18 (ロボット工学) - Qiita

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amazon EKS のチュートリアルで Kubernetes を理解する #05 Container Insights

はじめに

本記事は、以下の内容の続きになります。

前回は、k8s自体の特長のひとつである 「セルフヒーリング(自己回復)」 の動作を確認しました。
今回は、運用を想定して、ログやメトリクスの管理について確認します。

Amazon EKS の場合、 CloudWatch Container Insights を利用して、コンテナのログやメトリクスを、CloudWatchに集約することができます。
CloudWatch Container Insights は、Amazon EKS 専用のサービスではなく、Amazon ECS 含め、AWSのコンテナ関連のサービスにおけるコンテナのログやメトリクスを管理するために利用されます。

以下に、CloudWatch Container Insights の説明が書かれています。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/ContainerInsights.html

CloudWatch Container Insights を使用して、コンテナ化されたアプリケーションとマイクロサービスのメトリクスとログを収集、集計、要約します。Container Insights は Amazon Elastic Container Service、Amazon Elastic Kubernetes Service、および Amazon EC2 の Kubernetes プラットフォームで利用できます。このメトリクスには、CPU、メモリ、ディスク、ネットワークなどのリソース使用率が含まれます。Container Insights では、問題の迅速な特定と解決に役立つ、コンテナの再起動失敗などの診断情報も提供されます。また、Container Insights が収集するメトリクスには CloudWatch アラームを設定できます。

Container Insights のセットアップ

ワーカーノードのIAMロールへのポリシー設定

最初に、k8sクラスタでワーカーノードとして動作しているECインスタンスに対して、「CloudWatchAgentServerPolicy」のポリシーを追加します。

amazon-eks-dev08.jpg

ワーカーノードとして動作しているECインスタンスのIAMロールの確認、および、ポリシーの設定の詳細は、以下のページを参照してください。

Container Insights の利用準備

Container Insights を利用するためには、以下のセットアップを行うことになります。

  • CloudWatchにメトリクスを送信するために、CloudWatchエージェントをDaemonSetとして登録する。
  • CloudWatchLogsにログを送信するために、FluentDをDaemonSetとして登録する。

これらを個別に登録することも可能なのですが、AWS Samplesのリポジトリに、両方をまとめて登録できるマニフェストがあるので、今回はそれを利用します。
クラスタ名({{cluster_name}})と、AWSリージョン名({{region_name}})を指定する必要があるので、以下のように、マニフェストファイルを一度ダウンロードして、内容の一部を置換します。

$ curl -o cwagent-fluentd-quickstart-template.yaml https://raw.githubusercontent.com/aws-samples/ama![amazon-eks-dev11_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22893/79471c33-0f0d-3385-ce45-19bf1317b3bf.jpeg)
zon-cloudwatch-container-insights/master/k8s-yaml-templates/quickstart/cwagent-fluentd-quickstart.yaml

$ sed "s/{{cluster_name}}/dev/;s/{{region_name}}/us-west-2/" cwagent-fluentd-quickstart-template.yaml > cwagent-fluentd-quickstart.yaml

その上で、CloudWatchエージェントとFluentDを、DaemonSetとして登録します。

$ kubectl apply -f cwagent-fluentd-quickstart.yaml
namespace/amazon-cloudwatch created
serviceaccount/cloudwatch-agent created
clusterrole.rbac.authorization.k8s.io/cloudwatch-agent-role created
clusterrolebinding.rbac.authorization.k8s.io/cloudwatch-agent-role-binding created
configmap/cwagentconfig created
daemonset.apps/cloudwatch-agent created
configmap/cluster-info created
serviceaccount/fluentd created
clusterrole.rbac.authorization.k8s.io/fluentd-role created
clusterrolebinding.rbac.authorization.k8s.io/fluentd-role-binding created
configmap/fluentd-config created
daemonset.apps/fluentd-cloudwatch created

Container Insights の動作確認

CloudWatchエージェントとFluentDが、DaemonSetとして登録されると、自動で、ログやメトリクスの収集が始まります。

amazon-eks-dev09.jpg

CloudWatchのログストリームを確認すると、ノードごとにログストリームが生成されていることが分かります。

amazon-eks-dev10_1.jpg

CloudWatchのメニューから 「ログ」 > 「インサイト」 をクリックし、クエリを実行すると、
ワーカーノードから収集されたログの内容を確認することができます。

amazon-eks-dev11_1.jpg

また、CloudWatchのトップ画面で、Container Insights の内容を確認すると、
メトリクスも収集されていることが分かります。

メトリクス

Amazon EKS で収集できるメトリクスは、以下のページから確認できます。

Node、もしくは、Pod 単位で、CPU使用率やメモリ使用量を取得できたりするようです。

まとめ

CloudWatchエージェントとFluentDを利用して、CloudWatchに、ログやメトリクス情報も集約できることが確認できました。
これによって、アラートなども簡単に設定することができるようになります。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WordPressで画像認証表示されずログインできなくなった件

昨日突然、WordPressのログインページで、画像認証が表示されずログインできなくなりました。
ネット検索したところ、SiteGuard WP Pluginが原因と分かりました。
https://dara-blog.com/siteguard-wp-plugin-no-image

SSHでSFTP接続して、
/public_html/wp/wp-content/plugins/
まで移動しました。
そして、siteguardをフォルダごと削除しました。
これで、ログインできるようになりました。

でも、また問題発生です。
プラグインの更新が、できないのです。

『インストールに失敗しました: ダウンロードに失敗しました。 ファイルストリーミングの送り先となるディレクトリが存在しないか、書き込み不可になっています。』
と言うエラーが出ました。

色々検索したところ、フォルダのパーミッションを変えると直ると知りました。
それで、下記の記事を参考にしました。
https://php-java.com/archives/622

https://agohack.com/aws-bitnami-wpsetting/

https://wordpressdeec.jp/howto/howto-004/

最終的に、wp-contentの中のuploadsのパーミッションを775にしたら、直りました。

AWSのEC2でWordPressをインストールする際、Bitnamiを使ったときは、ディレクトリの権限やパーミッションの設定を気をつけた方が良いです。

そのため、自分でEC2にWordPressをインストールする手順を踏んだ方が、後々楽なような気がしてきました。

何事も、最初が肝心です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Amplifyでリソース作成に失敗したときの対処法

amplify pushしようとしたらエラーが出た

該当issue

エラー内容

Following resources failed

Resource Name: UserPoolClientLambda (AWS::Lambda::Function)
Event Type: create
Reason: The runtime parameter of nodejs8.10 is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs12.x) while creating or updating functions.

バージョンをあげましょう

$ npm install -g @aws-amplify/cli
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む