- 投稿日:2019-07-16T23:43:26+09:00
AWS ELBでSSL化した際にLaravelのメール認証(EmailVerification)ができなくなった話
起きたこと
ELBでSSL化を行った際に、Laraveのメール認証が動かなくなってしまった。
エラーを探ってるとこんなメッセージが
This request has been blocked;. the content must be served over HTTPS.
結論
ここに記載してあるとおり
TLS/SSL証明を行うロードバランサの裏でアプリケーションが実行されている場合は別で対応が必要みたいです。Tip!! AWS Elastic Load Balancingを使用している場合、$headersの値は
Request::HEADER_X_FORWARDED_AWS_ELBに設定する必要があります。$headersで使用する
内容の詳細は、Symfonyのtrusting proxiesドキュメントを参照してください。
- 投稿日:2019-07-16T21:04:49+09:00
VScode�でAWS Cloud9の操作 | アクセスエラーの原因と対処法
概要
参考の手順に従いVSCodeにLive Sync for AWS Cloud9をセットアップした。
しかし、エラーが発生しCloud9にアクセスできない。
その対処方を備忘録として残す。
問題
Environmentsは表示されるが、Connectするとエラーが発生している。
エラー内容
User: arn:aws:iam::714834470136:user/local-vscode-t3500 is not authorized to perform: cloud9:CreateEnvironmentToken on resource: 5992e3f14a604d23a5146be72951fe99 with an explicit deny原因
原因は、Cloud9を作成したユーザと、VSCodeに登録した ユーザ異なる ためであった。
I believe what is happening is that another user has created the environment and that user has not shared the environment with the user you specified in VS Code. I believe the fix would be to log into the Cloud9 web interface and click the "Share" button and add the user that you're using in VS Code.
How to delete C9 Environment? · Issue #4 · iann0036/cloud9-sync
対策
Cloud9の設定から、VSCodeに登録した ユーザを招待 することで、Environmentへのアクセス権限を得ることができ、無事VSCodeからアクセスできた。
以上
- 投稿日:2019-07-16T17:37:56+09:00
s3cmd --help 日本語訳
業務で必要になったため、自分用に訳します。
s3cmdすら今更感がありますが、version 1.5.2準拠です(最新は2.0.2のよう)。
この内容で日本語訳を作っておきたいと思うレベルの英語力なので、なにか間違いがあればご指摘いただけると大変助かります。前文
s3cmdは、Amazon S3ストレージ内のオブジェクトを管理するためのツールです。 「バケット」の作成と削除、そしてこれらのバケットの「オブジェクト」のアップロード、ダウンロード、削除を可能にします。
オプション
-h, --help
ヘルプを表示します。
--configure
対話型(再)設定ツールを起動します。 オプションで
--configure s3://some-bucket
を使用すると特定のバケットへのアクセスをテストします。-c FILE, --config=FILE
設定をファイルから読み込みます。デフォルトのファイルパスは
$HOME/.s3cfg
です。--dump-config
設定ファイルとコマンドラインオプションを解析した後、現在の設定をダンプします。
--access_key=ACCESS_KEY
AWSのアクセスキーを指定します。
--secret_key=SECRET_KEY
AWSのシークレットキーを指定します。
-n, --dry-run
アップロードまたはダウンロードする必要があるものだけを表示し、実際には実行しません。 バケットリストやその他の情報を取得するためにS3リクエストを実行する可能性があります(ファイル転送コマンドのみ)。
-s, --ssl
S3との通信にHTTPS接続を利用します。
--no-ssl
HTTPSを利用しません。(※デフォルト)
-e, --encrypt
S3へのアップロード前にファイルを暗号化します。
--no-encrypt
ファイルを暗号化しません。
-f, --force
上書きやその他の危険な操作を強制実行します。
--continue
getコマンド使用時、部分的にダウンロードされたファイルの取得を続行します(の場合のみ)。
--continue-put
部分的にアップロードされたファイルまたはマルチパートアップロード内パートのアップロードを続行します。 サイズとmd5が一致しないファイル/パートを再起動し、スキップします。
注:MD5チェックサムは、ファイルの等価性を(部分的に)チェックするために必ずしも十分ではありません。 ご自身の責任でこれを有効にしてください。
--upload-id=UPLOAD_ID
--continue-putと同様に既存のアップロードを続けたい場合や、複数の部分的なアップロードがある場合は、マルチパートアップロードのUPLOAD_IDを設定します。
s3cmd multipart [URI]
を使用して`、指定されたURIにどのUPLOAD_IDが関連付けられているかを確認します。--skip-existing
getおよびsyncコマンド使用時、転送先に存在するファイルをスキップします。
-r, --recursive
再帰的アップロード、ダウンロード、削除を実行します。
--check-md5
syncコマンドでファイルを比較する際にMD5チェックサムを確認します。(※デフォルト)
--no-check-md5
syncコマンドでファイルを比較する際にMD5チェックサムを確認せず、ファイルサイズのみで比較します。転送速度が大幅に向上する可能性がありますが、変更されたファイルを見逃すこともあります。
-P, --acl-public
だれでも読み取り可能になるようにACLを付与してオブジェクトを保存します。
--acl-private
あなただけがアクセスを許可されているデフォルトのACLを付与してオブジェクトを保存します。
--acl-grant=PERMISSION:EMAIL or USER_CANONICAL_ID
指定のamazonユーザーに権限を与えます。パーミッションは
read, write, read_acp, write_acp, full_control, all
のいずれかです。--acl-revoke=PERMISSION:USER_CANONICAL_ID
指定のamazonユーザーに与えられた権限を取り消します。パーミッションは
read, write, read_acp, write_acp, full_control, all
のいずれかです。-D NUM, --restore-days=NUM
restoreコマンド使用時、復元されたファイルを利用可能に保つ日数を指定します。
--delete-removed
syncコマンド使用時、対応するローカルファイルがないリモートオブジェクトを削除します。
--no-delete-removed
リモートオブジェクトを削除しません。
--delete-after
syncコマンド使用時、新規アップロード後に削除を実行します。
--delay-updates
syncコマンド使用時、更新されたすべてのファイルを最後に配置します。
--max-delete=NUM
delおよびsyncコマンド使用時、指定の数値NUMを超える数のファイルを削除しません。
--add-destination=ADDITIONAL_DESTINATIONS
最後の引数に加えて、並列アップロード用の追加の転送先を指定します。 繰り返す可能性があります。
--delete-after-fetch
getおよびsyncコマンド使用時、ローカルファイルにフェッチした後にリモートオブジェクトを削除します。
-p, --preserve
ファイルシステムの属性(モード、所有権、タイムスタンプ)を保持します。 syncコマンドのデフォルトです。
--no-preserve
ファイルシステムの属性を保持しません。
--exclude=GLOB
GLOBに一致するファイル名とパスは同期から除外されます。
--exclude-from=FILE
--exclude
のGLOBをファイルから読み込みます。--rexclude=REGEXP
REGEXP(正規表現)に一致するファイル名とパスは同期から除外されます。
--rexclude-from=FILE
--rexclude
のREGEXPをファイルから読み込みます。--include=GLOB
以前に
--(r)exclude(-from)
パターンの1つによって除外されていたとしても、GLOBに一致するファイル名とパスが同期に含まれます。--include-from=FILE
--include
のGLOBをファイルから読み込みます。--rinclude=REGEXP
--include
と同じですが、GLOBの代わりにREGEXP(正規表現)を使用します。--rinclude-from=FILE
--rinclude
のREGEXPをファイルから読み込みます。--ignore-failed-copy
キーが見つからず失敗した場合でも、終了しません。
--files-from=FILE
FILEからソースファイル名のリストを読みます。 標準入力から読み込むには
-
を使用してください。--region=REGION, --bucket-location=REGION
バケットを作成するリージョンを指定します。
--reduced-redundancy, --rr
put、cp、mvコマンド使用時、'低冗長化' でオブジェクトを保存します。GBあたりの価格が下がります。
--no-reduced-redundancy, --no-rr
put、cp、mvコマンド使用時、'低冗長化' せずにオブジェクトを保存します。GBあたりの価格が高くなります。
--access-logging-target-prefix=LOG_TARGET_PREFIX
cfmodifyおよびaccesslogコマンド使用時、アクセスログのターゲットプレフィックス(S3 URI)を指定します。
--no-access-logging
cfmodifyおよびaccesslogコマンド使用時、アクセスログ出力を無効にします。
--default-mime-type=DEFAULT_MIME_TYPE
格納されているオブジェクトのデフォルトのMIMEタイプを指定します。 アプリケーションのデフォルトはbinary/octet-streamです。
-M, --guess-mime-type
拡張子またはMIME magicでファイルのMIMEタイプを推測します。
-default-mime-type
オプションで指定されているデフォルトのMIMEタイプにフォールバックします。--no-guess-mime-type
MIMEタイプを推測せず、代わりにデフォルトのタイプを使用します。
--no-mime-magic
MIMEタイプを推測するときに、mime magicを使用しません。
-m MIME/TYPE, --mime-type=MIME/TYPE
MIMEタイプを強制します。
--default-mime-type
と--guess-mime-type
の両方をオーバーライドします。--add-header=NAME:VALUE
アップロード要求に指定されたHTTPヘッダーを追加します。 複数回使用できます。 例えば、このオプションを使用して 'Expires'または 'Cache-Control'ヘッダー(あるいはその両方)を設定します。
--remove-header=NAME
modifyコマンド使用時、指定されたHTTPヘッダを削除します。 複数回使用できます。 たとえば、このオプションを使用して 'Expires 'または 'Cache-Control 'ヘッダー(あるいはその両方)を削除します。
--server-side-encryption
put、sync、cp、modifyコマンド使用時、オブジェクトを配置する際にサーバー側の暗号化を使用するように指定します。
--encoding=ENCODING
自動検出された端末とファイルシステムのエンコーディング(文字セット)をENCODINGで上書きします。
--add-encoding-exts=EXTENSIONs
S3へのアップロード時に、[css, js, html]などコンマ区切りの拡張子にエンコードを追加します。
--verbatim
コマンドラインで指定されているS3名を使用してください。 前処理やエンコードなどは行われません。注意して使用してください。
--disable-multipart
--multipart-chunk-size-mb
で指定されたファイルサイズより大きいファイルはマルチパートアップロードを無効にします。--multipart-chunk-size-mb=SIZE
マルチパートアップロードの各チャンクのサイズを指定します。 SIZEより大きいファイルはマルチスレッド - マルチパートとして自動的にアップロードされ、小さいファイルは従来の方法でアップロードされます。 SIZEはメガバイト単位で、デフォルトのチャンクサイズは15MB、最小許容チャンクサイズは5MB、最大は5GBです。
--list-md5
lsコマンド使用時、バケットリストにMD5チェックサムを含めます。
-H, --human-readable-sizes
判読可能な形式でサイズを表示します(例:1234→1kB)。
--ws-index=WEBSITE_INDEX
ws-createコマンド使用時、index-documentを指定します。
--ws-error=WEBSITE_ERROR
ws-createコマンド使用時、error-documentを指定します。
--expiry-date=EXPIRY_DATE
expireコマンド使用時、有効期限ルールがいつ有効になるかを示します。
--expiry-days=EXPIRY_DAYS
expireコマンド使用時、オブジェクトの作成から有効期限ルールが有効になるまでの日数を示します。
--expiry-prefix=EXPIRY_PREFIX
expireコマンド使用時、有効期限ルールが適用されるプレフィックスを使用して1つ以上のオブジェクトを識別します。
--progress
進行状況メーターを表示します(TTYのデフォルト)。
--no-progress
進行状況メーターを表示しません(TTYでない場合のデフォルト)。
--enable
cfmodifyコマンド使用時、特定のCloudFrontディストリビューションを有効にします。
--disable
cfmodifyコマンド使用時、特定のCloudFrontディストリビューションを無効にします。
--cf-invalidate
CloudFrontにアップロードされたファイルを無効にします。 [cfinval]コマンドも参照してください。
--cf-invalidate-default-index
Custom OriginおよびS3静的Webサイトを使用している場合は、デフォルトのインデックスファイルを無効にします。
--cf-no-invalidate-default-index-root
Custom OriginおよびS3静的Webサイトを使用している場合は、デフォルトのインデックスファイルへのパスを無効にしません。
--cf-add-cname=CNAME
cfcreateおよびcfmodifyコマンド使用時、指定されたCNAMEをCloudFrontディストリビューションに追加します。
--cf-remove-cname=CNAME
cfmodifyコマンド使用時、指定されたCNAMEをCloudFrontディストリビューションから削除します。
--cf-comment=COMMENT
cfcreateおよびcfmodifyコマンド使用時、CloudFrontディストリビューションにCOMMENTを設定します。
--cf-default-root-object=DEFAULT_ROOT_OBJECT
cfcreateおよびcfmodifyコマンド使用時、URLにオブジェクトが指定されていない場合に返されるデフォルトのルートオブジェクトを相対パスで設定します。
(例:/default/index.html または s3://bucket/default/index.html → default/index.html)
-v, --verbose
詳細出力を有効にします。
-d, --debug
デバッグ出力を有効にします。
--version
s3cmdのバージョンを表示します。
-F, --follow-symlinks
通常のファイルであるかのようにシンボリックリンクに対応します。
--cache-file=FILE
ローカルソースのMD5チェックサムを含むキャッシュファイルを指定します。
-q, --quiet
標準出力へ出力せずに実行します。
--ca-certs=CA_CERTS_FILE
システムデフォルトの代わりに使用するSSL CA証明書ファイルへのパスを指定します。
--check-certificate
SSL証明書の有効性を確認します。
--no-check-certificate
SSL証明書の有効性を確認しません。
--signature-v2
新しい署名方法の代わりにAWS Signatureバージョン2を使用します。 まだAWS Signature v4を搭載していないS3ライクなシステムに役立ちます。
コマンド
バケットを作成する
s3cmd mb s3://BUCKETバケットを削除する
s3cmd rb s3://BUCKETバケットまたはオブジェクトを一覧表示する
s3cmd ls [s3://BUCKET[/PREFIX]]すべてのバケットのすべてのオブジェクトを一覧表示する
s3cmd laバケットにファイルをアップロードする
s3cmd put FILE [FILE...] s3://BUCKET[/PREFIX]バケットからファイルをダウンロードする
s3cmd get s3://BUCKET/OBJECT LOCAL_FILEバケットからファイルを削除する
s3cmd del s3://BUCKET/OBJECT s3cmd rm s3://BUCKET/OBJECT # del のエイリアスアーカイブからファイルを復元する
s3cmd restore s3://BUCKET/OBJECTディレクトリツリーをS3と同期する
オプションで上書きされない限り、sizeとmd5チェックサムを使用してファイルの鮮度をチェックします。
s3cmd sync LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIRバケットの使用量を確認する
s3cmd du [s3://BUCKET[/PREFIX]]バケットやファイルに関する情報を取得する
s3cmd info s3://BUCKET[/OBJECT]バケット間でオブジェクトをコピーする
s3cmd cp s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]オブジェクトのメタデータを変更する
s3cmd modify s3://BUCKET1/OBJECTバケット間でオブジェクトを移動する
s3cmd mv s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]バケットやファイルのアクセスコントロールリスト (ACL)を変更する
s3cmd setacl s3://BUCKET[/OBJECT]バケットポリシーを変更する
s3cmd setpolicy FILE s3://BUCKETマルチパートアップロードを表示する
s3cmd multipart s3://BUCKET [Id]マルチパートアップロードを中止する
s3cmd abortmp s3://BUCKET/OBJECT Idマルチパートアップロードのパートを一覧表示する
s3cmd listmp s3://BUCKET/OBJECT Idバケットのアクセスログ出力を有効化または無効化する
s3cmd accesslog s3://BUCKET秘密鍵を使って任意の文字列に署名する
s3cmd sign STRING-TO-SIGN有効期限付きの限定公開アクセスを提供するためにS3 URLに署名する
s3cmd signurl s3://BUCKET/OBJECT <expiry_epoch|+expiry_offset>バケット内の無効なファイル名を修正する
s3cmd fixbucket s3://BUCKET[/PREFIX]バケットからウェブサイトを作成する
s3cmd ws-create s3://BUCKETウェブサイトを削除する
s3cmd ws-delete s3://BUCKETウェブサイトの情報を表示する
s3cmd ws-info s3://BUCKETバケットの有効期限ルールを設定または削除する
s3cmd expire s3://BUCKETバケットのライフサイクルポリシーを設定する
s3cmd setlifecycle s3://BUCKETバケットのライフサイクルポリシーを削除する
s3cmd dellifecycle s3://BUCKETCloudFrontディストリビューションを一覧表示する
s3cmd cflistCloudFrontディストリビューションのパラメータを表示する
s3cmd cfinfo [cf://DIST_ID]CloudFrontディストリビューションを作成する
s3cmd cfcreate s3://BUCKETCloudFrontディストリビューションを削除する
s3cmd cfdelete cf://DIST_IDCloudFrontディストリビューションのパラメータを変更する
s3cmd cfmodify cf://DIST_IDCloudFrontの無効リクエストのステータスを表示する
s3cmd cfinvalinfo cf://DIST_ID[/INVAL_ID]
- 投稿日:2019-07-16T17:06:29+09:00
httpsのリダイレクト(S3+CloudFront+Route53)
概要と注意
wwEBサイトの引越しの時などに、Route53+S3でS3の静的Webサイトホスティング機能を使うと便利。
しかし、httpsをリダイレクトしたい場合、S3単体ではSSL証明書を扱うことができないため、CloudFront経由で行う。S3 Static Website hostingで全てのリクエストをリダイレクトするように設定する。
↓
AWS Certificate Managerで証明書を作る。
↓
CloudFrontのDistributionを作りOriginにS3 Static Website hostingのエンドポイントと証明書を設定する。
↓
Route53にS3が向くようにAレコードをを追加する。※バージニア北部で作成してください!!!CloudFront に SSL Certificate が東京リージョンを指定できないため。
1.ドメインを登録し、Route53のNSレコードを登録する
AWS Certificate Manager - ELB(+ACM発行証明書)→EC2の1-3を参考に設定する。
2.ACM から SSL/TLS 証明書を取得する
AWS Certificate Manager - ELB(+ACM発行証明書)→EC2の4を参考に証明書を取得する。
3.S3 バケットを作成し、リクエストを別のドメイン名にリダイレクトするようにバケットを設定する
「エンドポイント」は後で使います。
「リクエストをダイレクトする」にし、*リクエストをリダイレクトする先のドメイン (oldexample.com) * の名前を入力します。
プロトコルは「https」のみにします。
4.CloudFront ディストリビューションを作成または更新する
Origin Domain Name:「3.S3 バケットを作成し、リクエストを別のドメイン名にリダイレクトするようにバケットを設定する」のStatic Website hostingのエンドポイントを入力
Viewer Protocol Policy:HTTP and HTTPS
Alternate Domain Names(CNAMEs):ユーザーがコンテンツにアクセスするために使用するリダイレクト元(newexample.com)を入力する。
SSL Certificate:Custom SSL Certificate にし、「#2.ACM から SSL/TLS 証明書を取得する」で取得したACMを選択。
5.CloudFront ディストリビューションにトラフィックをルーティングする Route 53 レコードを作成する
タイプ: A - IPv4 address
エイリアス:はい
エイリアス先: CloudFront ディストリビューション
ルーティングポリシー:シンプル
CloudFrontのStatusがDeployedになるまで30分ほどかかるため、エイリアス先に表示されるのに時間がかかります。
ほかに表示がされない場合は、Route 53 エイリアスリソースレコードセットを作成する際に目的のエイリアス先が選択できないのはなぜですか?
を参照しましょう。6.テストする
どちらの場合も、DNS クエリをリダイレクトする先のドメインのコンテンツが表示されるか確認しましょう。
- 投稿日:2019-07-16T15:30:46+09:00
新入社員とはじめるAWS ~Lambdaをつかってサーバーを自動で起動・停止させてみよう編~
自己紹介
はじめまして。
4月にとあるSIerに新卒入社した、たからといいます。もともと勉強していたのはWebの分野で、開発か新しめの技術に触れられる部署を希望していたのですが残念ながら叶わず!
しかし色々あってAWSを勉強させてもらってます!興味はあったのですが、何から手を付けていいかわからなかったところ、勉強する機会がもらえて非常にありがたいです。
そこで自分が実際に触って動かした内容をまとめていこうと思います!こんな人向け
・AWS興味あるけど触ったことないよ
大丈夫です!こちらの記事などを参考にサーバーを立てるとこまでやってみて下さい!
接続とかApacheのインストールはしなくても大丈夫です!・AWSはサーバー起動くらいしかやったことないよ
・EC2以外もちょっと触ってみたいよ
っていうぐらいの層の人向けに書いてます!
やりたいこと
・EC2で立てたサーバーを、決めた時間に自動で停止したり起動させたい
・土日など、サーバー使わないよ!っていう日だけ自動で停止させて、月曜の朝に自動で起動させて少しでも節約させます。AWSは従量課金制なので。。登場人物
AWS Lambda
・「らむだ」と読みます。
・他のAWSと連携したりして、サーバーを立てずに特定の関数(メソッド)だけ実行できます。
使用例:
・サーバーのログやエラーなどをSlackに通知させる
・S3(AWSのクラウドストレージサービス)に送られた画像ファイルを自動でリサイズする
といった風に、各サービス間を連携させる関数を作れます。・今回はこいつを使って、決まった時刻にサーバを起動&停止させる関数を作ります。
IAMロール
・各AWSサービスを利用するための権限設定ができます。
・「あいあむ」と読みます。「I am」とかかってるんですかね!おぼえやすい!
・構築された環境を、初心者がワンクリックで崩壊させるのを防いでくれるような設定ができたりします。
・作成したIAMロールに、いろいろな権限を持たせる形で運用します。こちらの記事が理解しやすかったです!
AWS アカウント、IAM ユーザー、IAM グループ、IAM ロールの違い・Lambdaで作った関数を実行するのにもIAMロールが必要になるため、こちらも作成します。
CloudWatch Events
・AWSの各種リソースに対しトリガを設定すれば、何かを実行してくれるよ
・今回は、
決まった時刻に、事前に作っておいたLambdaの関数を起動中のサーバに対して発動させる
というふうに使います。・こちらを参考に
Amazon CloudWatch Eventsについてやってみよう
IAMロールの作成
まずはLambdaの実行に必要な権限設定(IAMロールの作成)から始めていきます。
AWSマネジメントコンソールから、「IAM」と検索して出てきたやつに飛びましょう!
開いたページの中の、【ロールの作成】という項目をクリック。
次のページの「このロールを使用するサービスを選択」から【Lambda】を選択し、次のステップへ進みます。次に、ロールに付与するアクセス権限ポリシーを選択する画面に飛びます。
用意されている中から選ぶこともできるのですが、ここでは自分でポリシーを作成します!
【ポリシーの作成】をクリックします。
ポリシー作成画面で、【JSON】タブを開いたあと、以下のコードをコピペしましょう!{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:Start*", "ec2:Stop*" ], "Resource": "*" } ] }「lambda_start_stop_ec2」という名前をつけて、ポリシーの作成を完了します。
前の画面に戻り、作成したポリシーをロールにアタッチして次に進みます!
次は「タグの追加」という画面に進みますが、こちらは特になにもせず次に進みます。
確認画面にてロール名を入力します。
ここも「lambda_start_stop_ec2」としてあげて、作成ボタンを押しましょう!
これでロールの完成です!Lambda関数の作成
次はいよいよ、インスタンスへ自動停止・自動起動の命令を送る関数を作っていきます!
まずは停止の方から!Stop関数の作成
コンソールからLambdaを開き、【関数の作成】をクリックします。
最初のオプションではデフォルトの【一から作成】を選択します。
その後は以下のスクショに従って入力してください。①関数名:StopEC2Instances
②ランタイム:Python2.7
③実行ロール:既存のロールを使用する
④既存のロール:先の手順で作った「lambda_start_stop_ec2」を使用入力が終わったら、【関数の作成】をクリックし、次に進みます。
作成した関数の設定画面に進むので、下の方にある「関数コード」の画面にインスタンスを停止させるコードを記述していきます。
こちらには初期状態で「Hello from Lambda!」を表示する関数が書かれていますが、こちらをすべて削除して、以下のコードをコピペします。import boto3 # Enter the region your instances are in, e.g. 'us-east-1' region = 'XX-XXXXX-X' # Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX'] instances = ['X-XXXXXXXX'] def lambda_handler(event, context): ec2 = boto3.client('ec2', region_name=region) ec2.stop_instances(InstanceIds=instances) print 'stopped your instances: ' + str(instances)こちらがインスタンスを停止させるコードです。
このコード内のリージョンとインスタンスIDの部分を変更して、自分のインスタンスが対象になるように設定していきます。
リージョンについては、AWS画面右上に
このように表示されているリージョンを確認したあと、こちらのリンクからリージョンコードを確認し、書き換えてください!
例 オハイオ:'us-east-2'次にインスタンスIDですが、関数の対象にしたいインスタンスのIDを、EC2のコンソールから確認しましょう!
ダッシュボードから「インスタンス」を選択し、表示されたインスタンスIDをもとに、Lambdaのコードを書き換えてあげましょう!タイムアウトまでの実行時間を変更する
デフォルトだと関数の実行時間が3秒になっていますが、実際はもっとかかるためこのままだと実行中にタイムアウトになってしまいます。
そのため、同じ画面の下の方にある【基本設定】の項目から、タイムアウトの時間を30秒に変更します。
これらの設定が終わったら、右上の「保存」ボタンを押して完了です!
これでインスタンスを停止させる関数ができました!
Start関数の作成
基本的にはStopの関数を作るときと同じです。
Lambdaのコンソールから「関数の作成」を押して再度進めましょう。
関数名を「StartEC2Instances」にし、同じように進めていきいます。
起動のコードはこちらになります。import boto3 # Enter the region your instances are in, e.g. 'us-east-1' region = 'XX-XXXXX-X' # Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX'] instances = ['X-XXXXXXXX'] def lambda_handler(event, context): ec2 = boto3.client('ec2', region_name=region) ec2.start_instances(InstanceIds=instances) print 'started your instances: ' + str(instances)こちらも自分のリージョンとインスタンスIDを入力します。
その後、タイムアウトの設定もさきほど同様に変更し、保存ボタンを押して完成です。これで自動停止・自動起動させるための関数ができました!
CloudWatch Eventsの設定
上の作業で作成した関数を、CloudWatch Eventsという機能を使って、決められた時刻に起動してもらうように設定していきます!
まずはインスタンス停止の関数(StopEC2Instances)からセットしていきましょう。
AWSのコンソールよりCloudWatchを開き、左側のメニューから「ルール」を選択。
出てきた画面より【ルールの作成】をクリックします。Cron式の設定
③のCron式でイベントを起動する時間を指定します!
一見むずかしそうに見えますが、全然そんなことないです!0/5 * * * ? *この式は左から、
・分 ・時間 ・日 ・月 ・曜日 ・年Amazonのガイドを参考に設定してみて下さい!
参考までに、式を2つ載せておきます。
#毎週金曜の20時 00 11 ? * FRI * #毎週月曜の朝8時 0 23 ? * MON *以下の注意点を読みつつ、好みの時間になるよういじってみて下さい!
・注意点その1 タイムゾーンの違い
上の式では、金曜の20時にとなっているにも関わらず、式の時間の項目(左から2つ目)は11時になっています。
これはAWSで使われているタイムゾーンがUTC(日本はJST)であることから生じるズレです。
以下のサイトで希望の時間を変換して使いましょう。
時差計算・注意点その2 Cron式上のはてなマーク
cron 式の日フィールドと曜日フィールドを同時に指定することはできません。
一方のフィールドに値 (または *) を指定する場合、もう一方のフィールドで ? (疑問符) を使用する必要があります。のようです。
つまり、#毎週金曜の20時 00 11 * * FRI *曜日フィールドに値がある(右から2つ目)のに、日フィールド(左から3つ目)が*になっているため、この式はアウトです。
なので、00 11 ? * FRI *このように日フィールドにハテナを入れてあげれば大丈夫です!
Cron式の設定が終わったら、ターゲットの追加で先程作ったLambda関数を指定して次に進みましょう!あと少しです!
次の画面でルールの名前を入力し(ここではStopEC2Instances)、状態が有効になっていることを確かめて、右下の作成ボタンを押せば完成です!
同じ要領で、自動起動のルールも設定してあげましょう!
動作確認
こちらの関数が実際に動くかどうかを確かめます。
先程作ったイベントのルール内のCron式を、現在時刻の5分後などに設定し、EC2のコンソールからちゃんと停止するか試してみましょう!指定時刻を過ぎたら更新ボタンを押して、インスタンスの状態がrunning→stoppedになっていれば成功です!
動作状況は、CloudWatchコンソールのログ→ロググループ→ログストリームから確認できます!
自動起動の方も動作確認ができれば、あとは好みの時間に設定し直すだけで完成です!
おつかれさまでした!!注意点
起動したインスタンスは、使わなければ停止しておきましょう。
私は起動しっぱにしてたら、いつのまにか無料期間超えたようで5ドルの請求が発生しましたw・参考にした記事
LambdaとCloudWatch EventsでEC2の自動起動&自動停止をやってみた(Python版)
- 投稿日:2019-07-16T15:30:46+09:00
新入社員とはじめるAWS Lambda
自己紹介
はじめまして。
4月にとあるSIerに新卒入社した、たからといいます。もともと勉強していたのはWebの分野で、開発か新しめの技術に触れられる部署を希望していたのですが残念ながら叶わず!
しかし色々あってAWSを勉強させてもらってます!興味はあったのですが、何から手を付けていいかわからなかったところ、勉強する機会がもらえて非常にありがたいです。
そこで自分が実際に触って動かした内容をまとめていこうと思います!こんな人向け
・AWS興味あるけど触ったことないよ
大丈夫です!こちらの記事などを参考にサーバーを立てるとこまでやってみて下さい!
接続とかApacheのインストールはしなくても大丈夫です!・AWSはサーバー起動くらいしかやったことないよ
・EC2以外もちょっと触ってみたいよ
っていうぐらいの層の人向けに書いてます!
やりたいこと
・EC2で立てたサーバーを、決めた時間に自動で停止したり起動させたい
・土日など、サーバー使わないよ!っていう日だけ自動で停止させて、月曜の朝に自動で起動させて少しでも節約させます。AWSは従量課金制なので。。登場人物
AWS Lambda
・「らむだ」と読みます。
・他のAWSと連携したりして、サーバーを立てずに特定の関数(メソッド)だけ実行できます。
使用例:
・サーバーのログやエラーなどをSlackに通知させる
・S3(AWSのクラウドストレージサービス)に送られた画像ファイルを自動でリサイズする
といった風に、各サービス間を連携させる関数を作れます。・今回はこいつを使って、決まった時刻にサーバを起動&停止させる関数を作ります。
IAMロール
・各AWSサービスを利用するための権限設定ができます。
・「あいあむ」と読みます。「I am」とかかってるんですかね!おぼえやすい!
・構築された環境を、初心者がワンクリックで崩壊させるのを防いでくれるような設定ができたりします。
・作成したIAMロールに、いろいろな権限を持たせる形で運用します。こちらの記事が理解しやすかったです!
AWS アカウント、IAM ユーザー、IAM グループ、IAM ロールの違い・Lambdaで作った関数を実行するのにもIAMロールが必要になるため、こちらも作成します。
CloudWatch Events
・AWSの各種リソースに対しトリガを設定すれば、何かを実行してくれるよ
・今回は、
決まった時刻に、事前に作っておいたLambdaの関数を起動中のサーバに対して発動させる
というふうに使います。・こちらを参考に
Amazon CloudWatch Eventsについてやってみよう
IAMロールの作成
まずはLambdaの実行に必要な権限設定(IAMロールの作成)から始めていきます。
AWSマネジメントコンソールから、「IAM」と検索して出てきたやつに飛びましょう!
開いたページの中の、【ロールの作成】という項目をクリック。
次のページの「このロールを使用するサービスを選択」から【Lambda】を選択し、次のステップへ進みます。次に、ロールに付与するアクセス権限ポリシーを選択する画面に飛びます。
用意されている中から選ぶこともできるのですが、ここでは自分でポリシーを作成します!
【ポリシーの作成】をクリックします。
ポリシー作成画面で、【JSON】タブを開いたあと、以下のコードをコピペしましょう!{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "ec2:Start*", "ec2:Stop*" ], "Resource": "*" } ] }「lambda_start_stop_ec2」という名前をつけて、ポリシーの作成を完了します。
前の画面に戻り、作成したポリシーをロールにアタッチして次に進みます!
次は「タグの追加」という画面に進みますが、こちらは特になにもせず次に進みます。
確認画面にてロール名を入力します。
ここも「lambda_start_stop_ec2」としてあげて、作成ボタンを押しましょう!
これでロールの完成です!Lambda関数の作成
次はいよいよ、インスタンスへ自動停止・自動起動の命令を送る関数を作っていきます!
まずは停止の方から!Stop関数の作成
コンソールからLambdaを開き、【関数の作成】をクリックします。
最初のオプションではデフォルトの【一から作成】を選択します。
その後は以下のスクショに従って入力してください。①関数名:StopEC2Instances
②ランタイム:Python2.7
③実行ロール:既存のロールを使用する
④既存のロール:先の手順で作った「lambda_start_stop_ec2」を使用入力が終わったら、【関数の作成】をクリックし、次に進みます。
作成した関数の設定画面に進むので、下の方にある「関数コード」の画面にインスタンスを停止させるコードを記述していきます。
こちらには初期状態で「Hello from Lambda!」を表示する関数が書かれていますが、こちらをすべて削除して、以下のコードをコピペします。import boto3 # Enter the region your instances are in, e.g. 'us-east-1' region = 'XX-XXXXX-X' # Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX'] instances = ['X-XXXXXXXX'] def lambda_handler(event, context): ec2 = boto3.client('ec2', region_name=region) ec2.stop_instances(InstanceIds=instances) print 'stopped your instances: ' + str(instances)こちらがインスタンスを停止させるコードです。
このコード内のリージョンとインスタンスIDの部分を変更して、自分のインスタンスが対象になるように設定していきます。
リージョンについては、AWS画面右上に
このように表示されているリージョンを確認したあと、こちらのリンクからリージョンコードを確認し、書き換えてください!
例 オハイオ:'us-east-2'次にインスタンスIDですが、関数の対象にしたいインスタンスのIDを、EC2のコンソールから確認しましょう!
ダッシュボードから「インスタンス」を選択し、表示されたインスタンスIDをもとに、Lambdaのコードを書き換えてあげましょう!タイムアウトまでの実行時間を変更する
デフォルトだと関数の実行時間が3秒になっていますが、実際はもっとかかるためこのままだと実行中にタイムアウトになってしまいます。
そのため、同じ画面の下の方にある【基本設定】の項目から、タイムアウトの時間を30秒に変更します。
これらの設定が終わったら、右上の「保存」ボタンを押して完了です!
これでインスタンスを停止させる関数ができました!
Start関数の作成
基本的にはStopの関数を作るときと同じです。
Lambdaのコンソールから「関数の作成」を押して再度進めましょう。
関数名を「StartEC2Instances」にし、同じように進めていきいます。
起動のコードはこちらになります。import boto3 # Enter the region your instances are in, e.g. 'us-east-1' region = 'XX-XXXXX-X' # Enter your instances here: ex. ['X-XXXXXXXX', 'X-XXXXXXXX'] instances = ['X-XXXXXXXX'] def lambda_handler(event, context): ec2 = boto3.client('ec2', region_name=region) ec2.start_instances(InstanceIds=instances) print 'started your instances: ' + str(instances)こちらも自分のリージョンとインスタンスIDを入力します。
その後、タイムアウトの設定もさきほど同様に変更し、保存ボタンを押して完成です。これで自動停止・自動起動させるための関数ができました!
CloudWatch Eventsの設定
上の作業で作成した関数を、CloudWatch Eventsという機能を使って、決められた時刻に起動してもらうように設定していきます!
まずはインスタンス停止の関数(StopEC2Instances)からセットしていきましょう。
AWSのコンソールよりCloudWatchを開き、左側のメニューから「ルール」を選択。
出てきた画面より【ルールの作成】をクリックします。Cron式の設定
③のCron式でイベントを起動する時間を指定します!
一見むずかしそうに見えますが、全然そんなことないです!0/5 * * * ? *この式は左から、
・分 ・時間 ・日 ・月 ・曜日 ・年Amazonのガイドを参考に設定してみて下さい!
参考までに、式を2つ載せておきます。
#毎週金曜の20時 00 11 ? * FRI * #毎週月曜の朝8時 0 23 ? * MON *以下の注意点を読みつつ、好みの時間になるよういじってみて下さい!
・注意点その1 タイムゾーンの違い
上の式では、金曜の20時にとなっているにも関わらず、式の時間の項目(左から2つ目)は11時になっています。
これはAWSで使われているタイムゾーンがUTC(日本はJST)であることから生じるズレです。
以下のサイトで希望の時間を変換して使いましょう。
時差計算・注意点その2 Cron式上のはてなマーク
cron 式の日フィールドと曜日フィールドを同時に指定することはできません。
一方のフィールドに値 (または *) を指定する場合、もう一方のフィールドで ? (疑問符) を使用する必要があります。のようです。
つまり、#毎週金曜の20時 00 11 * * FRI *曜日フィールドに値がある(右から2つ目)のに、日フィールド(左から3つ目)が*になっているため、この式はアウトです。
なので、00 11 ? * FRI *このように日フィールドにハテナを入れてあげれば大丈夫です!
Cron式の設定が終わったら、ターゲットの追加で先程作ったLambda関数を指定して次に進みましょう!あと少しです!
次の画面でルールの名前を入力し(ここではStopEC2Instances)、状態が有効になっていることを確かめて、右下の作成ボタンを押せば完成です!
同じ要領で、自動起動のルールも設定してあげましょう!
動作確認
こちらの関数が実際に動くかどうかを確かめます。
先程作ったイベントのルール内のCron式を、現在時刻の5分後などに設定し、EC2のコンソールからちゃんと停止するか試してみましょう!指定時刻を過ぎたら更新ボタンを押して、インスタンスの状態がrunning→stoppedになっていれば成功です!
動作状況は、CloudWatchコンソールのログ→ロググループ→ログストリームから確認できます!
自動起動の方も動作確認ができれば、あとは好みの時間に設定し直すだけで完成です!
おつかれさまでした!!注意点
起動したインスタンスは、使わなければ停止しておきましょう。
私は起動しっぱにしてたら、いつのまにか無料期間超えたようで5ドルの請求が発生しましたw・参考にした記事
LambdaとCloudWatch EventsでEC2の自動起動&自動停止をやってみた(Python版)
- 投稿日:2019-07-16T14:51:06+09:00
EC2インスタンスへのログイン方法
EC2インスタンスへのログインの手順
ホームディレクトリに移動する。
$ cd ~ホームディレクトリから隠しファイルである「.ssh」というディレクトリ(ファイル名)
$ ls -ahttps://gyazo.com/a3b158acc0ade19fe9db319a24ba3b39
ホームディレクトリから.sshにcdコマンド(絶対パス?)で移動する。
$ cd ~/.ssh.sshから、以下のコマンドを実行して、EC2インスタンスへのログインする。
$ ssh -i pemキー名 ec2-user@ 自身のIPアドレス「pemキー名」は、AWSの鍵の名前を指す。
「自身のIPアドレス」は、インスタンス作成時に作成される数字
ログインが完了すると、以下のような画面になる。
https://gyazo.com/d8358a055227c0859543a3e47b016775※隠しファイルのリストを見たい時は、-aで一覧表示できる。
$ ls -aまた、Finderにおいて、隠しファイルの一覧を表示させるには、
シフトキー + command + .のコマンドを実行すると、以下のような挙動となる。
https://gyazo.com/045020868a0f15b3e5fab25f5482588e
- 投稿日:2019-07-16T14:11:06+09:00
[AWS]VSCodeでSAMのHelloWorldを5分で行う
AWS Toolkit for Visual Studio Code の正式版がリリースされたということで、早速HelloWorldしてみました。
今回はPythonを使います。node.jsもほぼ同じでできます。
0. 環境準備
VSCode
肝心のVSCode以下からインストールします。
https://code.visualstudio.com/Docker
DockerはLambdaローカル実行時に使用するので必須です。
インストールしてない方はここからインストールします。
https://hub.docker.comPython
awscliをインストールする際に使います。
インストールされてない場合は、インストールしてください。$ python --version Python 3.7.0 $ pip --version pip 19.1.1AWS Cli
以下コマンドでawsとsamをインストールしましょう。
$ pip install awscli $ pip aws-sam-cliインストール済みの場合は、awscliのバージョンを上げておきましょう。
$ pip install -U aws-sam-cliaws configureでaws のアクセスキーとシークレットキーを設定しましょう。
$ aws configure
AWS Toolkit for Visual Studio Code
VSCodeの拡張機能で「AWS Toolkit」と検索して、インストールします。
1. HelloWorldローカル実行
1-1. テンプレ作成
コマンドパレット(Macなら、Shift + ⌘ + P) を開き、
「aws create new Sam Application」を選択します。以下の順に聞かれるので入力します。
- 開発する言語(今回はPython3.7を選びました)
- ディレクトリ(今回はtest)
- プロジェクト名(今回はhello)
test/helloが作られていればOKです。
1-2. ローカル実行
hello_world/app.pyを開きます。
以下の上に 「Run Locally | Debug Locally | Configure」と表示されているので、
「Run Locally」をクリックしていきなり実行します。def lambda_handler(event, context):{"statusCode":200,"body":"{\"message\": \"hello world\"}"} Local invoke of SAM Application has ended.こんな感じで出力されればOKです(最初はコンテナが起動するので時間がかかります)。
これでローカルでLambdaが実行できました。2. デプロイ
- デプロイ用のS3バケットを作成($ aws s3 mb s3://BUCKET_NAME)
- コマンドパレットを開いて、「aws Deploy SAM Application」を選択
- デプロイするテンプレートの選択。今回は「hello/template.yaml」を選択
- リージョンの選択。今回は「Asia Pacific (Tokyo)」を選択
- 1で作成したS3バケット名を指定
- cloudformationのstack名を入力(プロジェクト名をいれておけばまずOK)
Successfully deployed SAM Application to CloudFormation Stack: hello with profile: ****上記出力されれば無事にデプロイされました。
VSCodeの左メニューのAWSアイコンを選択すると、
CloudFormationおよびLambdaの所に、デプロイしたhelloが表示されていると思います。AWSコンソール「API GateWay」>「hello」>「ステージ」>「Prod」>「URL の呼び出し」
のURLに/helloをつけてブラウザ等でアクセスすると「hello_word」のメッセージが表示されます。URLは以下の感じ。
https://*********.execute-api.ap-northeast-1.amazonaws.com/Prod/helloこれで、Lambdaのデプロイができました(APIが作れました)。
削除する際は、VSCodeからCloudFormationのhelloを選択して、「Delete CloudFormation Stack」をしてください。
これで関連するサービスがすべて消えます。番外編
AWS Toolkit for Visual Studio Code がなかった頃はコマンドでやってましたので、コマンドでもやってみます。
1. HelloWorldローカル実行
0.環境準備 は済んでいるものとします。
1-1. テンプレ作成
$ cd test $ sam init -r python3.7 -n hellotestディレクトリにhelloプロジェクトをPython3.7で作成します。
以下の通り、作成されます。
$ cd hello $ tree . |-- README.md |-- event.json |-- hello_world | |-- __init__.py | |-- __pycache__ | | |-- __init__.cpython-37.pyc | | `-- app.cpython-37.pyc | |-- app.py | `-- requirements.txt |-- template.yaml `-- tests `-- unit |-- __init__.py |-- __pycache__ | |-- __init__.cpython-37.pyc | `-- test_handler.cpython-37.pyc `-- test_handler.py1-2. ローカル実行
以下のコマンドで実行します。
hello worldが出力されればOK$ cd hello $ sam local invoke -e event.json 〜(略)〜 {"statusCode": 200, "body": "{\"message\": \"hello world\"}"}2. デプロイ
デプロイ用のS3バケットを作ります。作ってあればOKです
$ aws s3 mb s3://BUCKET_NAME
以下コマンドでパッケージ化したものをS3に設置
$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket BUCKET_NAME $ sam deploy --template-file packaged.yaml --stack-name hello --capabilities CAPABILITY_IAM Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - helloAWSコンソールから,CloudFormation, Lambda, APIGateWay を確認してみてください。
作成されているはずです。削除する際は、CloudFormationから削除すれば関連するサービスまとめて削除してくれます。
- 投稿日:2019-07-16T14:11:06+09:00
[AWS]VSCodeでSAM(Lambda)のHelloWorldを5分で行う
AWS Toolkit for Visual Studio Code の正式版がリリースされたということで、早速HelloWorldしてみました。
今回はPythonを使います。node.jsもほぼ同じでできます。
0. 環境準備
VSCode
肝心のVSCode以下からインストールします。
https://code.visualstudio.com/Docker
DockerはLambdaローカル実行時に使用するので必須です。
インストールしてない方はここからインストールします。
https://hub.docker.comPython
awscliをインストールする際に使います。
インストールされてない場合は、インストールしてください。$ python --version Python 3.7.0 $ pip --version pip 19.1.1AWS Cli
以下コマンドでawsとsamをインストールしましょう。
$ pip install awscli $ pip aws-sam-cliインストール済みの場合は、awscliのバージョンを上げておきましょう。
$ pip install -U aws-sam-cliaws configureでaws のアクセスキーとシークレットキーを設定しましょう。
$ aws configure
AWS Toolkit for Visual Studio Code
VSCodeの拡張機能で「AWS Toolkit」と検索して、インストールします。
1. HelloWorldローカル実行
1-1. テンプレ作成
コマンドパレット(Macなら、Shift + ⌘ + P) を開き、
「aws create new Sam Application」を選択します。以下の順に聞かれるので入力します。
- 開発する言語(今回はPython3.7を選びました)
- ディレクトリ(今回はtest)
- プロジェクト名(今回はhello)
test/helloが作られていればOKです。
1-2. ローカル実行
hello_world/app.pyを開きます。
以下の上に 「Run Locally | Debug Locally | Configure」と表示されているので、
「Run Locally」をクリックしていきなり実行します。def lambda_handler(event, context):{"statusCode":200,"body":"{\"message\": \"hello world\"}"} Local invoke of SAM Application has ended.こんな感じで出力されればOKです(最初はコンテナが起動するので時間がかかります)。
これでローカルでLambdaが実行できました。2. デプロイ
- デプロイ用のS3バケットを作成($ aws s3 mb s3://BUCKET_NAME)
- コマンドパレットを開いて、「aws Deploy SAM Application」を選択
- デプロイするテンプレートの選択。今回は「hello/template.yaml」を選択
- リージョンの選択。今回は「Asia Pacific (Tokyo)」を選択
- 1で作成したS3バケット名を指定
- cloudformationのstack名を入力(プロジェクト名をいれておけばまずOK)
Successfully deployed SAM Application to CloudFormation Stack: hello with profile: ****上記出力されれば無事にデプロイされました。
VSCodeの左メニューのAWSアイコンを選択すると、
CloudFormationおよびLambdaの所に、デプロイしたhelloが表示されていると思います。AWSコンソール「API GateWay」>「hello」>「ステージ」>「Prod」>「URL の呼び出し」
のURLに/helloをつけてブラウザ等でアクセスすると「hello_word」のメッセージが表示されます。URLは以下の感じ。
https://*********.execute-api.ap-northeast-1.amazonaws.com/Prod/helloこれで、Lambdaのデプロイができました(APIが作れました)。
削除する際は、VSCodeからCloudFormationのhelloを選択して、「Delete CloudFormation Stack」をしてください。
これで関連するサービスがすべて消えます。番外編
AWS Toolkit for Visual Studio Code がなかった頃はコマンドでやってましたので、コマンドでもやってみます。
1. HelloWorldローカル実行
0.環境準備 は済んでいるものとします。
1-1. テンプレ作成
$ cd test $ sam init -r python3.7 -n hellotestディレクトリにhelloプロジェクトをPython3.7で作成します。
以下の通り、作成されます。
$ cd hello $ tree . |-- README.md |-- event.json |-- hello_world | |-- __init__.py | |-- __pycache__ | | |-- __init__.cpython-37.pyc | | `-- app.cpython-37.pyc | |-- app.py | `-- requirements.txt |-- template.yaml `-- tests `-- unit |-- __init__.py |-- __pycache__ | |-- __init__.cpython-37.pyc | `-- test_handler.cpython-37.pyc `-- test_handler.py1-2. ローカル実行
以下のコマンドで実行します。
hello worldが出力されればOK$ cd hello $ sam local invoke -e event.json 〜(略)〜 {"statusCode": 200, "body": "{\"message\": \"hello world\"}"}2. デプロイ
デプロイ用のS3バケットを作ります。作ってあればOKです
$ aws s3 mb s3://BUCKET_NAME
以下コマンドでパッケージ化したものをS3に設置
$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket BUCKET_NAME $ sam deploy --template-file packaged.yaml --stack-name hello --capabilities CAPABILITY_IAM Waiting for changeset to be created.. Waiting for stack create/update to complete Successfully created/updated stack - helloAWSコンソールから,CloudFormation, Lambda, APIGateWay を確認してみてください。
作成されているはずです。削除する際は、CloudFormationから削除すれば関連するサービスまとめて削除してくれます。
- 投稿日:2019-07-16T13:29:31+09:00
[AWS] EMR調査メモ
EMR
- 公式
- Amazon EMR は、業界をリードするクラウドネイティブなビッグデータプラットフォームです。大規模環境で大量のデータを迅速かつコスト効率よく処理できます
公式HPから引用
クラスター作成
- クラスター名を入力
- ログ記録するかチェック
- 今回はログ記録しない
- 起動モードは「クラスター」を選択
- リソース選択
emr-5.24.1
を選択- アプリケーション
Core Hadoop: Hadoop 2.8.5 with Ganglia 3.7.2, Hive 2.3.4, Hue 4.4.0, Mahout 0.13.0, Pig 0.17.0, and Tez 0.9.1
- インスタンスタイプ
m3.xlarge
- インスタンス数
- 1
- EC2キーペア
- アクセス権限
- デフォルト
EC2ログイン
- 上記で指定したキーペアの権限を「400」に変更
- EMR用のEC2インスタンスを確認しログインする
- ex)
ssh -i "xxxx.pem" ec2-user@xxxx.xxxx.compute.amazonaws.com
S3DistCp
- ドキュメント
- S3に対する様々な操作が可能
- 複数ファイル集約
- 圧縮
- 使用方法7つのヒント
ファイル集約
s3-dist-cp --src /data/incoming/hourly_table --dest s3://my-tables/processing/daily_table --targetSize=10 --groupBy=’.*/hourly_table/.*/(\d\d)/.*\.log’
- 投稿日:2019-07-16T12:01:58+09:00
Amazon VPC エンドポイント の GatewayとInterface
1.GatewayとInterface
下記の通り、VPCエンドポイントの方式には、GatewayとInterfaceがある。Gatewayはs3とdynamodのみ。
Gateway
VPCのルートテーブルを書き換えてVPCエンドポイントのゲートウェイ経由でAWSのAPIエンドポイントへアクセスする。
ゲートウェイVPCエンドポイントではAWSのAPIへはパブリックIPへ向いており、アクセス制御はゲートウェイのアクセスポリシーで行います。Interface
サービスのエンドポイントとENIをPrivateLinkと呼ばれるものでリンクされます。
DNSを使ってENIのプライベートIPに<サービス名>.<リージョン>.amazonaws.comのようなAレコードが設定されます。
インターフェイスVPCエンドポイントではENIに対してアクセスするため、アクセス制御はセキュリティグループで行います。詳しくは下記のページが参考になりました。
タイプによる違いを整理:ゲートウェイとインターフェース2.Gateway
ここでは、[com.amazonaws.ap-northeast-1.s3]を選択します。
エンドポイントにアクセスできるVPCとサブネットを指定します。
ここでは、わざとカスタムで特定のバケットに対し、GetとPutのみ許可するようなポリシーを設定しています。詳細は、Amazon S3 のエンドポイントポリシーの使用
を参考にしてください。{ "Statement": [ { "Sid": "Access-to-specific-bucket-only", "Principal": "*", "Action": [ "s3:GetObject", "s3:PutObject" ], "Effect": "Allow", "Resource": ["arn:aws:s3:::naata-vpcep", "arn:aws:s3:::naata-vpcep/*"] } ] }なお、ルートテーブルに以下のとおり、追加されていることがわかります。
検証してみます。
特定のバケットへのGetとPutのみ許可しているので、これはもちろんアクセスできません。
aws s3 ls --region ap-northeast-1 An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied下記のとおり、特定のバケットへのputが成功していることがわかります。
aws s3 cp test.txt s3://naata-vpcep upload: ./test.txt to s3://naata-vpcep/test.txt3.Interface
ここでは、プライベートサブネットに配置してあるEC2インスタンスから、sshを利用せずセッションマネージャーを利用して接続したいと思います。
エンドポイントは同じように4つ作成すればよい。
com.amazonaws.ap-northeast-1.ssm
com.amazonaws.ap-northeast-1.ssmmessage
com.amazonaws.ap-northeast-1.ec2
com.amazonaws.ap-northeast-1.ec2messages
Systems Manager 用 VPC エンドポイントを作成する「com.amazonaws.ap-northeast-1.ssm」を選択します。
VPCエンドポイントを設定するVPCを選択して、ENIを配置するサブネットを選択します。
[プライベート DNS 名を有効にする]で「このエンドポイントで有効にする」にチェックを入れます。
【注意】
「このエンドポイントで有効にする」でチェックを入れている場合、VPCの設定でDNS 解決とDNS ホスト名を有効にしておく必要があります。
ENIに設定するセキュリティグループを選択します。※対象のEC2からHTTPS(443)を受け取れるセキュリティグループとするのが基本です。
作成されたら、DNS Namesが3つ作成されと思います。
<エンドポイントID>-XXXXXXXX.ssm.<リージョン>.vpce.amazonaws.com
<エンドポイントID>-XXXXXXXX-.ssm.ap-northeast-1.vpce.amazonaws.com
ssm.ap-northeast-1.amazonaws.com
セッションマネージャを確認し、接続できるか確認してみましょう。
コマンドを打てるコンソールまでは開いたが、何も反応しない。。。
そこで、こちらのページにある内容で解決!
セッションマネージャーのログの出力先として設定されている s3やCloudWatch Logsのロググループの設定を確認し、接続することができた。
- 投稿日:2019-07-16T12:01:08+09:00
[AWS] AWSソリューションアーキテクトアソシエイト合格までにしたこと
AWSソリューションアーキテクトアソシエイト
先日受験し無事合格することができました
受験対策として自分が行ったことを記録して置こうと思いますAWSソリューションアーキテクトアソシエイトは長いので、「SAA」と略します
SAAとは
- AWS認定の一つ
- AWS のテクノロジーを使用して安全で堅牢なアプリケーションを構築およびデプロイするための知識を効果的に証明できる、とされている
対象者
- 可用性、優れたコスト効率、耐障害性を備え、スケーラブルな AWS 上での分散システムの設計に関して、少なくとも 1 年の実務経験のある方が対象
詳しくは
合格までの事前知識とスケジュール
事前知識
- AWSは「少し触ったことがある」程度
- EC2、S3などの有名サービスは「知っている」程度
- どのように組み合わせたらシステムが構築できるかについては全く無知
- 初心者
スケジュール
- 4月
- 対策本を読む
- 5月
- Udemy講座をひたすら見る
- 6月
- Udemy講座をひたすら見る
Architecting on AWS
の受講- 問題集を解く
- 7月
- 受験&合格
合格までにしたこと&合格貢献度
- 対策本
- Udemy講座
Architecting on AWS
の受講- AWS公式模擬試験
1. 対策本
まず上記書籍を購入しAWSとは何か、AWSソリューションアーキテクトアソシエイトとは何かを勉強しました
この本で得られたことは
- SAAでカバーすべきサービスが分かる
- 構成図も載っているのでサービスをどのように組み合わせてシステム構成すればよいか分かる
- AWSベストプラクティス「5つの柱」について章別に記載されているのでそれぞれについてしっかり学べる
- 各章末に確認問題があるので知識確認になる
- 模擬問題がDLでき本番試験にかなり似た問題を事前に解いて感覚を養える
まず手始めにAWSを知る、SAAを知るには丁度良いかと思います
ページ数も膨大、というほどではないので早い人だと数日で読み終えられると思います2. Udemy講座
上記講座は、様々な合格記事を拝見している中でオススメされていたので自身でも購入
結果、この講座にて合格できたと言っても過言ではないくらいにお世話になった本講座で得られたことは
- ハンズオンによりAWSを実際に触りながら対象のサービスを理解できる
- 細かく章立てされているので移動時間に必要な箇所だけを見られる
- 噛み砕かれた説明を聞くことで理解がしやすい
- 問題集が「3回分」ついていて かつ 内容がかなり本番に近い
この講座がなければ合格は無理だったなと振り返って思います
「問題集」がかなり役に立ちます
本番にかなり似た問題が出題されるので知識確認をするのに最適です
この問題でしっかりと点を取れるようになれば合格は近いと思います3.
Architecting on AWS
の受講縁あって上記コースを受講することができました
3日間のコースとなっています本講座でえられたことは
- 3日間集中してみっちりと学習することができる
- AWSマスターのような方々から直接学ぶことができ得るものが大きい
- 「AWSの考えた」を学ぶことができる
AWS公式だけあってとても内容の濃い講座でした
2日座学、1日ハンズオンでしたが、座学の濃さに頭破裂する寸前でしたw
この講座で最も学びがあったのは「AWS」がどのように考えて様々なサービスや機能を作っているか、を知ることができたことです
これをしっかり意識しているかどうかでかなり差が出ると感じます4. AWS公式模擬問題
公式の模擬問題です
オンラインで受験可能で「25問」の問題を解くことができます
点数ではなく%で結果が通知されます模擬問題で得られたことは
- 試験のリハーサルになった
- 自身の実力を知ることができた
問題は本番と比べるとかなり簡単でした
ですので模擬問題でしっかりと点が取れてないと合格はかなり厳しいと感じます振り返り
自分がなぜ合格できたかを振り返ってみます
- 良質な学習コンテンツを通して学べた
- 問題集を繰り返し解いた
良質な学習コンテンツを通して学べた
Udemy講座は本当に役立ちました
この講座だけで本当に合格ラインまではいけると思います
(オススメし過ぎて回し者みたいですね、、、)
Architecting on AWS
は「AWSの考え」を知れたとても良い講座でした
ただし非常に高額ですので無理に受講する必要はないかと思います
SAA合格に必須ではないでしょう問題集を繰り返し解いた
対策本(1回分)、Udemy講座(3回分)、計4回分の問題を解きました
本番試験の問題と遜色ないレベルの問題で非常に有益でした
4回分全てを繰り返し解き合格点が取れるようにしましたあとがき
簡単ですが自分の合格に関するまとめです
問題を解くことで合格に近づきましたが、
それに加えて「AWSだからこの場合はこうする」「これは○○のパターンだ」といういった考え方でできたら合格はすぐだと思います
微力でもお役に立ったらと思います
- 投稿日:2019-07-16T10:31:54+09:00
[豆知識?]突然死したEC2インスタンスは停止から起動で蘇生できる
概要
掲題の通りにEC2インスタンスが突然死し、ホスティングしているサービスがダウン、SSHログイン不可、各種メトリクス取得不可、AWSコンソールからのインスタンスの再起動でも改善されないという時に以下の手順を実行してみてください
この突然死は事前に過度な負荷があったわけでもなく、なにか作業しているわけでもなく、ほんとうに突然ぽっくりとお亡くなることを指します
結論
一旦「停止」してから「開始」することで復活します
なぜなのか
上記のケースはインスタンスのホスト障害による可能性があります。(最終的にはサポートに確認することをお勧めします)
一旦停止し、再度起動することで正常なホスト上でインスタンスが起動される仕組みのようです(サポート担当者から教えて頂きました)
- 投稿日:2019-07-16T09:00:14+09:00
AWS CloudFormationのLambda-BackedカスタムリソースでネストされたJSONを返しても参照できない
AWS CloudFormationn(CFn)のLambda-Backedカスタムリソースを利用していてレスポンスとしてネストされたJSONを返そうとしたらハマったので調べてみました。
ハマった内容
Lambda-Backedカスタムリソースで
import cfnresponse def handler(event, context): data = { "hoge": "hoge", "foo": { "hoge": "foohoge" } } cfnresponse.send(event, context, cfnresponse.SUCCESS, data)のようにCFnへレスポンスを返してCFnテンプレートで
Outputs: hoge: Value: !GetAtt CustomResource.hoge foo: Value: !GetAtt CustomResource.foo.hogeと、カスタムリソースの値を参照すると
!GetAtt CustomResource.foo.hoge
でエラーになりました。
エラー内容はCustomResource attribute error: Vendor response doesn't contain foo.hoge key
。解決策
Lambda-BackedカスタムリソースでJSONを返す場合はネストせずフラットなJSONを返しましょう。
以下検証内容となります。
検証内容
前提
- AWSアカウントがある
- AWS CLIが利用できる
- AWS Lambda、CloudFormationの作成権限がある
エラーにならないケース
テンプレート
Lambda関数ではネストされたJSONを返しますが、
!GetAtt
ではネストされた値を参照しないパターンです。
これでスタック作成してもエラーになりません。cfn-template.yamlResources: CustomResource: Type: Custom::CustomResource Properties: ServiceToken: !GetAtt CustomResourceFunction.Arn CustomResourceFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Role: !GetAtt FunctionExecutionRole.Arn Code: ZipFile: !Sub | import cfnresponse def handler(event, context): data = { "hoge": "hoge", "foo": { "hoge": "foohoge" } } cfnresponse.send(event, context, cfnresponse.SUCCESS, data) Runtime: python3.7 FunctionExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: root PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: "arn:aws:logs:*:*:*" Outputs: hoge: Value: !GetAtt CustomResource.hogeスタック作成して確認する
> aws cloudformation create-stack \ --stack-name cfn-response-test \ --template-body file://cfn-template.yaml \ --capabilities CAPABILITY_IAM { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a" } > aws cloudformation describe-stacks \ --stack-name cfn-response-test { "Stacks": [ { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "StackName": "cfn-response-test", "CreationTime": "2019-06-26T01:47:20.177Z", "RollbackConfiguration": {}, "StackStatus": "CREATE_COMPLETE", "DisableRollback": false, "NotificationARNs": [], "Capabilities": [ "CAPABILITY_IAM" ], "Outputs": [ { "OutputKey": "hoge", "OutputValue": "hoge" } ], "Tags": [], "EnableTerminationProtection": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] }正常に作成できました。Lambda関数のログを確認しておきます。
> aws cloudformation list-stack-resources \ --stack-name cfn-response-test { "StackResourceSummaries": [ { "LogicalResourceId": "CustomResource", "PhysicalResourceId": "2019/06/26/[$LATEST]f518c197bb8541f0b651a151bb201560", "ResourceType": "Custom::CustomResource", "LastUpdatedTimestamp": "2019-06-26T01:47:45.532Z", "ResourceStatus": "CREATE_COMPLETE", "DriftInformation": { "StackResourceDriftStatus": "NOT_CHECKED" } }, { "LogicalResourceId": "CustomResourceFunction", "PhysicalResourceId": "cfn-response-test-CustomResourceFunction-HI0ITG58NF7G", "ResourceType": "AWS::Lambda::Function", "LastUpdatedTimestamp": "2019-06-26T01:47:39.855Z", "ResourceStatus": "CREATE_COMPLETE", "DriftInformation": { "StackResourceDriftStatus": "NOT_CHECKED" } }, (略) ] } > aws logs get-log-events \ --log-group-name /aws/lambda/cfn-response-test-CustomResourceFunction-HI0ITG58NF7G \ --log-stream-name '2019/06/26/[$LATEST]f518c197bb8541f0b651a151bb201560' \ --output=text \ --query "events[*].message" START RequestId: db73aff3-d14a-4ff1-92cc-6335d23279aa Version: $LATEST https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/(略) Response body: {"Status": "SUCCESS", "Reason": "See the details in CloudWatch Log Stream: 2019/06/26/[$LATEST]f518c197bb8541f0b651a151bb201560", "PhysicalResourceId": "2019/06/26/[$LATEST]f518c197bb8541f0b651a151bb201560", "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "RequestId": "c734ee9f-7963-4626-bf6e-40d7e24a99ab", "LogicalResourceId": "CustomResource", "NoEcho": false, "Data": {"hoge": "hoge", "foo": {"hoge": "foohoge"}}} Status code: OK END RequestId: db73aff3-d14a-4ff1-92cc-6335d23279aa REPORT RequestId: db73aff3-d14a-4ff1-92cc-6335d23279aa Duration: 310.53 ms Billed Duration: 400 ms Memory Size: 128 MB Max Memory Used: 24 MBレスポンス内容の
Data
でネストされたJSONを返していることが確認できます。エラーにならないケース
Outputs
の定義を変更して確認します。テンプレート(抜粋)
cfn-template.yaml_抜粋Outputs: hoge: Value: !GetAtt CustomResource.hoge foo: Value: !GetAtt CustomResource.foo.hogeスタック更新して確認する
> aws cloudformation update-stack \ --stack-name cfn-response-test \ --template-body file://cfn-template.yaml \ --capabilities CAPABILITY_IAM { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a" } > aws cloudformation describe-stacks \ --stack-name cfn-response-test { "Stacks": [ { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "StackName": "cfn-response-test", "CreationTime": "2019-06-26T01:47:20.177Z", "LastUpdatedTime": "2019-06-26T01:50:44.408Z", "RollbackConfiguration": {}, "StackStatus": "UPDATE_ROLLBACK_COMPLETE", "DisableRollback": false, "NotificationARNs": [], "Capabilities": [ "CAPABILITY_IAM" ], "Outputs": [ { "OutputKey": "hoge", "OutputValue": "hoge" } ], "Tags": [], "EnableTerminationProtection": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] }
UPDATE_ROLLBACK_COMPLETE
となり更新に失敗しました。
イベントを取得してエラー内容を確認します。> aws cloudformation describe-stack-events \ --stack-name cfn-response-test { "StackEvents": [ { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "e01c4f90-97b4-11e9-bb14-12f81177eb92", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:51:12.126Z", "ResourceStatus": "UPDATE_ROLLBACK_COMPLETE" }, { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "df9dd0c0-97b4-11e9-9cbb-0eaa79b17470", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:51:11.295Z", "ResourceStatus": "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" }, { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "d1776100-97b4-11e9-a0b3-0a20b68b404c", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:50:47.544Z", "ResourceStatus": "UPDATE_ROLLBACK_IN_PROGRESS", "ResourceStatusReason": "CustomResource attribute error: Vendor response doesn't contain foo.hoge key in object arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a|CustomResource|c734ee9f-7963-4626-bf6e-40d7e24a99ab in S3 bucket cloudformation-custom-resource-storage-useast1" }, (略) ] }
CustomResource attribute error: Vendor response doesn't contain foo.hoge key
とエラー内容が確認できます。参照方法を変えてみる
!GetAtt CustomResource.foo.hoge
としているのがダメなのかなと考えて参照方法を変更してみました。テンプレート(抜粋)
cfn-template.yaml_抜粋Outputs: hoge: Value: !GetAtt CustomResource.hoge foo: Value: !GetAtt CustomResource.foo['hoge']スタック更新して確認する
> aws cloudformation update-stack \ --stack-name cfn-response-test \ --template-body file://cfn-template.yaml \ --capabilities CAPABILITY_IAM { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a" } > aws cloudformation describe-stacks \ --stack-name cfn-response-test { "Stacks": [ { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "StackName": "cfn-response-test", "CreationTime": "2019-06-26T01:47:20.177Z", "LastUpdatedTime": "2019-06-26T01:54:45.226Z", "RollbackConfiguration": {}, "StackStatus": "UPDATE_ROLLBACK_COMPLETE", "DisableRollback": false, "NotificationARNs": [], "Capabilities": [ "CAPABILITY_IAM" ], "Outputs": [ { "OutputKey": "hoge", "OutputValue": "hoge" } ], "Tags": [], "EnableTerminationProtection": false, "DriftInformation": { "StackDriftStatus": "NOT_CHECKED" } } ] } > aws cloudformation describe-stack-events \ --stack-name cfn-response-test { "StackEvents": [ { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "6f1d0b80-97b5-11e9-b714-0a2e8057061e", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:55:12.038Z", "ResourceStatus": "UPDATE_ROLLBACK_COMPLETE" }, { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "6eb6f6b0-97b5-11e9-aaf5-0a437bda7b86", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:55:11.375Z", "ResourceStatus": "UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" }, { "StackId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "EventId": "609a23e0-97b5-11e9-a31e-0e366af4fd90", "StackName": "cfn-response-test", "LogicalResourceId": "cfn-response-test", "PhysicalResourceId": "arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a", "ResourceType": "AWS::CloudFormation::Stack", "Timestamp": "2019-06-26T01:54:47.692Z", "ResourceStatus": "UPDATE_ROLLBACK_IN_PROGRESS", "ResourceStatusReason": "CustomResource attribute error: Vendor response doesn't contain foo['hoge'] key in object arn:aws:cloudformation:us-east-1:xxxxxxxxxxxx:stack/cfn-response-test/55d8cd90-97b4-11e9-aa0c-128a65397f5a|CustomResource|c734ee9f-7963-4626-bf6e-40d7e24a99ab in S3 bucket cloudformation-custom-resource-storage-useast1" }, (略) ] }
CustomResource attribute error: Vendor response doesn't contain foo['hoge'] key
とエラーになりました。まとめ
Lambda-BackedカスタムリソースでネストされたJSONを返しても
!GetAtt
では参照できないことがわかりました。ドキュメントにはDataの型がType: JSON object
と定義されているのですが制限があるみたいです。。。カスタムリソースの応答オブジェクト - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html参考
カスタムリソースの応答オブジェクト - AWS CloudFormation
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html
- 投稿日:2019-07-16T08:29:07+09:00
AMI をアカウント跨ぎで(他リージョンへ)スケジュールコピーする Lambda 関数
以前、AMIを他リージョンへスケジュールコピーするLambda関数という記事を書きましたが、それをアカウントを跨いで実行するためのものです。
ポイント
- コピー対象の AMI 全てにコピー先のアカウントに対するアクセス権を付与する
- コピー元アカウントの KMS キーを利用できるようにコピー先で作成する Lambda 関数のロールに必要なポリシーを付与する
- コピー先アカウントからはコピー元のタグは不可視なので、別項目(「説明」:description)をキーにしてコピー対象を絞り込む
なお、今回は、
- AMI のアクセス権付与はコピー元アカウントで
- AMI コピーはコピー先アカウントで
それぞれ実行するための Lambda 関数を作成します。
※前回同様、コピー元の AMI は KMS カスタマー管理キーで暗号化されているものとします(デフォルトキー=AWS マネージドキーは不可)。
作業内容
1. コピー元アカウントで KMS キーにキーユーザーを登録
AMI 暗号化のために使っている KMS カスタマー管理キーに対して、
- 4. の Lambda 関数で利用するロール(キーユーザーとして)
- 前回記事「1. ロール作成」と同じ要領で作成。面倒なら 4. の Lambda 関数作成時に合わせて作成して KMS カスタマー管理キーに追加する。↓の 2. も同様。
- コピー先アカウント(アカウント ID)
を追加します。
2. コピー先アカウントで KMS カスタマー管理キーを作成してキーユーザーを登録
カスタマー管理キーを作成し、キーユーザーとして 5. の Lambda 関数で利用するロールを追加します。
3. コピー先アカウントでポリシーを登録
コピー元アカウントの KMS カスタマー管理キーを使えるように、コピー先アカウントに以下のポリシーを登録します。
ポリシー登録{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowUseOfCMK", "Effect": "Allow", "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "arn:aws:kms:ap-northeast-1:【コピー元アカウントID】:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" }, { "Sid": "AllowUseofCMKToCreateEncryptedResources", "Effect": "Allow", "Action": "kms:CreateGrant", "Resource": "arn:aws:kms:ap-northeast-1:【コピー元アカウントID】:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", "Condition": { "Bool": { "kms:GrantIsForAWSResource": true } } } ] }※「key/」の後ろにはコピー元 AMI の暗号化に使う KMS カスタマー管理キーの ID を入力します。
登録したら、2. の KMS カスタマー管理キーのキーユーザーとして登録した Lambda 関数のロールにこのポリシーを追加で付与します。
4. コピー元アカウントで AMI アクセス権付与のための Lambda 関数を作成
Python 3.7 で以下のコードを登録します。
AMIアクセス権付与import boto3 import os def lambda_handler(event, context): region = os.environ["REGION"] tagKey = os.environ["TAG_KEY"] owner = os.environ["OWNER"] share = os.environ["SHARE"] # 変更対象のイメージを抽出 client = boto3.client('ec2', region) images = client.describe_images( Filters=[{'Name':'tag-key','Values':[tagKey]}], Owners=[owner] ) # 変更対象イメージがあれば変更実行 for image in images['Images']: modifyKey = image['ImageId'] print("Modifying Image Attribute '{}'.".format(modifyKey)) client.modify_image_attribute( ImageId=modifyKey, LaunchPermission={'Add':[{'UserId':share}]} ) for snapshot in image['BlockDeviceMappings']: client.modify_snapshot_attribute( CreateVolumePermission={'Add':[{'UserId':share}]}, SnapshotId=snapshot['Ebs']['SnapshotId'] )なお、AMI の抽出対応を 5. と同様に「説明」(description)にしたい場合は 5. を参考にコードを書き替えてください。
テストしてみてうまく動作したら、必要に応じて CloudWatch イベントの cron 式で定時実行をセットします。
5. コピー先アカウントで AMI コピーを行う Lambda 関数を作成
Python 3.7 で以下のコードを登録します。
AMIコピーimport boto3 import os def lambda_handler(event, context): sourceRegion = os.environ["SOURCE_REGION"] destRegion = os.environ["DEST_REGION"] sourceDescription = os.environ["SOURCE_DESCRIPTION"] destTagKey = os.environ["DEST_TAG_KEY"] owner = os.environ["OWNER"] encryptKey = os.environ["ENCRYPT_KEY"] # コピー対象のイメージを抽出 sourceClient = boto3.client('ec2', sourceRegion) sourceImages = sourceClient.describe_images( Filters=[{'Name':'description','Values':[sourceDescription]}], Owners=[owner] ) # 削除対象のイメージを抽出 destClient = boto3.client('ec2', destRegion) deleteImages = destClient.describe_images( Filters=[{'Name':'tag-key','Values':[destTagKey]}], Owners=[owner] ) # コピー対象イメージがあればコピー実行 for sourceImage in sourceImages['Images']: copyKey = sourceImage['ImageId'] print("Copying Image '{}' to {}.".format(copyKey, destRegion)) new_ami = destClient.copy_image( DryRun=False, SourceRegion=sourceRegion, SourceImageId=copyKey, Name=sourceImage['Name'], Description='', Encrypted=True, KmsKeyId=encryptKey ) destClient.create_tags(Resources=[new_ami['ImageId']], Tags=[{'Key':destTagKey,'Value':''}]) # 削除対象イメージがあれば削除実行 for deleteImage in deleteImages['Images']: deleteKey = deleteImage['ImageId'] print("Deleting Image '{}' from {}.".format(deleteKey, destRegion)) try: destClient.deregister_image(ImageId=deleteKey) for snapshot in deleteImage['BlockDeviceMappings']: destClient.delete_snapshot(SnapshotId=snapshot['Ebs']['SnapshotId'], DryRun=False) except destClient.exceptions.NoSuchEntityException: print("Image '{}' not found.".format(deleteKey))※コピー対象の AMI の絞り込みには以下の項目を使います。
テストしてみてうまく動作したら、必要に応じて CloudWatch イベントの cron 式で定時実行をセットします(4. の 10 ~ 15 分程度後の時間を指定)。
その他
以前、一度にコピーできる AMI の数は 25 個だった気がするのですが、最近実行してみたところ 50 個まで同時にコピーできるようになっていました。
- 投稿日:2019-07-16T04:18:04+09:00
Terraform設計・運用のノウハウ
概要
Terraformを使い始めて一年ほど経ったので、設計や運用上のノウハウを公開していこうと思います。
基本的にAWSを使うことが多いので、AWS寄りの話になります。設計編
利用可能なプロバイダを調べる
TerraformはAWSやGCPといったクラウドサービスをコード化できることで有名ですが、オフィシャルだけでも様々なプロバイダに対応しています。
私はAWSのほか、GitHubやDatadogをコード化して運用してます。ネットワーク設計
サービスを構築する上で本番環境のほかに開発やステージング環境を作りますが、環境の分け方は大きく分けて次のいずれかになることが多いと思います。
- 1つのVPCに全ての環境を入れる
- 環境ごとにVPCを分ける
- 環境ごとにAWSアカウントを分ける
2のパターンで設計する場合、Terraformで構成を組む際はVPCを
development
、staging
、production
に分離し、更に各VPCで共通となるサービスを配置するためのmanagement
を作成します。management
には踏み台であったり、CI/CDを管理するインスタンスを配置しています。
ネットワーク上はmanagement
から各環境にVPCペアリングで接続できますが、環境間(例えばdevelopment
からstaging
、staging
からproduction
)の接続はルートテーブル上で制限しています。Workspaceを使う
Terraformで環境ごとのリソースを管理する方法は大きく分けて2つあります。
- 環境ごとにディレクトリを分けて管理
- Workspaceを使う
TerraformにはWorkspaceと呼ばれる環境ごとにリソースを管理する仕組みがあります。
先に上げたネットワーク構成にWorkspaceを適用することで、VPC単位のリソース構成が管理しやすくなります。$ terraform workspace list default * development production staging※
management
VPCはWorkspace管理下から除外しています。ディレクトリ設計
Terraformでリソースを管理する場合、悩むことになるのがディレクトリ構成かと思います。最もシンプルな構成は以下のような構成ではないでしょうか。
terraform aws ec2 main.tf variables.tf outputs.tf providers.tf backend.tf version.tf security_group main.tf variables.tf outputs.tf providers.tf backend.tf version.tf ...サービスが1つであれば上記構成でも運用できそうですが、サービスがスケールするにつれ、サブドメインで動く別のシステムや、リージョンをまたいだ構成も生まれる可能性があります。
最近私が設計していて割と汎用的に使えると思ってる構成は以下のようなものです。
terraform providers aws global: AWS全般に関する設定 general: global iam route53 ... ap-northeast-1 cognito cloudtrail ... management: Management VPC global iam waf ... ap-northeast-1 vpc security_group ... workspace: 環境ごとの設定 global iam waf ... ap-northeast-1 vpc ecs ... {SERVICE NAME}: サービス名。例えばqiita general global route53 ... workspace ap-northeast-1 global route53 cloudfront ... datadog ... github ...利点としては、
- Terraformの実行単位がAWSのサービス構成と同じ (誤ってリソースを操作した際の影響範囲が限定される)
- AWS全般に関わる設定を
base
、特定のサービスに依存する設定を{SERVICE_DOMAIN}
下に配置することで、リソースの構成が視覚化されるなどが挙げられます。
moduleはあえて使わず、Terraform Best Practiceを読む
Terraform Best Practiceを読みましょう。中でもNaming conventionsは非常に有用です。いくつか気になるポイントをまとめてみました。
- Resource and data source arguments
- リソース名や変数、出力名の区切り文字には
-
の代わりに_
を使う- リソース名にはリソースタイプを含めない (例えば、
aws_route_table
のリソース名にroute_table
などのタイプを含めない)- 単一リソースや妥当な名前がない場合、リソース名は
this
とするtags
、depends_on
、lifecycle
はリソースの最後に記述する- Variables
default = []
がある場合、type = "list"
は省略するdefault = {}
がある場合、type = "map"
は省略するlist
やmap
の変数名は複数形を使用する- Outputs
- 名前は
{name}_{type}_{attribute}
形式が望ましい実装編
Docker版Terraformを使う
Docker版のTerraformを利用しましょう。
バージョンを指定する
利用するバージョンを明確化することで、無用なトラブルを回避することができます。
Terraform
terraform { required_version = "= 0.12.4" }Docker版Terraformを利用する場合、イメージのバージョンは
latest
ではなく、0.12.4
のように番号で指定することをお勧めします。プロバイダバージョン
provider "aws" { version = "= 2.19.0" }モジュールバージョン
module "foo" { source = "terraform-aws-modules/security-group/aws" version = "3.0.1" }尚、
source
がGitHubの場合はversion
が使えないので、代わりにref
でバージョンを指定する必要がある。module "foo" { source = "github.com/azavea/terraform-aws-acm-certificate?ref=1.1.0" }tfstateファイルの管理方法
リソースの状態を管理するtfstateファイルはローカルやGitで管理するべきではありません。TerraformのBackend機能を使うことで、tfstateをDynamoDBやS3で管理することができます。
AWSを利用しているのであれば、S3がお手軽かと思います。terraform { backend "s3" { bucket = "mybucket" key = "path/to/my/key" region = "us-east-1" } }尚、S3を使う場合、対象バケットのバージョニングの有効化を強くお勧めします。tfstateを誤って削除したり、Terraformのバージョンアップでファイル構成が書き換わっても、簡単にステートファイルを復元することができます。
Terraform Module Registryを使う
Terraform Module Registryでは、汎用的に使えるモジュールが公開されてます。AWSで言えばEC2やSecurity Groupなど、いくつかの変数を渡すだけでリソースを作成してくれます。
Registryには大きく分けて、Terraformコミュニティが作ったものと、HashiCorpによって検証されたVerifiedモジュールがあります。
運用で使う場合は、検索時にVerified
にチェックを付けることをお勧めします。フォーマットを整形する
fmt
コマンドでディレクトリ下のファイルに対しまとめて整形してくれます。# 0.11まで $ terraform fmt # 0.12以降 $ terraform fmt -recursive環境ごとに異なる値を読み込む方法
変数名はWorkspace名を含めて定義します。
variable "rds_cluster" { default = { "default.engine_version" = "5.7.12" "production.engine_version" = "5.7.22" } }リソース作成時に
lookup
関数を使うことで、現在有効なWorkspaceがproduction
であれば5.7.22
、それ以外であれば5.7.11
の値が設定されます。resource "aws_rds_cluster" "this" { engine_version = lookup( var.rds_cluster, "${terraform.workspace}.engine_version", var.rds_cluster["default.engine_version"], ) ...lifecycleでリソースを保護する
リソースに
lifecycle
ブロックを指定することで、リソース作成・更新時の動作を変更することができます。lifecycle
にはいくつかのタイプがありますが、prevent_destroy
を指定することで、強制的なリソース再作成が発生したときにエラーを発生するようになります。main.tflifecycle { prevent_destroy = true }
destroy
を実行した結果。$ terraform destroy ... Error: Instance cannot be destroyed on main.tf line 55: 55: resource "aws_eip" "this" { Resource aws_eip.this has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flagリソースを強制的に削除したい場合は、
prevent_destroy
をfalse
にするか、ブロックごと削除して、apply
を実行します。※
prevent_destroy
はあくまでTerraform上で削除を保護するためのもので、AWSコンソールやCLIからは削除することが可能です。EC2やRDSなどいくつかのサービスには削除保護のオプションがあるので、別途有効化しておくことをお勧めします。IAM PolicyのJSONはaws_iam_policy_documentで定義する
以下のリソースはIAMポリシーがヒアドキュメント形式で書かれており、可読性が低いです。
main.tfresource "aws_iam_policy" "example" { # ... other configuration ... policy = <<POLICY { "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "*", "Resource": "*" } } POLICY }ヒアドキュメントはこのように置き換えることができます。HCLで書けるのでだいぶスッキリします。
main.tfresource "aws_iam_policy" "example" { # ... other configuration ... policy = data.aws_iam_policy_document.example.json } data "aws_iam_policy_document" "example" { version = "2012-10-17" statement { effect = "Allow" actions = ["*"] resources = ["*" } }デバッグログを出力する
環境変数
TF_LOG
にログレベルを渡すことで、ログを出力することができます。ファイルに出力したい場合はTF_LOG_PATH
も指定すると良いでしょう。実行速度を改善する
Terraformのコマンドに
--parallelism
を渡すことで、APIの同時呼び出し数を変更することができます。$ terraform plan --parallelism=20デフォルト値は
10
です。パフォーマンスを見て数値を変えて見ると良さそうです。
尚、環境変数で指定する場合はTF_CLI_ARGS_plan
、TF_CLI_ARGS_apply
、TF_CLI_ARGS_destroy
を指定します。拡張ライブラリ
- GoogleCloudPlatform/terraformer
- 既存のリソースからtfファイルとtfstateファイルを生成してくれる
- gruntwork-io/terragrunt
- Terraformのラッパー。stateファイルのロックや、モジュール管理をDRYにする仕組みを提供
- hashivim/vim-terraform
- Vimmer向け。保存時にフォーマット整形、コード検証
- vim-terraform-completion
- Vimmer向け。入力補完やコード検証
- 投稿日:2019-07-16T01:23:51+09:00
AWS Certified Machine Learning – Specialtyを受けてきた
AWS Certified Machine Learning – Specialtyを受けてきました。
取得を考えている方の参考になれば幸いです。試験概要
https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/
- 時間:170分
- 問題数:65問1
事前準備
- courseraでStanfordが提供している機械学習のオンライントレーニングを受講する
- 模擬試験を受ける
- 本を読む
- サンプル問題を解く
- AWSの無料オンライントレーニングを受講する
特に、1.courseraのオンライントレーニングはオススメです。
結果
幸い合格でした。
(スコアはAWSの認定のサイトからダウンロードします。)受験者スコア: 871
The AWS Certified Machine Learning - Specialty (MLS-C01) の試験結果は、100 から 1000 の間
の値で示されます。合格に必要な最低スコアは 750 です。受験者のスペック
参考になるかわかりませんが。。。
- AWS歴:5年
- クラウド関連の保有資格
- AWS: アソシエイト×3+プロフェッショナル×2+Big Data+Security+Network
- GCP: クラウドアーキテクト+データエンジニア
- 外観:メガネぼーず
難易度について
AWSの知識よりも機械学習の知識が問われる問題が多かったです。
また、他のAWSの試験に比べ、要求されるAWSの知識はかなり浅めに感じました。
そのため難易度は、こんな感じではないかと思います。機械学習を仕事で利用されている方 → 簡単
AWSのエンジニアだが機械学習は初学者(=自分) → 難しい感想
時間はかなり余りました。落ち着いてゆっくり解いても、十分試験時間内に収まると思います。
試験ガイドに記載が無いので、問題数は変わるかもしれません ↩