- 投稿日:2020-01-17T23:36:43+09:00
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.js
、mutations.js
、subscriptions.js
が作られることで、CRUDが簡単に行えるようになります。基本設定
下記の例では、idをプライマリーキーとして、Postテーブルが作成されます。
type Post @model { id: ID! title: String! tags: [String!]! }PostデータのCRUDするために、
queries.js
にはgetPost
とlistPost
。mutations.js
にはcreatePost
とupdatePost
、deletePost
。subscriptions.js
にはonCreatePost
とonUpdatePost
、onDeletePost
がそれぞれ自動生成されます。具体的な使用方法については、別記事でまとめていますので、下記の記事をご確認ください。
AWS Amplify フレームワークの使い方Part4〜API実践編〜詳細設定
@model
のあとに、記述を追加することで自動生成されるCURDを制御することができます。
下記のように記述した場合は、mutations.js
とsubscriptions.js
内に自動生成なしでqueries.js
内にgetPost
のみが生成されます。type Post @model(queries: { get: "post" }, mutations: null, subscriptions: null) { id: ID! title: String! tags: [String!]! }おわりに
もう少し細かい事もできるようですが、現状試しているのはここまでになります。
@model
さえ使えれば、簡単なアプリはできてしまうので、一度は触ってもらうとわかりやすいと思います。参考
関連記事
AWS amplify フレームワークの使い方Part1〜Auth設定編〜
AWS Amplify フレームワークの使い方Part2〜Auth実践編〜
AWS Amplify フレームワークの使い方Part3〜API設定編〜
AWS Amplify フレームワークの使い方Part4〜API実践編〜
- 投稿日:2020-01-17T21:52:20+09:00
[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.pyfrom 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
を指定します。
ただし、timezone
もtimezone
サブクラスから生成する必要があるため、そこでちょっと戸惑いました。
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」
ということみたいです。
- 投稿日:2020-01-17T21:52:20+09:00
[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.pyfrom 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
を指定します。
ただし、timezone
もtimezone
サブクラスから生成する必要があるため、そこでちょっと戸惑いました。
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」
ということみたいです。
言葉だけだと少々理解しにくいですが、実際にプログラムを動かしてみて結果の差異を見ることで実感できました。
- 投稿日:2020-01-17T21:28:13+09:00
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"参考リンク
- 投稿日:2020-01-17T21:27:24+09:00
Cloud9でPackerを実行する
「Packer」とは、TerraformでおなじみのHashiCorp社が出しているマシンイメージの作成ツールで、AWS、Azure、GCPなどマルチクラウドに対応している点が売りです。
AWSですと最近「EC2 Image Builder」というサービスが出ましたが、これに近いでしょう。今回、Cloud9でPackerをインストール&実行して、AMIを作成してみました。
手順
1. Homebrewをインストール
以下リンク先の手順で一撃です。
「Cloud9にHomebrewをインストールする手順」
https://qiita.com/nasuvitz/items/5eec6ab9444cff8e94672. Packerをインストール
一撃です。
$ brew install packer3. 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が出来上がります。
出来上がったAMIを確認してみます。
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専用でも選択肢に入ります。参考文献
- 投稿日:2020-01-17T20:51:11+09:00
スナップショットからRDSインスタンスを作成する方法
はじめに
"出来合いのDB"のスナップショットからクローンとなるRDSインスタンスを作る機会があったので、その手順をまとめてみました。
スナップショットの選択
- AWSマネジメントコンソールのトップ画面から、[サービス]>[RDS]と進みます。
- RDSの画面の左側のパネルで、[スナップショット]を選択します。
- スナップショット画面が開いたら、所望のスナップショットにチェックを入れます。
- その後、スナップショット画面上部の[スナップショットのアクション]のリストをクリックして、[スナップショットの復元]を選択します。
スナップショットの復元
DBインスタンスの復元画面で、以下の事項を設定します。
設定が完了したら、画面最下部の[DBインスタンスの作成]ボタンをクリックして、スナップショットからRDSインスタンスを作成します。インスタンスの仕様
- DBエンジン
- ライセンスモデル
- ライセンス込み(ライセンス料はRDSの利用料に含まれている)
- BYOL(自分のライセンス使用)
- DBインスタンスのクラス
- db.t3.micro~db.t3.2xlargeなど、20種類程度の中から選びます。
- マルチAZ配置
- ストレージタイプ
- 汎用SSD/プロビジョンドIOPS/マグネティックの3種類から選びます。
設定
- DBインスタンス識別子
- RDSの画面では"DB インスタンス ID"の欄に表示されます。
ネットワーク&セキュリティ
- VPC
- サブネット
- パブリックアクセシビリティ
- デフォルトは「いいえ」。
- DBを外部に公開する場合は「はい」に設定します。(※参考にした記事はこちら)
- アベイラビリティ―ゾーン
- VPCセキュリティグループ
- デフォルトは[新規のVPCセキュリティグループを作成]となっているので、このRDSインスタンス用に新しいセキュリティグループが作られます。
- [既存のVPCセキュリティグループの選択]を選択すると、既存のセキュリティグループを選ぶことも可能です。
データベースの設定
- データベースの名前
- RDSの画面では"DB 名"の欄に表示されます。
- データベースのポート
- DBエンジンがOracleの場合、デフォルト値は1521となっています。
- DBパラメータグループ
- オプショングループ
バックアップ
- タグをスナップショットへコピー
暗号化
ログのエクスポート
- アラートログ/監査ログ/リスナーログ/トレースログの中から、CloudWatch Logsに発行するログを選択します。
- 上記の中から複数個選択可能です。
メンテナンス
- マイナーバージョン自動アップグレード
- リリースと同時にDBエンジンのバージョンアップを自動的に行う場合は「はい」に設定します。
まとめ
- スナップショットからの復元には数分~の時間を要するようです。
- 当たり前の話ですが、復元が完了するまではRDSインスタンスの設定を変更できません。
- DBを外部に公開する場合は、
パブリックアクセシビリティを有効化する
だけでなく、セキュリティグループ
にも気を付ける必要があります。
- セキュリティグループで、インバウンドの欄に
接続元となる信頼できるIP
が設定されていることを必ず確認すること。- スナップショットからの復元時に
新規のVPCセキュリティグループを作成
が選択されている場合、余計なセキュリティグループが出来てしまって、それを削除する手間がかかるかもしれません。- スナップショットからの復元は、新しいRDSインスタンスを作ることに等しいです。
- こちらの記事にも書かれているように、「スナップショットを使って、ある時点まで既存のDBをロールバックする」のではなく、「スナップショットを使って、ある時点のDBインスタンスを新たに作る」ということになります。
参考URL
- 投稿日:2020-01-17T18:50:25+09:00
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}"
- 投稿日:2020-01-17T17:02:23+09:00
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 sharedtmpElasticBeanstalkからECSを使う場合も、Dockerrun.aws.jsonに同じように書くだけです。
以上です。
- 投稿日:2020-01-17T16:58:57+09:00
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の理解が甘かったので復習する予定です。
- 投稿日:2020-01-17T16:51:01+09:00
CircleCIでbranchへのpushはテスト環境にデプロイする設定をしてみたがS3とCloudFrontの接続でちょっとミスした話
目的
前回、GitHubへpushしたリソースをCircleCIを使ってS3へデプロイする構成を作ってみました。
今回はよりリアルな製品開発をイメージしてテスト環境と本番環境が分かれていることを想定し、branchへのコミットをテスト環境、masterへのコミットを本番環境へデプロイするようにs3とCiecleCIの設定を行いました。その中でS3の設定でミスに気づきましたので、対処方法含め共有します。
構成図
利用サービスやアーキテクトは前回と同じです。テストと本番の2環境となります。
環境構築
CircleCIのyaml設定
前回の設定値に「テスト環境のbucket名」とmasterへpushしなかった場合の処理を記載しました。
本来であればbranchへのpushを明示すべきですが、elseで処理してます。config.ymlversion: 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}" fiS3バケット作成
AWS_S3_BUCKET_NAME_TEST: で命名したbucketを作成します。
S3バケットの作成には「既存のバケットから設定をコピー」というオプションがあるので、前回作成した本番用バケットから設定をコピーしましたが、後述の理由で再作成となりました。
作成後、バケットポリシーの設定をコピーします。最終的にはここがエラーの原因だと気づきました。
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
Route53レコードセット追加
接続できない
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の値を手動で変更すればアクセスできたと推察しております。所感
接続トラブルの際はパラメータは一つ一つ検証する必要があります。
- 投稿日:2020-01-17T14:59:34+09:00
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環境機能は使用しません)。
ソリューション(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 8000DockerCompose\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.ymlversion: '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.csusing 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
修正履歴
まだありません
- 投稿日:2020-01-17T13:27:47+09:00
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) } }以上になります。
このメトリクス化する仕組みを用いればいろんなものを可視化することができるので、監視や運用に役立つかと思います。
- 投稿日:2020-01-17T12:55:49+09:00
Nginx経由でRailsをAWS環境で起動できないエラー時にまず確かめたいこと、使えるコマンド。
表題の内容に関して、チェックすべきポイントを
備忘録として以下に記す。そもそもURLは正しいか?
Nginx導入の際に、unicorn.rb内の記述を変更していると思うので、
改めてブラウザからElastic IPでアクセスしてみる。データベースは起動しているか?
Mysql使用時は以下を実行して確認。
ターミナル[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>] $ sudo service mysqld start #上記実行後running...と表示されていればOKRailsは起動しているか?
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 unicornNginx内の記述を確認してみる。
確認するための記述は以下。
ターミナル[ec2-user@ip-XXX-XX-XX-XXX <リポジトリ名>]$ sudo vim /開きたいファイルのURIアプリケーション名や、Elastic IP、その他記述に誤りがないか確認する。
※vimの操作に関しては、以下にとても参考になる記事のリンクを載せました。
https://qiita.com/knife0125/items/5e91176c8401acd6bb0a現状の理解
ターミナルでの作業はなかなか理解が難しい。
特にvimを使用する場面は理解が浅いので今後学習を強化していきたい。誤り等ございましたらご指摘のほどよろしくお願いいたします。
- 投稿日:2020-01-17T10:27:04+09:00
これだけで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が決まっていたら制御できる。フルオープンなので、「全世界に開かれていますよーと警告が出る」
インスタンスを作成するとpendingになり、数分経つとrunnningになる。
オンプレミスだとサーバー構築に時間がかかるけど、数分でサーバーを構築できる。というのは理解できた。ECSインスタンス操作は、MacかWindowsかで操作方法が変わる。windowsはTeraTermを使うとのこと。Macのため割愛。
- 【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)を指定してアクセス。
接続ボタン押して、表示される 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を検索。
ルートアカウントの MFA を有効化→ MFAを有効化する。(省略)
google authenticatorを使って二段階認証。すごい(小並感)7.個々のIAMのユーザーの作成
プログラムによるアクセス
AMSマネジメントコンソールへのアクセス
共にチェック。個々の IAM ユーザーの作成
IAMで検索→ 個々の IAM ユーザーの作成 → ユーザーの管理 → admin(adminアクセスにアタッチ) → タグ(role admin) で設定
ユーザー別に作成
先程のadminをクリック → アクセス権限の追加 → 既存のポリシーを直接アタック → AdministratorAccess にチェック → IAMユーザーが完成
パスワードポリシー
パスワードを任意の制約で設定。特に追加はしなかった。
8. Day1 対応の実施③
ログの取得。S3を登録する、
9. Day1 対応の実施 ④
請求のアラート設定。
マイ請求ダッシュボードにいき、IAM ユーザー/ロールによる請求情報へのアクセス(オリアプの際は使わないと判断しスルーしました)
Costexplolerにいき起動後、アラートを受け取るをチェック、
ダッシュボードから CloudWatchを検索 → リージョンをバージニア北部に変更→ 左上の「請求」をクリック→ アラームを作成 → Currencyを JP に変更
新しいトピックの選択→ アラート名、アドレスの登録、アラートの選択。
作成ボタンを押し、リージョンを東京に戻す。
完了。
ここまで終えて
設定量が多かった。ユーザーごとに管理を分けるというのが新鮮だった。
セクション3 AWSの仕組み
・オンプレサーバーではなくクラウドなので、時間もコストも少なく運用可能。
・ブロックパーツのように自分の好きなパーツを組みあせて構成を実現する仕組み
・アンマネージド型とマネージド型がある
・リージョン→ 東京や香港やムンバイなど地理的に離れた領域。AWSのデータセンターがある大まかな場所のようなもの(日本には東京と大阪にある)
・アベイラビリティーゾーン(AZ)→ 各リージョンの中にあるデータセンターのようなもの→ リージョン内でAZは繋がっている。(低レイテンシー) 。AZは1つの複数の物理的なデータセンターで繋がっている。よって1つのAZ内のみでAWSを使っているとサービス停止とかでリスク高い。そのため、複数AZで分けるのが信頼性の高いシステム構成。・エッジロケーション → キャッシュデータを利用する際に更に小さなエンドポイントとなる拠点
・AWSの操作
1.AWSマネジメントコンソール 2.インスタンス操作 (SSH等) 3.AWS (CLI操作)アソシエイト試験概要
AWSの操作ができるかじゃなくて、アーキテクチャ設計ができるか?が結構重要とのこと。
細かい点は省略
AWSの全体像
範囲など説明のため省略
セクションIAM
13.IAMの概要
執筆中です
- 投稿日:2020-01-17T10:18:33+09:00
初心者が5分で出来る簡単サーバレスAPIを構築してみる【Lambda】
はじめに
今回は機械学習ではないのですが、自分がAWSの試験を受けるにあたり、IT初心者としてサーバレスについてイメージが難しいところがありました。
サーバーへの考慮がいらない、サーバーのメンテナンスや管理をしなくていいと言われていますが、実際使い勝手などが分かりにくい。少しでも理解できるようになるために、1杯のコーヒーよりもコストが低いAPIの作成を実践してみました!
AWSのサーバレスサービス
サーバレスとは言いますが、サーバが存在していないわけでは無いのです。
あくまでもAWS側がサポートしてくれて、サーバを意識せずに、アプリケーションを作成したり運用できるサービスのことを指しています。1. DynamoDB でテーブルを作る
データベースのidの番号から、名前を引っ張ってこれるような簡単なAPIを作っていきます。
まずは、データベースの DynamoDB にテーブルを作成していきます。
テーブル名を入力して[デフォルト設定の使用]にチェックマークをつけて作成をクリック。
数秒待つとテーブルが作成されます。出来上がったテーブルをクリックして、右の[項目]のタブから[項目の作成]をクリック。
「id string:」の VALUE の項目にまず1という番号を入力して、+ボタンをクリックし、[Append]を選択してさらに[String]を選択します。
FIELD という項目には[name]を入力し、 string の項目には適当な名前を入力します。
同じ手順で三人分名前を登録しました。
2. Lambda関数を作る
次は Lambda のコンソールへ行き、関数の作成に入ります。
[一から作成]を選択している状態でまずは関数名を入力。
ランタイムで関数の言語を選択します。今回使うのは[Node.js 10.x] 。
実行ロールの選択または作成を選択し、DynamoDB のアクセス権限をつけます。そして作成をクリック。
次に DynamoDB からidの番号で名前を引っ張ってくるシンプルなコードを書いていきます。
コードはこちら。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 のデフォルトのコードを削除して書き直します。右の[保存]をクリックして更新します。
3. API をデプロイする
API Gateway のコンソールへ行き、API の作成に入ります。
リソースの横にある、アクションのプルダウンから[リソースの作成]を選択。
リソース名を入力して[リソースの作成]をクリック。
作ったリソースにさらに子リソース[id]を追加し、「{}」で囲みます。idの番号で指定できるようにするためです。
アクションのプルダウンから、次は[メソッドの作成]を選択します。
プルダウンから[GET]を選択したら、横にチェックマークが出るのでクリック。
セットアップ画面が出てくるので、先程作った Lambda 関数の名前を入力し紐付けます。
最後にアクションのプルダウンから[APIのデプロイ]を選択します。
デプロイされるステージは[新しいステージ]を選択。[prod]を入力し[デプロイ]をクリックします。
出来上がったAPIを確認するために、URLをコピーしておきます。
4.確認しよう
先程コピーしたURLの最後に、API で作ったリソースを指定します。
今回は「/users/{id}」でしたので、id のところは Dynamo で登録したidの番号を指定します。
(私が登録したのは1か2か3)
Dynamo で登録した「 id : 1 」の「 Jill 」を引き出せました!
所感
APIを形成するには、本来ならもっと細かく、インフラの構築から始めるようなものだと想像してましたが
データベースに登録して、Lambda でコードを書いて、API に紐付けただけで完了できました!
実に簡単で早い!これなら確かに、API やアプリの中身を構築することだけに集中して作業ができそうですね。
環境構築や障害対策のことを考えながら、アプリを運用するのはコストもかかるし、開発だけに集中するのはなかなか難しいところであると思います。
一日のリクエスト数、集中する時間が限られているものであれば、コスト面で最適だと思います。公式リンク
- 投稿日:2020-01-17T10:00:15+09:00
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 Managed Services
- https://aws.amazon.com/jp/managed-services/?id=docs_gateway
- 読み方: マネージド サービス
- 略称: AMS
- 俗称: なし
AWS Professional Services
- 正式名称: AWS Professional Services
- https://aws.amazon.com/jp/professional-services/?id=docs_gateway
- 読み方: プロフェッショナル サービス
- 略称: なし
- 俗称: なし
AWS Support
- 正式名称: AWS Support
- https://aws.amazon.com/jp/premiumsupport/?id=docs_gateway
- 読み方: サポート
- 略称: なし
- 俗称: なし
AWS Training and Certification
- 正式名称: AWS Training and Certification
- https://aws.amazon.com/jp/training/?id=docs_gateway
- 読み方: トレーニング アンド サーティフィケーション
- 略称: なし
- 俗称: なし
AWS IQ
- 正式名称: AWS IQ
- https://docs.aws.amazon.com/aws-iq/?id=docs_gateway
- 読み方: アイキュー
- 略称: なし
- 俗称: なし
他のまとめ
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
- 投稿日:2020-01-17T08:40:53+09:00
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.htmlCloudWatch 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」のポリシーを追加します。
ワーカーノードとして動作している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 createdContainer Insights の動作確認
CloudWatchエージェントとFluentDが、DaemonSetとして登録されると、自動で、ログやメトリクスの収集が始まります。
CloudWatchのログストリームを確認すると、ノードごとにログストリームが生成されていることが分かります。
CloudWatchのメニューから 「ログ」 > 「インサイト」 をクリックし、クエリを実行すると、
ワーカーノードから収集されたログの内容を確認することができます。
また、CloudWatchのトップ画面で、Container Insights の内容を確認すると、
メトリクスも収集されていることが分かります。メトリクス
Amazon EKS で収集できるメトリクスは、以下のページから確認できます。
Node、もしくは、Pod 単位で、CPU使用率やメモリ使用量を取得できたりするようです。
まとめ
CloudWatchエージェントとFluentDを利用して、CloudWatchに、ログやメトリクス情報も集約できることが確認できました。
これによって、アラートなども簡単に設定することができるようになります。参考
- 投稿日:2020-01-17T02:13:06+09:00
WordPressで画像認証表示されずログインできなくなった件
昨日突然、WordPressのログインページで、画像認証が表示されずログインできなくなりました。
ネット検索したところ、SiteGuard WP Pluginが原因と分かりました。
https://dara-blog.com/siteguard-wp-plugin-no-imageSSHでSFTP接続して、
/public_html/wp/wp-content/plugins/
まで移動しました。
そして、siteguardをフォルダごと削除しました。
これで、ログインできるようになりました。でも、また問題発生です。
プラグインの更新が、できないのです。『インストールに失敗しました: ダウンロードに失敗しました。 ファイルストリーミングの送り先となるディレクトリが存在しないか、書き込み不可になっています。』
と言うエラーが出ました。色々検索したところ、フォルダのパーミッションを変えると直ると知りました。
それで、下記の記事を参考にしました。
https://php-java.com/archives/622https://agohack.com/aws-bitnami-wpsetting/
https://wordpressdeec.jp/howto/howto-004/
最終的に、wp-contentの中のuploadsのパーミッションを775にしたら、直りました。
AWSのEC2でWordPressをインストールする際、Bitnamiを使ったときは、ディレクトリの権限やパーミッションの設定を気をつけた方が良いです。
そのため、自分でEC2にWordPressをインストールする手順を踏んだ方が、後々楽なような気がしてきました。
何事も、最初が肝心です。
- 投稿日:2020-01-17T00:56:57+09:00
Amplifyでリソース作成に失敗したときの対処法
amplify pushしようとしたらエラーが出た
エラー内容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