■AWS
アマゾン ウェブ サービス
https://aws.amazon.com/jp/
AWS = Amazon Web Services
Amazonが提供するクラウドコンピューティングサービス
従量課金制
■概要
Amazon EC2 インスタンスタイプ
https://aws.amazon.com/jp/ec2/instance-types/
Amazon RDS インスタンスタイプ
https://aws.amazon.com/jp/rds/instance-types/
【登壇資料】目的別、サーバーレスアーキテクチャの教科書!これのときはこう!【アーキテクチャ20連発】 #cm_osaka
http://dev.classmethod.jp/cloud/lean-serverless-architecture-pettern/
AWS特有の運用イベントまとめ(非障害系)
https://dev.classmethod.jp/cloud/aws/operational-event-on-aws/
AWSを学ぶために最初に構築するアーキテクチャパターン5選 - log4ketancho
http://www.ketancho.net/entry/2018/05/07/080000
AWS運用でよく聞く不安とその対策を書き出してみた | Developers.IO
https://dev.classmethod.jp/cloud/aws/anxiety-when-operating-aws/
Amazon EC2とは何か?「インスタンス」など関連用語もまとめて解説【保存版】 連載:やさしく学ぶAWS入門|ビジネス+IT
https://www.sbbit.jp/article/cont1/46306
【2022年】AWS全サービスまとめ | DevelopersIO
https://dev.classmethod.jp/articles/aws-summary-2022/
基本的なシステム構成図を理解するためのAWS基礎をまとめてみた - Qiita
https://qiita.com/goldayushi/items/0e0f34d19813b8fdc2b8
AWSの膨大で複雑なサービス群をすべて「たった1行」で説明していくとこうなる - GIGAZINE
https://gigazine.net/news/20200528-aws-one-line-explanation/
[初心者向け]200以上あるAWSサービスのどこから始めれば良いのかガイド | DevelopersIO
https://dev.classmethod.jp/articles/aws-beginners-guide/
[初心者向け]AWS Well-Architected ドキュメントの歩き方 | DevelopersIO
https://dev.classmethod.jp/articles/aws-well-architected-guide/
歴史・年表でみるAWS全サービス一覧 −アナウンス日、General Availability(GA)、AWSサービス概要のまとめ− - NRIネットコム Design and Tech Blog
https://tech.nri-net.com/entry/aws_history_and_chronology_all
Youは何のサービス?AWSの面白サービス名と認定試験の話 | DevelopersIO
https://dev.classmethod.jp/articles/what-aws-services/
AWS入門 初心者が覚えておくべきAWSの基本|コラム|クラウドソリューション|サービス|法人のお客さま|NTT東日本
https://business.ntt-east.co.jp/content/cloudsolution/column-37.html
■注意
AWSのコンソールはUIがどんどん改良されている
細かくメモしても次回に触れるときは何かしら変わっていることが多いので、内容を理解しつつ進めることが必要
■インスタンス選定・利用料金の計算
■料金
ざっくり見積もるなら以下のツールが便利
ざっくりAWS | AWSの料金を、日本円でざっくり
https://aws.noplan.cc/
AWSの料金を「ざっくり」計算できるサイトを作りました
https://qiita.com/noplan1989/items/64491dab247d92e10d41
以下に公式のツールがある
AWS Pricing Calculator
https://calculator.aws/
以下に公式の旧ツールがある
旧ツールは、そのうち廃止されるらしい
AWS Simple Monthly Calculator (簡易見積ツール)
http://calculator.s3.amazonaws.com/index.html?lng=ja_JP
※最初にリージョンの切り替えを忘れないように注意
※見積もりをする場合、日本リージョンで実際に使う構成を登録し、
EC2・ロードバランサー・RDSなどのデータ転送量をすべて「100GB/月」にすると、実際の料金に近い算出になる
※「Application Load Balancing」と「Network Load Balancing」の利用計算方法は要勉強
金額自体は「Classic Load Balancing」とそう変わらないらしいので、
普段は「Classic Load Balancing」の「Number of Classic LBs」が「1」で、
「Total Data Processed per CLB」が「100GB/月」として算出するようにしている
※1年目は無料利用枠が使えるが、それを考慮しない場合は「無料利用枠: 新規のお客様は最初の 12 か月間、無料利用枠をご利用になれます。」を外す
※このファイルの「金額比較メモ」項目に実例を記載している
クラウド推奨構成とお見積り例
https://aws.amazon.com/jp/cdp/
AWS 課金体系と見積り方法について
http://aws.amazon.com/jp/how-to-understand-pricing/
AWS 月額料金チートシート
http://qiita.com/jyotti/items/d47b52fa13d12476406f
AWS料金早見表
https://qiita.com/teradonburi/items/a382a17e1e0245b7d831
Amazon EC2とEBSの料金が秒単位の請求に変わります!
http://dev.classmethod.jp/etc/amazon-ec2-ebs-billing-per-seconds/
S3の料金体系が分かりにくいと聞かれたので纏めた
http://qiita.com/kawaz/items/07d67a851fd49c1c183e
データ転送量が多いと、S3結構高いのよ
http://blog.mah-lab.com/2014/04/20/s3/
【2021/2時点】AWSの通信料(コスト)を一枚にまとめてみた | いくらは神の食べ物
https://www.ikura-oisii.com/1065/
■無料利用枠
EC2で t2.micro を選択する画面で「無料利用枠の対象」と書かれているが、単純に「t2.micro なら無料で使える」という意味では無いので注意
「アカウント開設後12か月限定で、毎月稼働750時間まで無料」ということなので、2年目以降は関係ない
また、1ヶ月は長くて744時間なので、2台目のEC2を起動すると無料枠を超える
改めてAWSの「無料利用枠」を知ろう | DevelopersIO
https://dev.classmethod.jp/articles/overall-summary-about-aws-free-tier/
AWS無料枠一覧まとめ - Qiita
https://qiita.com/saxxos/items/78736bf700bd3479f9e2
データ転送量の無料枠は、2021年12月1日から拡張されたらしい
AWSのデータ転送無料枠が拡張されます。リージョンからの転送は月100GBまで無料、CloudFrontからの転送は月1TBまで無料に。 | DevelopersIO
https://dev.classmethod.jp/articles/aws-free-tier-data-transfer-expansion/
■制限
EC2インスタンスの起動数や固定IPの取得数など、諸々に上限が設けられている
大量のインスタンスを起動したり、複数の案件を一つのアカウントで管理したりする場合に注意
申請によって緩和することは可能
申請には3〜5営業日程度かかるとされている
AWS サービス制限
http://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html
AWSサービスの各種上限値一覧
http://dev.classmethod.jp/cloud/aws/aws-limits/
Amazon EC2 インスタンスの上限緩和申請時に確認しておくこと
https://dev.classmethod.jp/cloud/amazon-ec2-instance-lmits-check-point/
AWSの上限数とAWS Supportに泣きつく方法
http://blog.serverworks.co.jp/tech/2013/01/11/aws-limitation-and-aws-support/
EC2のインスタンス数は、インスタンスの種類によって異なる
よくある質問 - Amazon EC2
https://aws.amazon.com/jp/ec2/faqs/
「Q: Amazon EC2 ではいくつのインスタンスを実行できますか?」部分に具体的なインスタンス数が掲載されている
上限の初期値ではなく、現在の上限を確認したい場合は以下を参照
AWSのサポートに入っている人は Trusted Advisor 画面から確認できるらしい
AWS 現在のサービス上限値確認方法 - Qiita
https://qiita.com/ohayougenki/items/6112a5d298aa173b6331
限定的だが、CLIからも確認できる
$ aws ec2 describe-account-attributes --region ap-northeast-1 --output text
ACCOUNTATTRIBUTES supported-platforms
ATTRIBUTEVALUES VPC
ACCOUNTATTRIBUTES vpc-max-security-groups-per-interface
ATTRIBUTEVALUES 5
ACCOUNTATTRIBUTES max-elastic-ips
ATTRIBUTEVALUES 5
ACCOUNTATTRIBUTES max-instances
ATTRIBUTEVALUES 20
ACCOUNTATTRIBUTES vpc-max-elastic-ips
ATTRIBUTEVALUES 5
ACCOUNTATTRIBUTES default-vpc
ATTRIBUTEVALUES vpc-f11d9094
■障害情報
AWS Health Dashboard (東京リージョンは「Asia Pacific」タブ)
https://health.aws.amazon.com/health/status
AWS でいままで起きた大規模障害を振り返る
http://qiita.com/saitotak/items/07931343bcb703b101f8
AWSバッドノウハウ集
http://qiita.com/yayugu/items/de23747b39ed58aeee8a
以下はAWSに限定したものでは無いが参考になる
Downdetector
https://downdetector.jp/
■SLA
Amazon EC2 サービスレベルアグリーメント
https://aws.amazon.com/jp/ec2/sla/
シングルAZでEC2を配置していたものがダウンしてもSLAの対象外
「同一地域(リージョン)内で、
サービス利用者がインスタンスを実行している複数のアベイラビリティゾーンが、
サービス利用者にとって使用不能」
となったときが対象となる
AWSの共有責任モデル
http://www.slideshare.net/c95029/awsshared-responsibility-model-16612378
■Amazon Linux
Amazon Linux はRHEL6ベースなので、CentOS6の知識が役に立つ
Amazon Linux 2 はRHEL7ベースなので、CentOS7の知識が役に立つ
Amazon Linuxの特徴とCentOSとの違い まとめ
http://dev.classmethod.jp/cloud/aws/amazon-linux-centos-rhel-difference/
Amazon Linux2とAmazon Linuxの違いについて(メモ) - Qiita
https://qiita.com/akira345/items/2a09c4d06d2e3415bc8d
Amazon Linux AMI 2015.03 がリリースされました!
http://dev.classmethod.jp/cloud/aws/amazon-linux-ami-2015-03/
EC2で用意されているAMI、CentOS6とAmazonLinuxの挙動の違い - Qiita
https://qiita.com/CyberMergina/items/b9bf30b62380ebf16285
新世代のAmazon Linux 2 リリース | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/amazon-linux-2-release/
Amazon Linux 2 の登場と、Amazon Linux との違い、移行方法などをQ&Aから抜粋したメモ - michimani.net
https://michimani.net/post/aws-compare-amazonlinux-2-amazonlinux/
CentOS7自分がよく使うコマンド一覧 - Qiita
https://qiita.com/t-morisoba/items/2f60f88538b1ca0c5d0f
新規構築の場合、Amazon Linux ではなく Amazon Linux 2 を使うといい
Amazon Linuxのセキュリティ更新が2020年6月30日までとなっている
Amazon Linux 2へのアップグレードが必要だがサポート外
EBSの付け替えで対応できるか、完全新規に構築してファイル移行が必要か。検証が必要
…だったが、「メンテナンスサポート期間が2023年6月30日に設定されます」と更新されている
また「EOLは2020年12月31日まで拡張されました」とある
「新規で使用できるのが2020年12月31日まで、サポート期間は2023年6月30日まで」
ということか
いずれにせよ、新規構築は Amazon Linux ではなく Amazon Linux 2 を使う
Amazon Linux から Amazon Linux 2 へのアップグレードを計画しよう | Developers.IO
https://dev.classmethod.jp/articles/planning-al-to-al2/
さらに Amazon Linux 2022 が準備されているとのこと
Fedoraベースで、デフォルトでSELinuxが有効になっているとのこと
Amazon Linux 2022 のプレビューの発表
https://aws.amazon.com/jp/about-aws/whats-new/2021/11/preview-amazon-linux-2022/
[速報]Amazon Linux 2022がやってきた!(プレビュー版) | DevelopersIO
https://dev.classmethod.jp/articles/preview-amazon-linux-2022/
AWS、「Amazon Linux 2022」プレビュー版リリース--「Fedora」ベース - ZDNet Japan
https://japan.zdnet.com/article/35179920/
予定が遅れたので、「Amazon Linux 2023」という名前でリリースされるみたい
Amazon Linux 2023がGAされました | DevelopersIO
https://dev.classmethod.jp/articles/amazon-linux-2023-ga/
■セキュリティ
AWSにおけるセキュリティの考え方
http://www.slideshare.net/morisshi/aws-58223316
Amazon EC2 アクセス制御レシピ
http://dev.classmethod.jp/cloud/aws/ec2-cacess/
「AWS上のセキュリティ対策をどういう順序でやっていけばいいか」という話をしました~Developers.IO 2019 Security登壇資料~ | DevelopersIO
https://dev.classmethod.jp/cloud/aws/how-to-aws-security-with-3rd-party-solutions/
2017年版 AWSの侵入テストについて
http://dev.classmethod.jp/cloud/aws/2017-penetration-testing/
AWS、侵入テスト申請やめるってよ - とある診断員の備忘録
http://tigerszk.hatenablog.com/entry/2019/03/05/190815
AWSでセキュリティを高めるために今すぐやるべき7つのこと (1/2):EnterpriseZine(エンタープライズジン)
https://enterprisezine.jp/article/detail/12536
AWSでのセキュリティ対策全部盛り[初級から中級まで] - Speaker Deck
https://speakerdeck.com/cmusudakeisuke/awstefalsesekiyuriteidui-ce-quan-bu-sheng-ri-chu-ji-karazhong...
AWSアカウントを作成したら最初にやるべきこと -セキュリティ編- - Qiita
https://qiita.com/yanyansk/items/3a989b70d2d3d49eff16
[2020年版]最強のAWS環境セキュリティチェック方法を考えてみた[初心者から上級者まで活用できる] | Developers.IO
https://dev.classmethod.jp/articles/2020-strongest-aws-securitycheck-practice/
[2021年版]AWSセキュリティ対策全部盛り[初級から上級まで] というタイトルでDevelopersIO 2021 Decadeに登壇しました #devio2021 | DevelopersIO
https://dev.classmethod.jp/articles/aws-security-all-in-one-2021/
AWSアカウントを作ったら最初にやるべきこと 〜2021年版〜 #devio2021 | DevelopersIO
https://dev.classmethod.jp/articles/aws-1st-step-2021/
■サポート
技術的なお問い合わせに関するガイドライン
https://aws.amazon.com/jp/premiumsupport/tech-support-guidelines/
■有料サポート
サポートのプラン比較 | 開発者、ビジネス、エンタープライズ | AWS サポート
https://aws.amazon.com/jp/premiumsupport/plans/
20200616 AWS Black Belt Online Seminar AWS サポート技術支援サービス紹介
https://www.slideshare.net/AmazonWebServicesJapan/20200616-aws-black-belt-online-seminar-aws
サポートなしは「ベーシック」で、上位プラントして「デベロッパー」「ビジネス」「エンタープライズ」がある
ざっくりと、以下のように分類される
ベーシック … お試しのためのプラン(無料)
デベロッパー … 開発環境を運用するためのプラン
ビジネス … 本番環境を運用するためのプラン
エンタープライズ … 非常に重要な本番環境を運用するためのプラン
※顧客に提供する環境の場合、原則ビジネスが推奨される
※エンタープライズだと「テクニカルアカウントマネージャー」と呼ばれる専任のエンジニアが付くが、金額も月額150万円以上かかる
あまり手軽に利用できるプランではない
一度サポートに入ったら入り続けないといけない…というものではない
また、一時期だけプランを変えてもいい
ベーシックプランの料金とサポート内容は以下のとおり
・料金は「29 USD/月額」または「月額 AWS 使用料の 3%」の大きい方
・技術的な質問にメールで回答(日本語・回数制限なし)
・平日9時〜18時
・最短12時間で回答
つまり月額料金が10万円以下なら、固定で3,000円程度かかることになる(加入月は日割によって若干価格が下がる)
24時間365日の電話サポートまで求めるなら、さらに上位のプランを選択する
以下は実際に申し込んだときのメモ
コンソールにルートアカウントでログイン
サポートのプラン比較 | 開発者、ビジネス、エンタープライズ | AWS サポート
https://aws.amazon.com/jp/premiumsupport/plans/
にアクセス
「サポートプランの選択」をクリック
「プランの変更」をクリック
「現在のプラン」が「ベーシック」になっていることを確認し、「デベロッパー」に変更して「プランを変更」ボタンをクリック
完了すると以下が表示される
デベロッパー サポートプランへの変更を処理中です。
この変更について、確認メールを送信します。変更が有効になるまで、最大 15 分かかる場合があります。
デベロッパー プランでは、以下の機能が利用できるようになります:
・祝日と週末を除く月曜日から金曜日の地域の営業時間内での、システム障害ケースへの 12 時間以内の応答
・クラウドサポートアソシエイトからの、ウェブ/メールによる技術サポート
・1 人のユーザーが技術サポートケースを作成可能
・アーキテクチャサポート: 一般的なガイダンス
・ベストプラクティスのガイダンス
「サポートセンターに戻る」をクリック
2〜3分程度で、プランが変更されているのを確認できた
また、「Welcome to AWS Developer Support」という件名で以下のメールが届いた
Hello,
Thank you for purchasing Amazon Web Services Support! We are excited to provide you with one-on-one Technical Support services to help your business utilize the products and features provided by Amazon Web Services.
As a subscriber of the Developer-level Support plan you are entitled to the following benefits:
- 12 hour response times during local business hours to cases opened through Web Support in the Support Center (https://aws.amazon.com/support/).
- Basic building block architecture support for all AWS Services
- Access to Best Practices Guides and Client-Side Diagnostic Tools through the Support Center (https://aws.amazon.com/support/)
- 24/7/365 access to Customer Service for billing and account related questions
- Access to the Forums (https://forums.aws.amazon.com/index.jspa), Technical FAQs (http://aws.amazon.com/faqs/), and the Service Health Dashboard (http://status.aws.amazon.com/)
Here are some tips to help you get started with AWS Support:
1. Manage your named contacts (https://aws.amazon.com/support/contacts/). It's best to configure this before you need it to avoid delays.
2. Get to know the Support Center (https://aws.amazon.com/support/). This is your dashboard to create/manage your cases and access other support related content and services.
Please note that you are obligated to pay for a minimum of thirty (30) days of support each time you register to receive the service. If you cancel your subscription within 30 days of sign up you will see a minimum subscription charge on your next bill.
Sincerely,
Amazon Web Services
This message was produced and distributed by Amazon Web Services, Inc. and affiliates, 410 Terry Ave. North, Seattle, WA 98109-5210.
■第三者認証
AWS クラウドコンプライアンス
https://aws.amazon.com/jp/compliance/
責任共有モデル
https://aws.amazon.com/jp/compliance/shared-responsibility-model/
AWSセキュリティ編 今回は第三者認証について詳しくご紹介します。
https://recipe.kc-cloud.jp/archives/5135
■契約
【AWS】アカウント契約の準拠法をワシントン州法から日本法に、管轄裁判所をワシントン州キング群州裁判所から東京裁判所に変更する方法 - Qiita
https://qiita.com/yokoyan/items/2e4cef0728aaf8d2e7d8
AWSの準拠法を日本法に変更する方法 | DevelopersIO
https://dev.classmethod.jp/articles/aws-change-governing-law-to-japan/
■事例
国内のお客様の導入事例 Powered by AWS クラウド
https://aws.amazon.com/jp/solutions/case-studies-jp/
AWS 導入事例:株式会社スクウェア・エニックス
https://aws.amazon.com/jp/solutions/case-studies/square-enix/
AWS 導入事例:任天堂株式会社、株式会社ディー・エヌ・エー
https://aws.amazon.com/jp/solutions/case-studies/nintendo-dena/
AWS 導入事例:株式会社フロム・ソフトウェア | AWS
https://aws.amazon.com/jp/solutions/case-studies/fromsoftware/
[レポート] Fate/Grand Orderにおける、ディライトワークス流AWS導入&活用術
http://dev.classmethod.jp/cloud/aws/fatego/
【レポート】『Fate/Grand Order』事例から学ぶインフラ運用設計…海外展開のために必要な要項についても詳しく紹介
http://gamebiz.jp/?p=188024
三菱UFJのAWS活用、6つのポイントとは (1/2) - ITmedia エンタープライズ
http://www.itmedia.co.jp/enterprise/articles/1706/05/news047.html
FINAL FANTASY XV POCKET EDITION を支える AWS サーバレス技術
https://d1.awsstatic.com/events/jp/2018/summit/tokyo/customer/37.pdf
■インスタンスの種類
T ... 小規模なCPUリソース(バースト機能あり・後述)
M ... バランスのいい、汎用性が高いもの
C ... 性能の高いプロセッサが搭載されている
R ... メモリが多く搭載されている
G ... GPUが搭載されている
H, I ... ストレージが最適化されている
※Tは主に、開発環境やマイクロサービスを想定しているみたい
ただし他はmicroやsmallが提供されていない場合があるので、特性を理解したうえで一般的な本番環境に使うのは問題無い
Amazon EC2 インスタンスタイプの選び方ガイド
https://pages.awscloud.com/rs/112-TZM-766/images/C2-07.pdf
【AWS初心者向け】EC2のインスタンスタイプの選び方|コラム|NURO Biz(ニューロ・ビズ)
https://biz.nuro.jp/column/aws-mama-022/
■Tのバースト機能
※t2サーバやt3などT系を使っている場合、CPUクレジットの枯渇により突然負荷が上がることがあるので注意
クレジットは時間とともに回復し、高性能なインスタンスほど回復が早い
T2 インスタンス
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/t2-instances.html
CPU クレジット - T2 インスタンス - Amazon Elastic Compute Cloud
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/t2-instances.html#t2-instances-cpu-credits
解説より
従来の Amazon EC2 インスタンスタイプはパフォーマンスが一定ですが、
T2 インスタンスはベースラインレベルの CPU パフォーマンスを提供しながら、
そのベースラインレベルを超えてバーストする機能を備えています。
ベースラインパフォーマンスとバースト機能は、CPU クレジットにより管理されます。
EC2インスタンス(T2)のCPUクレジットと落とし穴
http://www.fridles.xyz/articles/4
解説より
1つのvCPUがCPU使用率100%の状態を1分間続けると、CPUクレジットが1減ります。
1つのvCPUでCPU使用率50%の状態を2分続けると、CPUクレジットが1減ります。
クレジットの回復については、インスタンスタイプによって変わります。t2.smallであれば、1時間で12回復します。
CPUクレジットには有効期限があり、それは24時間です。つまり、回復したクレジットを24時間以内に消費しないと自動で失効してしまうのです。
■T3インスタンス
まだリリースされたばかりだが検証したい
t2よりもt3の方が若干高性能で、かつ料金は若干安いらしい
t2と同じくCPUバースト機能があり、最大5Gbitのネットワークバースト機能もある
【速報】T3インスタンスがリリースされました! | Developers.IO
https://dev.classmethod.jp/cloud/aws/t3-instance/
T3インスタンスの性能をWordPress環境で確認してみた | Developers.IO
https://dev.classmethod.jp/cloud/aws/comparison-wordpress-t3-t2/
ただし t3.micro の2台目を起動しようとしたら「申請してください」の旨のエラーが表示された
t2 よりも台数制限が厳しいのかも?
その他、単純に「t3 は t2 の上位版」というものでは無いようなので注意。急ぎで構築するならしばらくは t2 を使う方が無難か
EC2の新しいT3インスタンスの注意点? - Qiita
https://qiita.com/hayao_k/items/0beb46b15e01903eecf2
■ELB
ELBは負荷状況に応じて動的に規模が変化する。具体的にはELBインスタンスの数や性能が変化する。
どのタイミングで変化するか明確な判断基準は無いみたい。
アクセス数が一気に増えることが予想されるコンテンツなら、あらかじめPre-warmingでスケールさせる。
金額も、スケーリングされる想定で算出する。
「はじめからELBは2つ使われるものとする」
など。
■回線帯域
AWSでは回線帯域を保証するサービスはないみたい
外部ネットワークとの接続に関しては「いくつかのインスタンス・タイプでI/O性能のベンチマーク試験を実施していただいた上で、最適なタイプをご利用いただければと存じます」らしい。iperfを使うなどして、実際にベンチマーク試験を行う
内部ネットワークに関しては「10Gbpsで相互に接続されており、300Mbpsの帯域幅は容易に確保していただけるかと存じます」らしい
https://forums.aws.amazon.com/message.jspa?messageID=225715
[EC2] m4インスタンスのネットワーク性能を測定してみた(win2012)
http://dev.classmethod.jp/cloud/aws/m4-ec2-win2012-iperf/
■アクセスキー
PHPからS3を操作する場合など、「Access Key ID」と「Secret Access Key」を発行して使用する
権限によってはEC2の作成などもでき、流出すると不正に使用されてしまう
(踏み台用にサーバを立てられたり、大量のインスタンスを立てられてAWSからの請求がすごいことになったり)
GitHubなどにソースコードを登録する際、アクセスキーを含めないように注意する
GitHub に AWS キーペアを上げると抜かれるってほんと???試してみよー! - Qiita
https://qiita.com/saitotak/items/813ac6c2057ac64d5fef
爾爾(ジジ)さんはTwitterを使っています 「AWSの不正請求、300万払えとかマ!? 元が1000万円だからだいぶ減ってるとはいえ相当辛い
https://t.co/cSasxS4Jx3」 / Twitter
https://twitter.com/jiji_0222/status/1495416224398086151
■素材
AWS シンプルアイコン - AWS アーキテクチャーセンター | AWS
https://aws.amazon.com/jp/architecture/icons/
AWS Architecture Icons、新しいAWS製品アイコンがリリースされました | DevelopersIO
https://dev.classmethod.jp/cloud/aws/aws-architecture-icons-2018/
■AWS認定ソリューションアーキテクトアソシエイト
AWSの資格試験
【未経験でも挫折しない】40時間でAWS認定ソリューションアーキテクトアソシエイトを取得する方法 - Qiita
https://qiita.com/rexiaxm7/items/c5b361ce14c55c19b13a
AWS SAA/SAP資格 予想問題集 Web版 | 日本語完全無料
https://awsjp.com/exam/saa-sap/c/
3週間でAWS認定ソリューションアーキテクト-アソシエイト-とったので、勉強法などまとめてみる - Qiita
https://qiita.com/fukubaka0825/items/238225f9e4c1962bc00c
15日間勉強してAWS ソリューションアーキテクト アソシエイト試験に合格した - My External Storage
https://budougumi0617.github.io/2019/05/12/pass-aws-solution-architect-associate/
■AWSアカウントの管理
・案件ごとにアカウントを作成することを推奨
複数の案件を一つのアカウントで管理する場合、各サービスの上限値に注意する
・さらに案件の「開発アカウント」「検収環境アカウント」「本番環境アカウント」に分けるのも有効そう
ただしそこまで分けると請求管理などが大変なので、AWS Organizationsの利用を検討する
AWS Organizationsの詳細は、後述の「AWS Organizations」の項目を参照
AWSアカウントはなぜ&どう分けるべき? - NRIネットコムBlog
https://tech.nri-net.com/entry/why_multi_accounts
組織におけるAWSのアカウント管理とコスト管理 - Speaker Deck
https://speakerdeck.com/sumi/zu-zhi-niokeruawsfalseakauntoguan-li-tokosutoguan-li
■AWSに登録
※住所や会社名は英語で入力する必要がある。日本語で入力するとエラーになるので気づくことはできる
手順中に本人確認の認証があるが、Softbankの携帯番号でSMS認証して大丈夫だった
※アカウント作成の時点でクレジットカードが必要になる
※メール送信のための制限緩和申請は、クレジットカードでの実際の支払いが発生するまでは非常に厳しい可能性がある
それ以外の申請も予期せず時間がかかる可能性があるので、アカウント開設とサーバ構築作業は早めに行っておく
AWS
http://aws.amazon.com/jp/
アカウントの作成&作成の流れ
http://aws.amazon.com/jp/register-flow/
コンソール
https://console.aws.amazon.com/console/home
※アカウント作成直後は、デフォルトではオハイオにインスタンスが作られる
作業を始めるときは、東京リージョン(もしくは使用したいリージョン)に切り替えてから行う必要があるので注意
以下、アカウントを新規作成したときの作業メモ
登録内容はあくまでも一例なので、必要に応じて変更する
□AWSにサインアップ
ルートユーザーのEメールアドレス: (複数のAWSアカウントを持つ可能性があるので、専用にメールアドレスを作成しておくといい)
AWSアカウント名: (案件内容を把握できる任意の文字列を半角英数字で)
rootユーザーパスワード: (任意の文字列)
※AWSアカウント名は後から変更できる
一般的な名前だと重複することがあるので、「refirio-project」など接尾語を付けるなどするといいかも
「続行」ボタンをクリック
□連絡先情報
AWS はどのように使用されますか?: ビジネス(法人でアカウントを作成する場合)
フルネーム: (AWSアカウント名と同じ値が初期値になるので、特に理由がなければそのままでいい)
組織名: (会社名を英語で)
電話番号: (会社電話番号)
国または地域コード: 日本
住所: (会社住所を英語で)
市区町村: (会社市区町村を英語で)
州/都道府県または地域: (会社都道府県を英語で)
郵便番号: (会社電郵便番号)
「アカウントを作成して実行」ボタンをクリック
□支払情報
クレジットカード情報を入力
「請求先住所」は「連絡先住所を使用する」のまま
「確認して次へ」ボタンをクリック
□本人確認
検証コードの受け取り方法: テキストメッセージ (SMS)
国またはリージョンコード: 日本(+81)
携帯電話番号: 有効な番号を入力する
「SMSを送信する」ボタンをクリック
携帯電話番号にコードが届くので入力する
「続行」ボタンをクリック
□サポートプランの選択
無料のベーシックプランを選択
「サインアップを完了」ボタンをクリック
「コンソールにサインイン」ボタンからサインインを試す
■AWSの初期設定
■IAMユーザの作成
IAM(Identity and Access Management)とはAWSにおける個別のユーザアカウント
AWS登録直後はルートアカウントのみだが、アカウントの削除や権限の剥奪ができるように、原則としてIAMアカウントを使う
二段階認証も設定することを推奨するが、以下のような事態には注意
AWSのMFA用デバイスを紛失してサービス停止しそうになった話 - Qiita
https://qiita.com/takano-h/items/f33e9a8a0350a5938e81
AWSのMFAを解除するためにアメリカ大使館に足を運んだ話 - Qiita
http://qiita.com/kechol/items/9de7bbc607b5c608c77b
以下は実際に作業用ユーザを作成したときのメモ
画面右上のアカウント名 → セキュリティ認証情報 → ユーザー → ユーザーを追加
ユーザー名: refirio-user
アクセスの種類: AWS マネジメントコンソールへのアクセス
コンソールのパスワード: (案件に合わせて選択)
パスワードのリセットが必要: (案件に合わせて選択)
「次のステップ: アクセス権限」をクリック
既存のポリシーを直接アタッチ → AdministratorAccess
にチェックを入れて「次のステップ: タグ」をクリック
次の画面で必要に応じてタグを設定して「次のステップ: 確認」をクリック(いったんタグは設定せずで大丈夫)
確認画面が表示されるので、内容を確認して「ユーザーの作成」をクリック
認証情報をCSVでダウンロードできるので、手元にダウンロードしておく。「閉じる」をクリックして完了
※「AdministratorAccess」でコンソールからひととおりの操作ができるが、
「マイアカウント」「マイ請求ダッシュボード」など一部の情報にはアクセスできなくなる
■IAMユーザの作成(より操作が限定されたユーザを作る場合の例)
S3のみ操作できるユーザを作成してみる
画面右上のアカウント名 → セキュリティ認証情報 → ユーザー → ユーザーを追加
ユーザー名: s3-user
アクセスの種類: AWS マネジメントコンソールへのアクセス
コンソールのパスワード: (案件に合わせて選択)
パスワードのリセットが必要: (案件に合わせて選択)
「次のステップ: アクセス権限」をクリック
既存のポリシーを直接アタッチ → AmazonS3FullAccess
にチェックを入れて「次のステップ: タグ」をクリック
次の画面で必要に応じてタグを設定して「次のステップ: 確認」をクリック(いったんタグは設定せずで大丈夫)
確認画面が表示されるので、内容を確認して「ユーザーの作成」をクリック
認証情報をCSVでダウンロードできるので、手元にダウンロードしておく。「閉じる」をクリックして完了
これでS3のみ操作できるアカウントとなる
AWSコンソールにログインして確認すると、EC2やRDSなどメニューには表示されるが、
「取得中にエラーが発生しました」「取得に失敗しました」
などのエラーになる
■IAMユーザの作成(部分的に管理を委譲する)
※未検証
AWS IAMの属人的な管理からの脱却【DeNA TechCon 2021】/techcon2021-19 - Speaker Deck
https://speakerdeck.com/dena_tech/techcon2021-19
■サインインリンクのカスタマイズ
作成したユーザは以下のようなURLから認証できる
https://123456789012.signin.aws.amazon.com/console
これでも問題ないが、カスタマイズして以下のようなURLから認証できるようにする
複数の案件でアカウントを管理している場合、URLからどの案件なのか直感的に把握できるようになる
https://refirio.signin.aws.amazon.com/console
IAM → AWSアカウント → アカウントエイリアス → 作成
から優先エイリアスを登録でき、ここで登録した文字列が先頭の数字部分に反映される
基本的にAWSアカウント名と同じにしておくと、余計な混乱がなくていい
■CloudTrail
AWS CloudTrail(ユーザーアクティビティと API 使用状況の追跡)| AWS
https://aws.amazon.com/jp/cloudtrail/
AWSの操作はコンソール・CLI・SDKなどを問わず、すべてAPIを通じて行われる
そのためAPIの操作を監視しておけば、AWSにどのような方法で操作が行われても記録できる
これを自動で行ってくれる
CloudTrail → 証跡の作成
認証名: management-events(初期値のまま)
ストレージの場所 S3バケット: (初期値のまま)
「証跡の作成」ボタンを押すと、S3にバケットが作成されて操作が記録されるようになるみたい
AWS管理コンソールの不正ログインをCloudTrail と CloudWatch Logsで検知する
http://dev.classmethod.jp/cloud/aws/aws-cloudtrail-cloudwatch-logs-badip/
2017年8月から、CloudTrailがすべてのユーザーで自動的に7日間保管され、追跡できるようになった
…とあるが、最初に「証跡の作成」は行っておくと良さそう
CloudTrail が自動有効化されるようになったのに合わせて、設定方法を改めて眺めてみる - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2017/08/15/cloud-trail-all-customers/
■GuardDuty
Amazon GuardDuty(マネージド型脅威検出サービス)| AWS
https://aws.amazon.com/jp/guardduty/
料金 - Amazon GuardDuty | AWS
https://aws.amazon.com/jp/guardduty/pricing/
【全員必須】GuardDutyがコスパ最強の脅威検知サービスであることを証明してみた | DevelopersIO
https://dev.classmethod.jp/articles/guardduty-si-strongest-thread-detection/
AWS利用料金の1〜2%程度で利用できるみたい
いったん30日の無料トライアルで、自身のアカウントだと実際にどれくらいかかるかを試すといい
GuardDuty → 今すぐ始める → GuardDutyの有効化
有効化すると、結果一覧に「結果がありません。」と表示された
結果が表示されるまでには、少し時間がかかるみたい
以下、結果が表示されるまでのメモ
・2022/05/09時点で有効にした
・2022/05/23時点で
「GuardDuty → 検出結果」を確認すると、「結果がありません。GuardDuty は継続的に AWS 環境を監視し、結果をこのページで報告します。」となっていた
「GuardDuty → 使用状況」を確認すると、$0.27となっていた
・2022/06/01時点で
「GuardDuty → 検出結果」を確認すると、「Policy:IAMUser/RootCredentialUsage」が表示されていた。重要度は「低い」となっている
「GuardDuty → 使用状況」を確認すると、$0.27となっていた。ただし「1日あたりの合計推定コスト」になっている。以前からこの表記だったか
これは、ルートアカウントの利用が検知されているみたい
※2022/06/07時点で
「GuardDuty → 検出結果」を確認すると、「Policy:IAMUser/RootCredentialUsage」「Recon:EC2/PortProbeUnprotectedPort」が表示されていた。重要度は「低い」となっている
さらに「Discovery:S3/TorIPCaller」も表示されていた。重要度は「高い」となっている
「GuardDuty → 使用状況」を確認すると、$0.04となっていた
GuardDutyでルートアカウントの利用を検知する | DevelopersIO
https://dev.classmethod.jp/articles/guardduty-rootaccount/
コストは低いので有効化のままでいいかもしれないが、警告を自動で通知するような仕組みが必要か
Security Hubなどと組み合わせる前提となるか
■Macie
Amazon Macie(機械学習による機密データの検出、分類、保護)| AWS
https://aws.amazon.com/jp/macie/
「メイシー」と読む
S3のパケットが公開されていないか、パケットへのアクセス権限がどうなっているか
など、S3の問題点を出してくれる
オンにするだけでレポートを出してくれる
個人情報を持っているバケットがあるなら使うといいみたい
■Config
現状の構成のスナップショットを取り、構成がどのように変更されたかを確認できる
ただし少々高額なので注意
Config → Get started
Step1 Settings: デフォルト値のまま「Next」
Step2 Rules: デフォルト値のまま「Next」
Step3 Review: 内容を確認して「Confirm」
以降、例えばセキュリティグループの設定を変更した場合などは、変更内容が記録されるようになるみたい
AWS Configはとりあえず有効にしよう
http://dev.classmethod.jp/cloud/aws/aws-config-start/
■Security Hub
AWS Security Hub(統合されたセキュリティ & コンプライアンスセンター)| AWS
https://aws.amazon.com/jp/security-hub/
料金 - AWS Security Hub | AWS
https://aws.amazon.com/jp/security-hub/pricing/
AWS Security Hub を有効にすると AWS Config の利用料が倍増した話 - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/security-hub-increases-aws-config-cost
AWS Security Hubで情報を集約!セキュリティ情報は一元管理する時代へ - ジード
https://www.zead.co.jp/column/securityhub/
利用料金が高額になることがあるみたいなので、注意が必要みたい
ConfigやGuardDutyなどを、別々に確認するのは大変なので、AWS Security Hubを使うといいらしい
一つ一つログを見るのではなく、リスクの高いものからリストアップされるので、順番につぶしていけるらしい
セキュリティベストプラクティスをどれくらい満たしているかも表示してくれるので、目安にはなる
■作業リージョンの選択
作業リージョンが「米国東部(バージニア北部)」になっているので、「アジアパシフィック(東京)」に変更しておく
■キーペアの作成
EC2 → キーペア → キーペアを作成
今回はキーペア名に「refirio」と入力し、作成
ファイルの形式は「pem」でいいが、必要に応じて変更する
※AWSのアカウントを複数持つ可能性があるので、単に「AWS」や「EC2」という名前にしない方がいい
よって「refirio-production」のような名前で作ると良さそう(案件名+環境名)
■アカウント作成後の大まかな作業内容
※備忘録にメモ
・ルートユーザとは別にコンソールの作業用ユーザを作成
・サインインリンクのカスタマイズ
・CloudTrailを有効化(現在はデフォルトで有効化されている)
・GuardDutyを有効化(しておくと良さそうだが、詳細は引き続き要確認)
・Configを有効化(しておくと良さそうだが、少々高額なので注意)
・Security Hubを有効化(しておくと良さそうだが、まだ試したことは無い)
・VPCを作成
・EC2の構築とElasticIPの割当
・RDSやなどを構築
・CloudWatch や CloudWatch Logs など監視を設定
・メール上限緩和&逆引き(rDNS)設定の申請(SESが使える案件ならSESを使う方がいい。その場合SESに関する利用申請を行う)
以下を参考に、他に必要な作業があれば実施したい(要調査)
AWSアカウントを作ったら最初にやるべきこと 〜令和元年版〜 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/aws-1st-step-new-era-reiwa/
AWS アカウントの初期設定 - それ積んどく?
https://jigoku1119.hatenablog.jp/entry/2021/06/28/163810
■VPC
※仮想ネットワーク(Virtual Private Cloud)を構築できる(リージョンに対して作成)
※後からの構成変更は大変なので、最初によく検討してから構築する
以前は一度作ったものは一切変更できなかったが、今は条件付きで後から拡張できるようになっているみたい(未検証)
Amazon VPCを「これでもか!」というくらい丁寧に解説 - Qiita
https://qiita.com/c60evaporator/items/2f24d4796202e8b06a77
フロントエンドエンジニアですが、AWS 始めてみます
http://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/
カジュアルにVPC作った結果がこれだよ!
http://www.slideshare.net/Yuryu/aws-casual-talks-1-vpc
[新機能] VPCのCIDRが拡張可能になりました!IPアドレス範囲を追加可能です! | Developers.IO
https://dev.classmethod.jp/articles/expanding-vpc-cidr/
Amazon VPCを使ったミニマム構成のサーバ環境を構築する
http://dev.classmethod.jp/cloud/aws/minimum-amazon-vpc-server-environment/
VPC とサブネット
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Subnets.html
デフォルト VPC とデフォルトサブネット
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/default-vpc.html
Amazon VPC設計時に気をつけたい基本の5のこと
https://dev.classmethod.jp/cloud/aws/amazon-vpc-5-tips/
AWSのAZの割り当ては、アカウントごとに違うという話 - プログラマでありたい
https://blog.takuros.net/entry/2019/08/26/090220
■リージョンとアベイラビリティゾーンとサブネット
リージョン内にVPC(仮想ネットワーク)を作成し、
その中にサブネット(サブネットワーク)を作成し、
その中にアベイラビリティゾーンを作成し、
その中でサーバの設置などを行う
作業前に、対象が「東京リージョン」であることを確認する(意図的なら他のリージョンで作業するのも問題ない)
2021年3月に、大阪リージョンが追加された。これにより、日本国内のみでマルチリージョンを実現できる
AWS 大阪リージョン - 2021年3月 誕生! | AWS (アマゾン ウェブ サービス)
https://aws.amazon.com/jp/local/osaka-region/
東京リージョンに新たにアベイラビリティゾーンを追加
https://aws.amazon.com/jp/blogs/news/the-fourth-new-availability-zone-tokyo-region/
なお、複数のアベイラビリティゾーンにサーバを配置する構成を「マルチAZ」と呼ぶ
基本的にマルチAZ構成にしておくことが推奨される
■料金
VPC自体は無料で利用できる
よくある質問 - Amazon VPC | AWS
https://aws.amazon.com/jp/vpc/faqs/
「VPC 自体の作成・使用には追加料金はかかりません。
Amazon EC2 などの他のアマゾン ウェブ サービスの利用料金が、データ転送料金を含めこれらのリソースに指定レートで適用されます。」
AWS VPCの料金 | TechCrowd
https://www.techcrowd.jp/datalink/fee-2/
VPC自体は無料で、VPNやNATを使う場合には利用可能時間をもとに課金されるとのこと。(公式のスライドあり。)
■プライベートIPアドレスの範囲
プライベートIPアドレスには
10.0.0.0 〜 10.255.255.255 ... 大規模ネットワーク向け
172.16.0.0 〜 172.32.255.255 ... 中規模ネットワーク向け
192.168.0.0 〜 192.168.255.255 ... 小規模ネットワーク向け
が使える
ただし 192.168.0.1 など、AWS側で予約されていて使えないアドレスがあるので注意
127.0.0.1 〜 127.0.0.254 はローカルループバックアドレス(自分自身を表す)なので、これも使えない
ネットワーク内のIPアドレス
http://www.pc-master.jp/internet/private-ip-address.html
AWSのVPCの予約IPについての勘違い
https://www.infoscoop.org/blogjp/2015/09/11/awsip/
Amazon VPC IPアドレス設計レシピ
http://dev.classmethod.jp/cloud/aws/vpc-cidr/
0から始めるVPC
https://www.slideshare.net/classmethod/0vpc
※デフォルトVPCのプライベートIPアドレスは 172.31.0.0 になっている
※自分でVPCを作る場合、可能なかぎり大きなサイズで作っておくのが無難
具体的には 10.0.0.0/16 で作っておくといい
■ネットワーク構成例
一般的なものとして、以下のような構成がある
基本的には「1」の構成をもとにすればいい
「2」の構成にするが、「4」に変更することを想定して「Public」「Protected」の2階層にする…というのも有効(むしろ1よりも柔軟でいいかも)
本来Trusted(Private)に置くべきサーバでも、監視のためにDMZ(Public)に置いたりすることはある
その場合、セキュリティグループなどでアクセス制限を行う
1
DMZ ... Webサーバなど配置用
Trusted ... DBサーバなど配置用
2
Public ... Webサーバなど配置用
Private ... DBサーバなど配置用
3
DMZ ... Webサーバなど配置用
Operation ... 踏み台サーバ、デプロイサーバ、バッチサーバなど配置用
Trusted ... DBサーバなど配置用
4
Public ... Webサーバなど配置用
Protected ... DBサーバなど配置用
Private ... 外部と通信させない領域
5
Frontend ... ロードバランサー、直接公開のWebサーバなど配置用
Application ... ロードバランサー配下のWebサーバ、バッチサーバなど配置用
Datastore ... DBサーバなど配置用
【AWS】VPC環境の作成ノウハウをまとめた社内向け資料を公開してみる | Developers.IO
https://dev.classmethod.jp/server-side/network/vpc-knowhow/
ネットワークやサーバなどを作成する際、名前タグを付けることができる
適当に付けても動作上は問題ないが、最初にルールを決めて名前を付けておくといい
以降の解説では例えばVPCの名前タグは「Develop-VPC」としているが、これはあくまでも一例
「xxsystem-dev-vpc」のように「案件名-環境-vpc」と付けるなども有効
弊社で使っているAWSリソースの命名規則を紹介します | DevelopersIO
https://dev.classmethod.jp/cloud/aws/aws-name-rule/
■VPCの作成
AWS → VPC → VPC(左メニュー) → VPCの作成
名前タグ : Develop-VPC
IPv4 CIDR ブロック : 10.0.0.0/16
IPv6 CIDR ブロック : IPv6 CIDR ブロックなし
テナンシー : デフォルト
と設定して作成
2つ目を作成する場合でも、IPv4 CIDR blockは常に 10.0.0.0/16 でいい
(後に記載するサブネットのように、10.1.0.0/16 とずらす必要は無い)
■サブネットの作成
サブネット(左メニュー) → サブネットの作成
名前タグ VPC アベイラビリティゾーン IPv4 CIDR ブロック
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Develop-DMZ-A Develop-VPC ap-northeast-1a 10.0.0.0/24
Develop-DMZ-C Develop-VPC ap-northeast-1c 10.0.1.0/24
Develop-Trusted-A Develop-VPC ap-northeast-1a 10.0.2.0/24
Develop-Trusted-C Develop-VPC ap-northeast-1c 10.0.3.0/24
と設定して作成
※サーバが3台以上の構成だとしても、2つずつの作成でいい(東京リージョンにAZは2つしかないため。…だったが、後ほど追加された。それでも基本的に2つずつの作成でいい)
作成したサブネットに、自動作成されたルートテーブルが割り当てられていることを確認する
※1つのサブネットには1つのルートテーブルのみ、関連付けることができる
自動作成されたルートテーブルはインターネットゲートウェイを考慮したものではないので、以降で
「インターネットゲートウェイとルートテーブルを作成する。ルートテーブルにインターネットゲートウェイを登録する。そのルートテーブルをサブネットに関連付ける」
とする
※インターネットゲートウェイは、VPCをインターネットに接続する仮想ルーター
※ルートテーブルは、個々のネットワークの宛先への経路一覧を保持しているもの
■インターネットゲートウェイ(仮想ルーター)の作成
インターネットゲートウェイ(左メニュー) → インターネットゲートウェイの作成
名前タグ : Develop-Gateway
と設定して作成
作成したものを選択して「VPCにアタッチ」を押し、先ほど作成したVPC「Develop-VPC」を選択して「アタッチ」
■ルートテーブルの作成
ルートテーブル(左メニュー) → ルートテーブルの作成
名前タグ : Develop-Route
VPC : Develop-VPC
と設定して作成
作成したルートテーブルを選択し、下のタブから「ルート」を選択し、「編集」ボタンを押し、「別ルートの追加」ボタンを押す
送信先 : 0.0.0.0/0
ターゲット : 先ほど作成したインターネットゲートウェイ
と設定して保存
サブネット(左メニュー)
先の手順で作成したサブネットを選択し、下のタブから「ルートテーブル」を選択し、「ルートテーブルの変更」ボタンを押す
「ルートテーブル ID」を先ほど作成したルートテーブルに選択し、下の一覧に追加されたのを確認して「保存」ボタンを押す
インターネット接続を許可したいサブネットすべてに対し、同じ操作を行う
※「すべての宛先(0.0.0.0/0)をインターネットゲートウェイに流す」という設定のルートテーブルを作成したことになる
※ルートテーブルは、インターネット接続を許可したいサブネットすべてに対し設定する。今回は Develop-DMZ-A, Develop-DMZ-C のみ
■セキュリティグループの作成
※セキュリティグループ=ファイヤーウォール。サーバ一台ごとではなく、グループ単位でファイヤーウォールを設定できる
※セキュリティグループ「default」は編集せずに、Webサーバ用やDBサーバ用に新規作成する
セキュリティグループ(左メニュー) → 「セキュリティグループの作成」
名前タグ : Develop-SSH
グループ名 : ssh
説明 : for develop ssh
VPC : Develop-VPC
と設定して作成
グループ名は、デフォルトのセキュリティグループで「default」という名前が付いているので、小文字の英数字で概要を一言で書けば良さそう
説明は、デフォルトのセキュリティグループで「default VPC security group」と設定されているので、英語で概要を書けば良さそう
作成したセキュリティグループを選択し、下のタブから「インバウンドルール」を選択し、「編集」ボタンを押す
タイプ プロトコル ポート範囲 送信元
SSH(22) TPC(6) 22 203.0.113.9/32
… アクセス元のIPアドレス
カスタムTPCルール TPC(6) 10022 203.0.113.9/32
… アクセス元のIPアドレス
と設定して保存。(ただし22番ポートは後ほど塞ぐ)
同様にして以下も作成する。
名前タグ : Develop-Web
グループ名 : web
説明 : for develop web
VPC : Develop-VPC
タイプ プロトコル ポート範囲 送信元
HTTP(80) TPC(6) 80 0.0.0.0/0
… すべてのIPアドレス
HTTP(443) TPC(6) 443 0.0.0.0/0
名前タグ : Develop-Cache
グループ名 : cache
説明 : for develop cache
VPC : Develop-VPC
タイプ プロトコル ポート範囲 送信元
カスタムTPCルール TPC(6) 11211 0.0.0.0/0
名前タグ : Develop-DB
グループ名 : db
説明 : for develop db
VPC : Develop-VPC
タイプ プロトコル ポート範囲 送信元
MySQL/Aurora(3306) TPC(6) 3306 0.0.0.0/0
■パブリックDNSを割り当てるための設定
AWSでPublic DNS(パブリックDNS)が割り当てられない時の解決法
http://qiita.com/sunadoridotnet/items/4ea689ce9f206e78a523
対象のVPCを選択し、「概要」で「DNS 解決」と「DNS ホスト名」を確認する
デフォルトでは
DNS 解決: はい
DNS ホスト名: いいえ
このようになっているが、この設定ではパブリックDNSは割り当てられない
以下の手順で両方とも「はい」にする
(対象のVPCを選択) → アクション → DNS解決の編集
(対象のVPCを選択) → アクション → DNSホスト名の編集
■RDSからVPCを利用するための設定
AWS → RDS → サブネットグループ → DBサブネットグループの作成
名前 : Develop-DB
説明 : for develop.
VPC ID : Develop-VPC
と入力。さらに
アベイラビリティーゾーン : サブネットを作成したAZ
サブネット ID : DB用に作成したサブネット
を追加し、さらに
アベイラビリティーゾーン : サブネットを作成したAZ(上とは別のAZ)
サブネット ID : DB用に作成したサブネット(上とは別のサブネット)
を追加し、「作成」ボタンを押す
■ElastiCacheからVPCを利用するための設定
Laravelのセッション管理にRedisを指定し、AWSのElastiCacheを利用する - 商売力開発ブログ
https://www.prj-alpha.biz/entry/2018/05/06/230232
AWS → ElastiCache → サブネットグループ → Cacheサブネットグループの作成
名前 : Develop-Cache
説明 : for develop.
VPC ID : Develop-VPC
と入力。さらに
アベイラビリティーゾーン : サブネットを作成したAZ
サブネット ID : DB用に作成したサブネット
を追加し、さらに
アベイラビリティーゾーン : サブネットを作成したAZ(上とは別のAZ)
サブネット ID : DB用に作成したサブネット(上とは別のサブネット)
を追加し、「作成」ボタンを押す
■VPCのトラフィックログを取得する
【新機能】VPC Flow LogsでVPC内のIPトラフィックを監視することができるようになりました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/introduce-to-vpc-flow-log/
VPC Flow Logsの出力先にS3が追加になって安価に使いやすくなりました | DevelopersIO
https://dev.classmethod.jp/cloud/aws/vpcflowlogs_to_s3/
【AWS】VPCフローログを使ってみた - Qiita
https://qiita.com/noskilluser/items/a8db20c9d614c0f3096e
■EC2
※汎用的なサーバを作成できる
EC2 → インスタンス → インスタンスを起動
名前: 「Develop-Web1」など自分で判別しやすい名前を付ける
Amazon マシンイメージ (AMI): Amazon Linux 2 AMI
インスタンスタイプ: t2.micro
キーペア名: 予め作成したキーペア
ネットワーク: 必要に応じて選択する
サブネット: 必要に応じて選択する
パブリックIPの自動割り当て: 有効化
ファイアウォール (セキュリティグループ): 予め作成したセキュリティグループ
ストレージ: 8GiB
※「キーペア名」について
キーペアはSSHアクセスの際などに使用する
新規に作成してもいいし、既存のものがあれば選択してもいい
※「パブリックIPの自動割り当て」について
「有効化」にすると、インスタンスが停止または削除されるまでのIPアドレスが割り当てられる。「無効化」にすると、IPアドレスが割り当てられない
外部からの直接アクセスが不要な場合、「無効」でいい
自動割り当てされたIPアドレスは、EC2を再起動しても変わらない。いったん停止させてから再度開始すると変わる。変わるのはIPアドレスだけなので、基本的にはSSHやHTTPの接続先さえ変えれば問題ない。固定IPが必要な場合、ElasticIPを使う
内部での通信なら、プライベートIPで通信できる。例えばPHPでHTTPリクエストを行う場合でも「file_get_contents('http://10.0.0.1/')」のように指定できる。プライベートIPは、停止させても変化しないみたい
「インスタンスを起動」ボタンをクリック
インスタンスが作成されるまで数分待つ
Amazon EC2の使い方【SSHまで全部GUIでできます!】
http://www.synaesthesia.jp/amazon/ec2/introduction.php
PoderosaをつかってAmazonEC2に接続
http://saifis.net/?p=116
EC2へpoderosaからログイン
http://xoxo-infra.hatenablog.com/entry/2013/02/09/061305
0から始めるAWS入門:VPC編
http://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b
EC2 Amazon Linux を立ち上げた時にする初期設定
http://qiita.com/shojimotio/items/79264678e9ea10b6fd19
■固定IPの取得&インスタンスに割り当て(固定IPが必要な場合)
※固定IPを割り当てなくても、インスタンスを停止させなければIPは変わらない
固定IPの上限はデフォルトで5つなので、割り当てるのは踏み台サーバやメールサーバなど限定的にする方がいいかもしれない
※Elastic IP による固定IPについては「Elastic IPs」の項目も参照
EC2 → Elastic IP → Elastic IPを割り当てる
基本的には特に何も変更せず、「割り当て」ボタンを押せばいい
一覧画面に遷移し、IPアドレスが割り当てられたことを確認できる
一覧から、作成したIPアドレスを選択 → アクション → Elastic IP アドレスの関連付け
作成したインスタンスを選択し、「関連付ける」ボタンを押す
■EC2へSSH経由でアクセス
※Poderosaなど、任意のSSHクライアントでアクセスできる
接続先:203.0.113.1(割り当てた固定IP。インスタンスの情報で「IPv4パブリックIP」として確認できる)
ユーザ名:ec2-user
ポート:22
鍵:作成したキーペア(pemファイル)
接続できない場合、一般的なSSH接続の確認事項に加えて
「EC2を外部からアクセスできるサブネットに配置したか」
「セキュリティグループでIP制限されていないか」
「正しいキーペアを使用しているか」
なども確認する
$ sudo passwd
でrootのパスワードを設定する
これで、
$ su -
でrootになれる。rootのパスワードを設定せずに、「sudo su -」でrootになることもできる
Amazon Linux AMI の root パスワード (Amazon EC2)
http://whatpgcando.blogspot.jp/2011/03/amazon-linux-ami-root-amazon-ec2.html
■Webサーバとして最低限の設定例
とりあえずWebサーバとして使えるようにし、ec2-userがSFTPでファイルアップロードできるようにする設定
あらかじめセキュリティグループで、22番ポートと80番ポートのアクセスを許可しておく
・「sudo su -」でrootになる
・必要に応じて日本語設定にしておく
・必要に応じてホスト名を設定しておく(デフォルトでは「ip-10-1-0-87」のようなホスト名。このままでもいい)
・必要に応じてタイムゾーンを設定しておく
・Apacheの場合、以下を設定(PHP5.6を使うならApacheは2.4をインストールする。詳細は Programming.txt を参照)
# yum -y install httpd
# vi /etc/httpd/conf/httpd.conf
#ServerName www.example.com:80
ServerName ip-10-0-0-1 … 任意の名前。仮で設定するならホスト名と同じにしておくなど
# service httpd start
# chkconfig httpd on
# usermod -a -G apache ec2-user
・nginxの場合、以下を設定
# amazon-linux-extras list
# amazon-linux-extras install nginx1 -y
# systemctl start nginx
# systemctl enable nginx
# usermod -a -G nginx ec2-user
■認証時のエラーログが記録されないようにする
/var/log/secure に以下のようなログが記録される
Sep 29 18:41:44 ip-10-1-0-11 sshd[24291]: error: AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys ec2-user SHA256:Xguv+wrJDpeOE0ou3wl22w++aUwns0ZpRpPjDLHndvc failed, status 22
動作上は問題ないようだが、監視システムなどで異常として検知される可能性はある
これは、sshd_config を編集することで記録されないようにできる
EC2でsecureログにerror: AuthorizedKeysCommandが出力されるようになった - Qiita
https://qiita.com/comefigo/items/e500dc53217b8b55260e
# vi /etc/ssh/sshd_config
#AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys %u %f
#AuthorizedKeysCommandUser ec2-instance-connect
AuthorizedKeysCommand と AuthorizedKeysCommandUser は、公開鍵での認証に関する設定らしい
この設定を変更することによって、ログインに異常が発生していないかは確認しておく
OpenSSH で全ユーザの公開鍵を1ファイルで管理する - meta‘s blog(2017-08-29)
https://w.vmeta.jp/tdiary/20170829.html
■EC2を停止
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの停止」
で停止できる
停止しない場合、再度
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの強制停止」
を行うと強制停止になる
強制停止は、停止の操作を行ってからしばらくすると現れるみたい?
以下は以前の操作手順メモ
今とは少し操作が変更されているみたい
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの停止」
で停止しない場合、再度
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの停止」
を行うと強制停止になる
■EC2のインスタンスタイプを変更
インスタンスタイプを変更するために、いったんインスタンスを停止させる
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの停止」
インスタンスタイプを変更する
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの設定」→「インスタンスタイプの変更」
任意のインスタンスタイプを選択して「適用」ボタンを押す
インスタンスを開始する
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「開始」
18:03に作業を開始してt2.microをt2.smallに変更した場合、
18:03 停止
18:05 性能変更(数秒で完了)
18:08 起動完了
18:10 ステータスチェック完了
くらいの時間だった。
※スワップを設定している場合、メモリに応じてスワップサイズを見直す
■インスタンスストアボリュームとEBS
インスタンスストアはEC2の揮発性ブロックストレージ
EBSはデータが永続化されるブロックストレージ
サーバを停止すると、インスタンスストアボリュームのデータは無くなる。EBSのデータは保持される
インスタンスストアボリュームの方がEBSよりも高速に読み書きできるので、一時的なデータの保持に使用できる
インスタンスストアボリュームを使うためには別途設定が必要なので、設定した覚えがないなら原則気にする必要は無さそう
インスタンスの停止と起動 - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/Stop_Start.html
Amazon EC2 インスタンスストア - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/InstanceStorage.html
EC2の揮発性ストレージ「インスタンスストア」を使ってみよう! | DevelopersIO
https://dev.classmethod.jp/articles/howto-ec2-volatile-block-storage-instance-store/
【AWS】インスタンスストアとEBSの違いとは? - Qiita
https://qiita.com/satton6987/items/42a4f8c56aa3851120f9
■EBSのボリュームサイズを変更(ボリュームサイズを直接増やす方法)
EBSとは「Elastic Block Store」の略で、EC2向けに設計されたストレージサービス
アップデートにより、EC2の再起動なしにボリュームサイズを増やすことができるようになった
コンソールからサイズ変更できるようになったが、パーティションの拡張とファイルシステムの拡張はCUI操作が必要
拡張コマンドはOSによって異なるので注意
OS別EBSオンライン拡張方法 | DevelopersIO
https://dev.classmethod.jp/articles/expand-ebs-in-online/
XFS利用時のEC2のディスクを拡張する方法 - Qiita
https://qiita.com/sand_bash/items/50c1721cc10f48fef804
ボリュームサイズ変更後の Linux ファイルシステムの拡張 - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html
【遂に来た!】EBS でボリュームサイズを変更できるようになりました(ボリュームタイプ変更も) | DevelopersIO
https://dev.classmethod.jp/articles/release-change-ebs-volume-size/
ご存知でしたか?EC2インスタンスは再起動なしにディスクサイズ(EBSボリュームサイズ)を増やせます | DevelopersIO
https://dev.classmethod.jp/articles/extending-disk-size-without-reboot/
また、
・インスタンスタイプが現行世代のインスタンスでなく、かつ旧世代の以下インスタンスファミリーでもない場合
・C1、C3、CC2、CR1、G2、I2、M1、M3、R3
・2TiB (2048GiB) 以上のボリュームの場合
・前回の変更から6時間以内の場合
・ボリュームサイズを小さくしたい場合
などの場合は利用できないので注意
この場合、このファイル内の「EBSのボリュームサイズを変更(ボリュームをデタッチ&アタッチして増やす方法)」の方法を参照
現行世代のインスタンスは、以下のページで確認できる
インスタンスタイプ - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/instance-types.html#current-gen-instanc...
以下、実際に8GBのEBSを12GBに拡張したときの手順
おおまかに
1. EBSのスナップショットを作成する
2. AWSコンソールからボリュームのサイズを変更する
3. EC2にSSHで接続し、パーティションの拡張とファイルシステムの拡張を行う
という流れになる
各内容の詳細は以下に記載する
作業前の状況は以下のとおり
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 8G 0 disk
└─xvda1 202:1 0 8G 0 part /
# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 474M 0 474M 0% /dev
tmpfs 492M 0 492M 0% /dev/shm
tmpfs 492M 412K 492M 1% /run
tmpfs 492M 0 492M 0% /sys/fs/cgroup
/dev/xvda1 8.0G 4.7G 3.4G 59% /
tmpfs 99M 0 99M 0% /run/user/1000
まず、対象となるEBSのスナップショットを作成しておく
(必須ではないが、念のためのバックアップ。もしくは、インスタンスのAMIを作成しておく)
インスタンス一覧から対象のインスタンスを選択し、「ストレージ」タブからボリュームIDを確認する
ボリューム一覧から対象のボリュームを選択し、「スナップショットの作成」を選択する
必要に応じて説明などを入力し、「スナップショットの作成」ボタンをクリックする
ボリューム一覧から対象のボリュームを選択し、「ボリュームの変更」を選択する
「サイズ」欄に変更したいサイズを入力する(今回は「8」を「12」に変更した)
以下の確認が表示される
内容を確認して「はい」を選択する
ボリューム一覧ですぐに変更を確認できた
ボリュームの状態は「使用中 - optimizing (0%)」という表示になり、これは10分ほどで「使用中」になった(30GB→500GBに変更したときに確認)
この完了を待たずに引き続きのパーティション拡張作業を行なっても、問題無く進めることができた
「lsblk」の結果でもサイズが増えているが、「df -h」の結果には変化が無い
つまり、この時点では拡張後の領域はまだ使用できない
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 12G 0 disk
└─xvda1 202:1 0 8G 0 part /
続いて、コンソールからパーティションの拡張を行う
# growpart /dev/xvda 1
CHANGED: partition=1 start=4096 old: size=16773087 end=16777183 new: size=25161695 end=25165791
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 12G 0 disk
└─xvda1 202:1 0 12G 0 part /
さらにファイルシステムの拡張を行う
(後述のとおり、ファイルシステムの拡張コマンドはOSによって異なる。以下のxfs_growfsコマンドは Amazon Linux 2 環境での例)
# xfs_growfs /dev/xvda1 … 結果を控えておくのを忘れたため、結果は「実際に8GBのEBSを12GBに拡張したとき」のものでは無いので注意
meta-data=/dev/xvda1 isize=512 agcount=4, agsize=524159 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1 spinodes=0
data = bsize=4096 blocks=2096635, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 2096635 to 3145211
# df -h
ファイルシス サイズ 使用 残り 使用% マウント位置
devtmpfs 474M 0 474M 0% /dev
tmpfs 492M 0 492M 0% /dev/shm
tmpfs 492M 412K 492M 1% /run
tmpfs 492M 0 492M 0% /sys/fs/cgroup
/dev/xvda1 12G 4.7G 7.4G 39% /
tmpfs 99M 0 99M 0% /run/user/1000
これでHDDのサイズが増えた(OSがサイズの増加を認識した)
Amazon Linuxの場合、xfs_growfsコマンドの代わりにresize2fsコマンドを使う
# resize2fs /dev/xvda1
resize2fs 1.43.5 (04-Aug-2017)
Filesystem at /dev/xvda1 is mounted on /; on-line resizing required
old_desc_blocks = 8, new_desc_blocks = 16
The filesystem on /dev/xvda1 is now 67108347 (4k) blocks long.
なお Amazon Linux 2 環境でresize2fsコマンドを使っても、以下のとおりエラーになる
# resize2fs /dev/xvda1
resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Bad magic number in super-block while trying to open /dev/xvda1
Couldn't find valid filesystem superblock.
方法はOSごとによって異なるので注意
詳細は以下のページが解りやすい
OS別EBSオンライン拡張方法 | DevelopersIO
https://dev.classmethod.jp/articles/expand-ebs-in-online/
■EBSのボリュームサイズを変更(ボリュームをデタッチ&アタッチして増やす方法)
※アップデートにより、ボリュームをデタッチ&アタッチせずに増やすことができるようになった
詳細は、このファイル内の「EBSのボリュームサイズを変更(ボリュームサイズを直接増やす方法)」を参照
Amazon EC2編〜EBSボリュームサイズを変更してみよう!Update〜
http://recipe.kc-cloud.jp/archives/8417
http://recipe.kc-cloud.jp/archives/1278
インスタンスを停止させる
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「インスタンスの停止」
ボリュームのスナップショットを作成する
「EC2」→「ボリューム」→ 対象のボリュームを選択 → 「アクション」→「スナップショットの作成」
「Name」と「説明」を入力して「作成」ボタンを押し、しばらく待つ。それぞれ「refirio_net-EBS」と「20160526」などを入力すればいい
スナップショットからボリュームを作成する
「EC2」→「スナップショット」→ 対象のボリュームを選択 → 「アクション」→「ボリュームの作成」
必要に応じてサイズやアベイラビリティーゾーンなどを変更する
インスタンスからボリュームを付け替える
「EC2」→「ボリューム」→ 対象のボリュームを選択 → 「アクション」→「ボリュームのデタッチ」
続いて新たに作成したボリュームを選択 → 「アクション」→「ボリュームのアタッチ」
「インスタンス」と「デバイス」を入力して「アタッチ」ボタンを押す。デバイスには「/dev/xvda」と入力すればいい
インスタンスを開始する
「EC2」→「インスタンス」→ 対象のインスタンスを選択 → 「インスタンスの状態」→「開始」
11:42に作業を開始して8GiBを16GiBに変更した場合、
11:42 停止&スナップショット作成
11:50 スナップショット作成完了&ボリューム作成
11:57 ボリューム作成完了
12:00 新ボリューム作成(比較的すぐに作成された)
12:04 ボリュームをデタッチ&アタッチ(即座に設定された)
12:05 インスタンスを開始
12:09 完了
くらいの時間だった。サイズが大きいと時間もかかるかも
■定期的にスナップショットを作成する
未検証だが、ライフサイクルポリシーから設定できるみたい
EC2のスナップショットを手軽に自動取得する方法 - Qiita
https://qiita.com/nkojima/items/3a39c94348e6d743b483
■EBSの料金
料金について調べて連携した時の内容
「恐らくこの計算で合っているだろう」というもの
↓
ストレージについて、以下がAmazonによる説明です。
リージョンは「アジアパシフィック(東京)」です。
ハイパフォーマンスブロックストレージの料金 - Amazon EBS の料金 - Amazon Web Services
https://aws.amazon.com/jp/ebs/pricing/
今案件でも採用している「汎用SSD (gp2) ボリューム」について、「1か月にプロビジョニングされたストレージ1GBあたり0.12USD」と書かれています。
仮に「1ドル=150円」で計算するとして、1GBあたり月額18円ほどとなります。
サーバは2台構成なので「30GB×2台」を「120GB×2台」にした場合、月額1080円(30×2×18)ほどかかっていたものが月額4320円(120×2×18)ほどに増えることになります。
サイズは、AWSでの容量設定画面に「最小: 1GiB、最大: 16384GiB」と書かれていますので、約16TBが最大となります。
■EC2の停止とEBSの課金
EC2を停止させるとEC2への課金は止まるが、そのEC2のディスクであるEBSへは課金が続けられるので注意
不要になったEBSとスナップショットは削除する
停止したインスタンスの EBS 課金を停止する
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ebs-charge-stopped-instance/
■PINGに応答させる
AWS EC2は(デフォルトで)Pingに応答しない - Qiita
https://qiita.com/jkr_2255/items/48be7527d88413a4fe71
AWS EC2 で Ping応答を得られるようにする設定 | Check!Site
http://www.checksite.jp/aws-ec2-icmp-rule/
AWSのEC2インスタンスをpingで確認できるようにする
http://a1-style.net/amazon-web-service/ping-icmp-setting/
■計画停止
ハードウェアのメンテナンスのため、EC2はまれに計画停止される
止められないサービスの場合、複数台構成にしておく必要がある
code.rock: Amazon EC2は、まれに「計画停止」されます
http://blog.dateofrock.com/2010/06/degraded-amazon-ec2-instance.html
インスタンスの予定されたイベント - Amazon Elastic Compute Cloud
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/monitoring-instances-status-check_sched.htm...
停止の15日ほど前に、以下のメールが送られてくる
差出人: "Amazon Web Services, Inc." <no-reply-aws@amazon.com>
件名: [Retirement Notification] Amazon EC2 Instance scheduled for retirement.
本文:
Dear Amazon EC2 Customer,
We have important news about your account (AWS Account ID: 584792723008).
EC2 has detected degradation of the underlying hardware hosting your Amazon EC2 instance (instance-ID: i-49335aec) in the ap-northeast-1 region.
Due to this degradation, your instance could already be unreachable.
After 2017-12-25 15:00 UTC your instance, which has an EBS volume as the root device, will be stopped.
You can see more information on your instances that are scheduled for retirement in the AWS Management Console (https://console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Events)
* How does this affect you?
Your instance's root device is an EBS volume and the instance will be stopped after the specified retirement date.
You can start it again at any time.
Note that if you have EC2 instance store volumes attached to the instance, any data on these volumes will be lost when the instance is stopped or terminated as these volumes are physically attached to the host computer
* What do you need to do?
You may still be able to access the instance.
We recommend that you replace the instance by creating an AMI of your instance and launch a new instance from the AMI.
For more information please see Amazon Machine Images (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) in the EC2 User Guide.
In case of difficulties stopping your EBS-backed instance, please see the Instance FAQ (http://aws.amazon.com/instance-help/#ebs-stuck-stopping).
* Why retirement?
AWS may schedule instances for retirement in cases where there is an unrecoverable issue with the underlying hardware.
For more information about scheduled retirement events please see the EC2 user guide (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-retirement.html).
To avoid single points of failure within critical applications, please refer to our architecture center for more information on implementing fault-tolerant architectures:
http://aws.amazon.com/architecture
If you have any questions or concerns, you can contact the AWS Support Team on the community forums and via AWS Premium Support at:
http://aws.amazon.com/support
Sincerely,
Amazon Web Services
This message was produced and distributed by Amazon Web Services, Inc., 410 Terry Avenue North, Seattle, Washington 98109-5210
Reference: AWS_EC2_PERSISTENT_INSTANCE_RETIREMENT_SCHEDULEDb0f0d3c6-3938-4d68-8c89-d1b90b0d3a19
「EC2 → イベント」から、計画停止対象のインスタンスを確認できる
「開始時刻」部分でメンテナンスの開始日時を確認できる
以下は実際に計画停止があったときの内容(「EC2 → イベント」に表示されたもの)
26日16時ごろに確認したものなので、「開始時刻」は日本時間で表示されているみたい
21時になったらインスタンスが停止させられるらしい
リソース名: web2
リソースタイプ: instance
リソース ID: i-0a6899bfecd4XXXXX
アベイラビリティーゾーン: ap-northeast-1c
イベントタイプ: instance-stop
イベントステータス: Scheduled
イベントの説明: The instance is running on degraded hardware
開始時刻: 2018年2月26日 21:00:00 UTC+9
所要時間: -
イベントの進行状況: 4 時間 48 分 に開始
「EC2 → インスタンス」で対象のインスタンスを選択すると、以下のメッセージが表示されている
「リタイア: このインスタンスは 2018年2月26日 21:00:00 UTC+9 後にリタイアが予定されています。」
さらに「i」マークをクリックすると、以下のメッセージが表示される
「リタイアが予定されているインスタンスは、指定された日付の後シャットダウンされます。
代替インスタンスを作成し、そのインスタンスへの移行を開始することをお勧めします。」
インスタンスを停止させると、「EC2 → イベント」「EC2 → インスタンス」に表示されていた警告は非表示になった
AWSではインスタンスを「停止 → 起動」とすると物理的に別の領域にインスタンスが立ち上がる(再起動では同じ領域が使われる)
つまり「停止 → 起動」で計画停止を回避できて、「再起動」では回避できない
■Session Manager
未検証
AWSコンソールまたはAWS CLIのコマンド経由で、SSM Agentを経由してサーバに接続することができる
Session Manager を設定する - AWS Systems Manager
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started.h...
Session Manager を使用した Linux インスタンスへの接続 - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/session-manager.html
踏み台EC2を廃止してSession Manager接続に置き換えました | by Daichi Harada | Eureka Engineering | Sep, 2021 | Medium
https://medium.com/eureka-engineering/started-to-use-ssm-session-manager-49dcd1e867a6
さらば踏み台サーバ。Session Managerを使ってEC2に直接SSHする - karakaram-blog
https://www.karakaram.com/aws-session-manager-tunneling-support-for-ssh/
初めてのAWS Session Manager(SSM) - Qiita
https://qiita.com/comefigo/items/b705325d082018ab2348
セッションマネージャー越しにSSHアクセスすると何が嬉しいのか | DevelopersIO
https://dev.classmethod.jp/articles/ssh-through-session-manager/
AWS Systems Managerを使用したEC2インスタンス管理手順 - 株式会社システムエグゼ
https://www.system-exe.co.jp/infraexpert01/
■Lightsail
未検証
VPSのような使い方ができるサーバ
制限はあるが、手軽に固定の低料金で使える
「EC2一台で、可用性は割り切って運用する」のような場合はLightsailを検討するといい
開発&検証環境として使うには良さそう
AWSの他のサービスと連動しないことが前提となっているかも
CloudTrailやCloudWatchの連動もなく、Lightsail専用画面で簡易的なログが見られるのみ
WordPressの環境を立ち上げるとSSL対応になっているが、使われているのはオレオレ証明書(証明書の警告が表示される)
最も安いプランなら、さくらVPSよりも安い$5で使えるらしい
が、IPを固定したければ「静的IPアドレス」の作成が必要
固定IPを設定すると$9近くになって金額的なメリットはあまり無い…と解説しているサイトがあったが、公式に
「静的 IP アドレスはインスタンスにアタッチされている間は無料です。」
と書かれている。それなら本当に$5で使えるかも
可用性を高めるために、複数台構成にしてロードバランサーを付けることもできる
が、1ヶ月あたり$18かかるので、金額的なメリットは消える
そこまでするならEC2でいいかも
あとからマネージドデータベースのサービスも追加された
金額は、実際にインスタンスを作成する画面に表示されている(料金シミュレータにはLightsailが無い)
月額 $5, $10, $20, $40, $80 のプランがある
https://lightsail.aws.amazon.com/ls/webapp/home/instances
ちなみにEC2だと、t2.microを一台立ち上げた時点で月額 $8.5
その後、さらに値下げされている
AWSの仮想プライベートサーバ(VPS)「Amazon Lightsail」が料金改定でほぼ半額に。メモリ16GB、32GBのインスタンスサイズも新設 − Publickey
https://www.publickey1.jp/blog/18/awsvpsamazon_lightsail16gb32gb.html
Amazon Lightsail - AWSの力、VPSの簡単さ | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/amazon-lightsail-the-power-of-aws-the-simplicity-of-a-vps/
Lightsail
https://aws.amazon.com/jp/lightsail/
Lightsail ロードバランサー
https://aws.amazon.com/jp/lightsail/features/load-balancing/
よくある質問
https://aws.amazon.com/jp/lightsail/faq/
Amazon Lightsailの注意点 - Qiita
https://qiita.com/morimori/items/27f7bfeeb5e508f5efa6
超便利そうな Amazon Lightsail の落とし穴を確認してみる - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2016/12/02/lightsail/
Amazon Lightsail 調べてみた(料金とかさくらとの比較とか) - やすはるラボ+嫁(*・ω・)
http://d.hatena.ne.jp/yasuhallabo/20170702/1499003812
AWSの仮想プライベートサーバ(VPS)「Amazon Lightsail」、数クリックでMySQLなどのマネージドデータベースが設定可能に − Publickey
https://www.publickey1.jp/blog/18/awsvpsamazon_lightsailmysql.html
EC2よりシンプルな料金体系の「Amazon Lightsail」で仮想プライベートサーバを立てる:AWSチートシート - @IT
https://www.atmarkit.co.jp/ait/articles/2103/15/news012.html
■RDS
※データベースに特化したインスタンスを作成できる
※最初に文字コードや時差を指定したパラメータグループを作成しておくと、スムーズに構築できそう(後述)
■パラメータグループの作成
作成したいRDSのバージョンに合わせてパラメータグループを作成し、以下の設定を変更しておく
設定については、後述の「データベースの文字コードをUTF8MB4にする」「時差対策」「スロークエリ出力」を参照
character_set_client: utf8mb4
character_set_connection: utf8mb4
character_set_database: utf8mb4
character_set_results: utf8mb4
character_set_server: utf8mb4
init_connect: SET SESSION time_zone = CASE WHEN POSITION('rdsadmin@' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
slow_query_log: 1
long_query_time: 1
■RDSの作成
「Relational Database Service → 今すぐ始める」もしくは「Relational Database Service → DBインスタンスの起動」からインスタンスを作成
データベース作成方法を選択: 標準作成
エンジンのオプション: MariaDB
バージョン: MariaDB 10.6.12
テンプレート: 開発/テスト
DBインスタンス識別子: refirio-develop(大文字で入力しても小文字で保存される)
マスターユーザー名: rdsmaster
マスターパスワード: XXXXXXXXXXXX
DBインスタンスクラス: バースト可能クラス(t クラスを含む)
db.t3.micro
ストレージタイプ: 汎用(SSD)
ストレージ割り当て: 20GiB
ストレージの自動スケーリングを有効にする: チェックを外す
マルチAZ配置: スタンバイインスタンスを作成しないでください
コンピューティングリソース: EC2コンピューティングリソースに接続
EC2インスタンス: (接続を許可したいEC2インスタンス。このEC2に自動作成されたセキュリティグループが追加されるらしい)
Virtual Private Cloud: (選択済みで変更できなくなっていた)
DBサブネットグループ: 既存の選択
既存のDBサブネットグループ: (あらかじめ作成したものを選択)
パブリックアクセス: なし
VPCセキュリティグループ (ファイアウォール): default ※「Amazon RDS は、コンピューティングリソースとの接続を許可 する新しい VPC セキュリティグループ rds-ec2-1 を追加します。」と表示されている
モニタリング: チェックを外す
最初のデータベース名: (作成したいデータベース名を入力)
DBパラメーターグループ: (上で作成したものを選択)
オプショングループ: default:mariadb-10-6
バックアップ保持期間: 3日間
削除保護の有効化: チェックを付ける
※「ストレージタイプ」は、マルチAZを使う場合はデフォルトが「プロビジョニングIOPS(SSD)」になる?
「汎用(SSD)」に比べて非常に高額なので注意
※マルチAZ配置の時に、アベイラビリティゾーンを指定するとインスタンス作成時にエラーになった
インスタンスが作成されるまで数分待つ
必要に応じて、WebサーバからMySQLにアクセスするための設定を行っておく
# yum -y install php-mysql
# service httpd restart
RDSのエンドポイントが以下の場合、
develop.xxxxx.rds.amazonaws.com:3306
例えばWebサーバからSSHで以下のようにすればRDSへ接続できる
mysql -h develop.xxxxx.rds.amazonaws.com -u webmaster -p
MySQL データベースエンジンを実行している DB インスタンスに接続する
http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html
RDSに接続できません
https://forums.aws.amazon.com/thread.jspa?threadID=115768
■EC2との紐づけ
2022年の終わりごろから、RDSインスタンス作成時に既存EC2との紐付けができるようになっている
RDSインスタンス作成時にEC2に接続設定するオプション | ヤマムギ
https://www.yamamanx.com/rds-ec2-autocon/
Amazon RDSインスタンス作成時に既存EC2との紐付けができるようになっていた - Qiita
https://qiita.com/wol/items/8add252515b4c70f5261
■マルチAZにしたときのRDSの挙動
マルチAZにしておくことで、ダウンタイムを短くすることができる
RDS起動後にマルチAZに変更する場合の解説は、後述の「RDSをシングルAZからマルチAZに変更」を参照
マルチAZか否かによっての停止時間の差は、後述の「RDSのインスタンスタイプを変更」を参照
【5分でわかる】スペックアップ&メンテナンス時のRDSの動作 - ナレコムAWSレシピ | AIに強い情報サイト
https://recipe.kc-cloud.jp/archives/10806
■データベースの文字コードをUTF8にする
※文字コードを何も設定しないと、日本語が文字化けしてしまう
※今新規に設定するなら、絵文字なども扱えるUTF8MB4にしておく方が良さそう(後述)
「RDS」→「パラメータグループ」→「パラメータグループの作成」
新しく「refirio-develop」のような名前でパラメータグループを作成し、「character_set_database」と「character_set_server」を「utf8」に設定する
今ならutf8mb4も検討する(後述)
作成したパラメータグループをもとにRDSインスタンスを作成する
(RDSインスタンス作成後にパラメータグループを設定しても、既存のデータベースの文字コードには影響しない
必要に応じてデータベースの文字コードを変更するか、データベースを作り直すかをする)
新規にテーブルを作成するときは、以下のように「DEFAULT CHARSET=utf8」を指定する
CREATE TABLE IF NOT EXISTS users(
id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '代理キー',
created DATETIME NOT NULL COMMENT '作成日時',
modified DATETIME NOT NULL COMMENT '更新日時',
username VARCHAR(80) NOT NULL UNIQUE COMMENT 'ユーザ名',
password VARCHAR(80) COMMENT 'パスワード',
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'ユーザ';
Amazon RDS の MySQL で UTF-8 のデータベースを作る
http://dotnsf.blog.jp/archives/2211314.html
RDSで日本語が文字化けする問題
http://qiita.com/reoy/items/e355debf1e2b2abd703b
■データベースの文字コードをUTF8MB4にする
※UTF8では4バイト文字が文字化けするので、絵文字などを扱いたければUTF8MB4にしておく
パラメータグループを「character_set_」で絞り込むと、文字コードに関する値が表示される
以下のを値をすべて「utf8mb4」に変更する
character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server
character_set_filesystem は変更しなくていいみたい
以降、MySQLと同様に「CHARSET=utf8mb4」を指定してテーブルを作成すればいい
RDS MySQL5.5.33 で『utf8mb4』(4バイト対応UTF-8文字コードセット)を試してみた
http://dev.classmethod.jp/cloud/aws/utf8mb4-on-rds-mysql/
MySQLの文字コードをutf8mb4に変更
http://qiita.com/deco/items/bfa125ae45c16811536a
■時差対策
「RDS」→「パラメータグループ」→ 作成したパラメータグループを選択 →「パラメータの編集」で、
「init_connect」の値に以下を設定する
SET SESSION time_zone = CASE WHEN POSITION('rdsadmin@' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
「time_zone」を「Asia/Tokyo」に設定しているが、「rdsadmin」というユーザで接続してきた場合のみ除外する
AmazonがRDSを管理するためにrdsadminというユーザを用意しているが、
このユーザが接続した時にタイムゾーンがUTC以外だと不都合が起こるらしい
Amazon Auroraでタイムゾーンを設定する
http://dev.classmethod.jp/cloud/aws/aurora-set-timezone/
AWS RDSのタイムゾーンについて
http://techfun.cc/aws/aws-rds-timezone.html
■スロークエリ出力
RDSでslow queryを出力させる方法
http://rfs.jp/server/aws/aws-rds_slow-query.html
RDSでslow queryを出力する
http://digape.com/201206/aws-rds%E3%81%A7slow-query%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B/
パラメータグループで指定できる
long_query_time を 0 にするとすべてのクエリが記録されるので、いったん 0 にして記録されることを確認する
最初は 0.1 くらいにして様子を見つつ、記録されるクエリが多いなら値を大きくして…と調整する
long_query_time はRDSを再起動しなくても、値を設定してから数秒後に反映された
(「適用タイプ」が「dynamic」の値は、すぐに反映されるみたい)
mysql> SHOW GLOBAL VARIABLES LIKE 'slow_query_log';
… スロークエリのONを確認
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | ON |
+----------------+-------+
1 row in set (0.00 sec)
mysql> SHOW GLOBAL VARIABLES LIKE 'long_query_time';
… スロークエリの記録時間を確認
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 0.100000 |
+-----------------+----------+
1 row in set (0.00 sec)
パラメータグループで log_output を FILE にしておくと、AWS管理画面からスロークエリのファイルをダウンロードできる
(RDS → インスタンス → インスタンスを選択 → ログ → slowquery/mysql-slowquery.log → ダウンロード)
パラメータグループで log_output を TABLE にしておくと、SQLで確認できる
mysql> SELECT * FROM mysql.slow_log;
… スロークエリを確認
+---------------------+-----------------------------------+------------+-----------+-----------+---------------+------+----------------+-----------+-----------+---------------------------------+-----------+
| start_time | user_host | query_time | lock_time | rows_sent | rows_examined | db | last_insert_id | insert_id | server_id | sql_text | thread_id |
+---------------------+-----------------------------------+------------+-----------+-----------+---------------+------+----------------+-----------+-----------+---------------------------------+-----------+
| 2016-11-16 11:11:31 | testuser[testuser] @ [10.0.0.23] | 00:00:00 | 00:00:00 | 341 | 341 | | 0 | 0 | 598711836 | SHOW STATUS | 7225454 |
| 2016-11-16 11:11:46 | webuser[webuser] @ [10.0.1.103] | 00:00:00 | 00:00:00 | 100 | 100 | test | 0 | 0 | 598711836 | SELECT * FROM accounts LIMIT 100| 7225468 |
| 2016-11-16 11:11:46 | webuser[webuser] @ [10.0.1.103] | 00:00:00 | 00:00:00 | 100 | 100 | test | 0 | 0 | 598711836 | Quit | 7225468 |
+---------------------+-----------------------------------+------------+-----------+-----------+---------------+------+----------------+-----------+-----------+---------------------------------+-----------+
3 rows in set (0.00 sec)
以下のように、対象を絞って確認するのも有効
mysql> SELECT start_time, query_time, lock_time, sql_text FROM mysql.slow_log ORDER BY start_time DESC LIMIT 10;
RDSでのエラーログは以前は見ることができなかったが、現在は
RDS → インスタンス → (インスタンスを選択) → ログ
から表示できる…らしいが、思ったような情報が書き込まれていないのでログはMySQL経由で確認するほうがいいような。要勉強
■タイムアウトの時間を変更する
設定を確認すると、以下のようになっている
mysql> SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 28800 |
+---------------+-------+
1 row in set (0.04 sec)
「max_connections」は、RDS上では「{DBInstanceClassMemory/12582880}」となっている
「wait_timeout」は、RDS上では空欄になっている
RDSのパラメータグループ設定画面から900(15分)に変更してみる
mysql> SHOW GLOBAL VARIABLES LIKE 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 900 |
+---------------+-------+
1 row in set (0.17 sec)
コマンドで確認すると変更されている
■RDSをシングルAZからマルチAZに変更
一時的にMulti-AZにしてフェイルオーバーしたRDSのAvailability Zoneを元にもどす一番簡単な方法(TGI Multi-AZ Pattern)
http://blog.serverworks.co.jp/tech/2014/10/08/tgi-multi-az-pattern/
「RDS」→「インスタンス」→ 対象のインスタンスを選択 →「変更」
「インスタンスの仕様」にある「マルチ AZ 配置」を「はい」に変更し、「次へ」ボタンを押す。
内容を確認し、「変更のスケジュール」にある「すぐに適用」にチェックを入れて「DBインスタンスの変更」ボタンを押す。
少し待つと、インスタンス一覧で「ステータス」が「変更中」になる。
「利用可能」になればOK。
変更自体は15分ほどかかったが、ダウンタイムは発生しないとのこと。
(ブラウザを時々リロードしていたが、アクセスできないことは無かった。)
■RDSのインスタンスタイプを変更
上に書いた、マルチAZへの変更と同じ手順で可能。
ただしシングルAZの場合、6〜8分程度インスタンスが停止する。
マルチAZの場合でも、1分程度インスタンスが停止する。
【AWS】RDSのインスタンスタイプ変更にかかる時間を調べてみた
http://dev.classmethod.jp/cloud/aws/rds-scaleup-instancetype/
18:58に作業を開始して db.t2.micro を db.t2.small に変更した場合、
18:58 変更
18:59 ステータスが「変更中」になった
19:05 データベースに接続できなくなった
19:06 データベースに接続できるようになった
19:14 ステータスが「利用可能」になった
くらいの時間だった(上記のように大抵15分程度で完了するが、アクセスが集中しているときに変更すると20分以上かかった)
RDSのイベントを見ると19:05に
「Multi-AZ instance failover started」「Multi-AZ instance failover completed」
となっていた。
ブラウザを時々リロードしていたが、接続できない時間は数十秒程度だった。その間RDSからは
SQLSTATE[HY000] [2003] Can't connect to MySQL server on 'develop.xxxxx.ap-northeast-1.rds.amazonaws.com' (4)
というエラーメッセージが返されていた
■RDSのマスターパスワードを変更
「RDS」→「インスタンス」→ 対象のインスタンスを選択 →「変更」
「新しいマスターパスワード」に設定したいパスワードを入力し、「次へ」ボタンを押す
内容を確認し、「変更のスケジュール」にある「すぐに適用」にチェックを入れて「DBインスタンスの変更」ボタンを押す
■バックアップの概要
Amazon RDS for SQL Server
https://aws.amazon.com/jp/rds/sqlserver/
DBインスタンスのバックアップが毎日、トランザクションログのバックアップが5分ごとに行われ
最大5分前まで、保持期間内の任意の時点にDBインスタンスを復元できます
自動バックアップの保持期間は、最大35日間まで設定できます
…とあるが、「データベースを特定時点の内容に戻せる」機能では無いので注意。以下詳細
■バックアップについて詳細
スナップショットが日次で自動取得され、5分ごとにトランザクションログも保存されている
それぞれ、保存先はS3となる
これらバックアップから、RDSを復元することができる
…が、これらは「データベースを特定時点の内容に戻せる」ではなく、
「特定時点の内容をもとに新規にデータベースを作成する」という機能なので注意
よって復元したデータベースを使用する場合、
・バックアップをもとにRDSを新規に起動する(普通にRDSを新規作成するだけの時間がかかる)
・サービスのエンドポイントを、新規に起動したRDSに変更する(WebアプリケーションのRDS接続先を変更する)
・セキュリティグループなど一部のパラメータを修正する(バックアップから復元時には指定できない)
・復元中に書き込まれたデータを新しいデータベースに反映する
という作業が必要になる
スナップショット自体については以下のとおり
データベースのバックアップと思っておいて問題ない
スナップショット (snapshot)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word14388.html
DB スナップショットの作成 - Amazon Relational Database Service
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_CreateSnapshot.html
RDSを稼働させたままスナップショットを取得した場合、データの整合性はどのタイミングまで保障されるのでしょうか? - 株式会社サーバーワークス サポートページ
https://support.serverworks.co.jp/hc/ja/articles/360007955413-RDS%E3%82%92%E7%A8%BC%E5%83%8D%E3%81%9...
スナップショット自動作成のデフォルト時間は、東京リージョンだと「13:00-21:00 UTC」から自動的に決定されるらしい
過去実際に構築した案件では、毎日「04:00 PM UTC」にバックアップが作成されていた(案件によって数時間の差がある)
「04:00 PM UTC」なので「16:00 UTC」なので「01:00 JST」となり、つまり深夜1時ごろ
AWS データベースサービスの自動バックアップ設定まとめ | DevelopersIO
https://dev.classmethod.jp/articles/automated-snapshots-of-aws-database-services/
シングルAZの場合、バックアップの際に数秒間I/Oが一時中断することがある
マルチAZの場合、バックアップはスタンバイから取得されるためI/Oは中断されない(数分負荷が高くなることはある)
バックアップの使用 - Amazon Relational Database Service
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html
自動バックアップウィンドウ中、バックアッププロセスの開始時にストレージ I/O が一時中断することがあります (通常は数秒間)。
マルチ AZ 配置のバックアップ中は、レイテンシーが数分間高くなることがあります。
MariaDB、MySQL、Oracle、PostgreSQL の場合、バックアップはスタンバイから取得されるため、
マルチ AZ 配置のバックアップ中プライマリで I/O アクティビティは中断しません。
■スナップショットの作成
「RDS」→「インスタンス」→ 対象のインスタンスを選択 → 「アクション」→「スナップショットの取得」
で、「スナップショット名」を指定して取得する
取得したスナップショットは
「RDS」→「スナップショット」
に保存される
■スナップショットの復元
「RDS」→「スナップショット」→ 対象のスナップショットを選択 → 「スナップショットの復元」
で、新規作成時と同様に各パラメータを入力する。
「DBインスタンス識別子」は、既存のものと重複しないものを指定する
セキュリティグループなど一部のパラメータは指定できないので、復元後に設定を変更する必要がある
入力したら「DBインスタンスの復元」ボタンを押す。RDSが新規に作成される。
■特定時点への復元
「RDS」→「インスタンス」→ 対象のインスタンスを選択 → 「アクション」→「特定時点への復元」
で、「復元可能な最新時刻を使用する」もしくは「任意の復元時刻を使用する」で日時を指定
あとは、スナップショットの復元と同様に各パラメータを入力する。
入力したら「DBインスタンスの起動」ボタンを押す。RDSが新規に作成される
■復元中に書き込まれたデータを新しいデータベースに反映
具体的な方法は要検討
SHOW TABLE STATUS;
を実行すると、「Create_time」にテーブルの作成日時、「Update_time」にテーブルの更新日時が表示される
これをもとに更新されたテーブルを特定
…と思ったが、InnoDBなどでは「Update_time」が常にNULLになるため使えない
(InnoDBは、システムテーブルスペース内に複数のテーブルを格納するため)
特定テーブルのみ、独自のシステムでバックアップしておくなど、何らかの保険を持っておくほうがいいかも?
■停止
RDSは停止できず、課金を中断したければスナップショットを撮って削除する必要があった
現在はシングルAZ構成なら停止が利用できるみたい
本番環境のRDSを止めることはないだろうけど、開発・検収環境のRDSなら使わない間は停止できる
…と思ったけど、7日を超えて停止させていると自動で削除されるらしい。使い所がよく分からず
[速報] RDSインスタンスの起動/停止
http://dev.classmethod.jp/cloud/aws/start-stop-db-instance-for-rds/
■マイナーバージョン自動アップグレード
[全部乗せ] Amazon Aurora の設定変更で注意が必要なものをまとめてみた | DevelopersIO
https://dev.classmethod.jp/articles/tsnote-aurora-downtime-occurs-setting-situation/
RDS マイナーバージョン自動アップグレードについて調べてみる
https://zenn.dev/ysmtegsr/scraps/a114584a3a5405
【小ネタ】RDSのマイナーエンジンアップグレードに失敗した話 | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2022-07-28-105106/
RDSのマイナーバージョンアップ = 後方互換あり
バージョンアップの自動適用 = ダウンタイムが発生する
となっている
意図しないダウンタイムを避けるためにも、本番環境では手動適用の方が良さそう
■メジャーバージョンアップグレード
Amazon RDS の MariaDB のバージョン - Amazon Relational Database Service
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/MariaDB.Concepts.VersionMgmt.html
「MariaDB 10.3 の終了」で10.3の終了について触れられている。2023年10月23日にサポートが終了するとのこと。
MariaDB DB エンジンのアップグレード - Amazon Relational Database Service
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.MariaDB.html
「MariaDB DB インスタンスのアップグレード」でアップグレードについて案内されている。
DB インスタンスのエンジンバージョンのアップグレード - Amazon Relational Database Service
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html
「エンジンバージョンの手動アップグレード」について触れられている。「変更」画面からエンジンを変更するとのこと。
【小ネタ】RDSのパラメータグループの差分を簡単に表示してみた | DevelopersIO
https://dev.classmethod.jp/articles/diff_rds_parameter/
同じ設定のパラメータグループを作り直す際に、差分比較を利用できる。
AWSから「[アクションが必要] Amazon RDS for MariaDB はエンジンメジャーバージョン 10.3 を廃止します」というメールが届いた。
本文を確認すると、MariaDB 10.6へのアップグレードが必要とのこと。
メジャーバージョンアップは手動で対応する必要がある。
$ mysql -h develop.xxxxx.ap-northeast-1.rds.amazonaws.com -u webmaster -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 100
Server version: 10.3.36-MariaDB-log Source distribution
作業前は「10.3.36」となっている。
該当のRDSには「RDS → パラメータグループ」にある「develop」を適用しているが、これはファミリーが「mariadb10.3」ベースとなっている。
これを「mariadb10.6」ベースにする必要があるが、あとからの変更には対応していない。よってパラメータグループを新規に作成して差し替える。
パラメータグループの一覧で「default.mariadb10.3」と「develop」を選択し、「パラメータグループアクション → 比較」を実行する。
以下の差分が表示された。
パラメータ default.mariadb10.3 develop
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
character_set_client <engine-default> utf8mb4
character_set_connection <engine-default> utf8mb4
character_set_database <engine-default> utf8mb4
character_set_results <engine-default> utf8mb4
character_set_server <engine-default> utf8mb4
init_connect <engine-default> SET SESSION time_zone = CASE WHEN POSITION('rdsadmin@' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
innodb_lock_wait_timeout <engine-default> 600
long_query_time <engine-default> 1
slow_query_log <engine-default> 1
これをもとに、新しくパラメータグループを作成する。
パラメータグループファミリー: mariadb10.6
グループ名: develop-mariadb10.6
説明: Parameter group for Develop
比較用に、デフォルト設定用のパラメータグループも作成する。
パラメータグループファミリー: mariadb10.6
グループ名: default-mariadb10-6
説明: Default group for MariaDB10.6
新しく作成したパラメータグループに、差分が無いことを確認する。
差分内容をもとに「develop-mariadb10.6」の値を調整する。調整後に再度差分を比較し、意図した内容になっているか確認する。
AWSコンソールで「RDS → データベース」で「develop」を選択し、「変更」ボタンをクリックする。
「DB エンジンバージョン」が「10.3.36」になっているが、これを「10.6.8」に変更する。(10.6系の一番新しいものを選択する。)
変更すると「DB パラメータグループ」が空欄になるので、上の手順で作成した「develop-mariadb10.6」に変更する。
ページ下部の「続行」ボタンをクリックする。
「変更のスケジュール」で「すぐに適用」を選択し、「DBインスタンスを変更」ボタンをクリックする。
11:45 変更を実行
11:46 ステータスが「アップグレード」になった
11:47 トップページで「SQLSTATE[HY000] [2002] Connection refused (SQL: select * from `session_generals` where `id` = FK9bRNg3gIvH3xYAAP39NuNBbK8eI7GLQ10uddiM limit 1)」のエラーが表示されるようになった
11:50 トップページが表示されるようになった。管理画面へのログインも維持できている
11:53 ステータスが「変更中」になった。サイトにはアクセスできている
11:54 ステータスが「利用可能」になった
AWSコンソールで、エンジンバージョンが「10.6.8」になっていることを確認できる
また、SSH経由でもバージョンの変更を確認できる
$ mysql -h develop.xxxxx.ap-northeast-1.rds.amazonaws.com -u webmaster -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 111
Server version: 10.6.8-MariaDB-log managed by
https://aws.amazon.com/rds/
■メジャーバージョンアップグレード(失敗した手順)
AWSコンソールで「RDS → データベース」で「develop」を選択し、「変更」ボタンをクリックする。
「DB エンジンバージョン」が「10.3.36」になっているが、これを「10.6.8」に変更する。(10.6系の一番新しいものを選択する。)
ページ下部の「続行」ボタンをクリックする。
「変更のスケジュール」で「すぐに適用」を選択し、「DBインスタンスを変更」ボタンをクリックする。
…が、以下のエラーが表示された。
申し訳ありません。DB インスタンス develop の変更のリクエストが失敗しました。
Current Parameter Group (develop) is non-default. You need to explicitly specify a new Parameter Group in this case (default or custom)
前述のとおり、パラメータグループを作り直す必要がある。
■RDSのスワップ
RDSのスワップを監視していると
・CPU使用率は基本的には1〜2%程度。たまに30%とか
・使用可能なメモリは1.4GBほどある
・書き込みレイテンシーはほとんど0
・スワップは時々発生している
という状態になっている
どの案件のRDSも数値は違えど同じ動作をしているので、
少なくとも「RDSに余計な設定をしてしまったからメモリが正しく使われていない」は無さそう
デフォルトの設定から、さらに突き詰めた設定をすべき、とかはあるかも
インスタンスをアップすべき、とかはあるかも
微々たるものだから問題ではない、とか?
AWS Developer Forums: RDS mysql instance uses swap but have ...
https://forums.aws.amazon.com/message.jspa?messageID=383919
RDSはそういう動作が普通みたい?
EC2も、freeのメモリがあってもswapは少し消費されるみたい?
Linuxサーバ全般でそういうものかも?
メモリ−は十分なはずなのに SWAP を使ってる? | Linux のメモリー管理(メモリ−が足りない?,メモリーリークの検出/防止)(Kodama's tips page)
http://www.math.kobe-u.ac.jp/HOME/kodama/tips-free-memory.html#memory_swap
どうしてメモリはスワップするのか!? - インフラエンジニアway - Powered by HEARTBEATS
https://heartbeats.jp/hbblog/2014/01/linux-page-swap.html
使われていないプログラムをメモリから追い出し、バッファやキャッシュに転用する
その際にもスワップが使われるらしい
物理メモリの空き容量が足りていても、malloc()した際に連続した領域が確保できないと、
その領域を確保できるまで物理メモリに存在するページをスワップするらしい
■Aurora
Amazon Aurora(高性能マネージドリレーショナルデータベース)| AWS
https://aws.amazon.com/jp/rds/aurora/
Amazon Auroraとは何かをわかりやすく図解、RDSとどう違う? 連載:全部わかるAWS入門|ビジネス+IT
https://www.sbbit.jp/article/cont1/95514
Amazon Auroraを作成してみた | DevelopersIO
https://dev.classmethod.jp/articles/lim-rds-aurora/
Amazon AuroraはRDSのデータベースエンジンの1つであり、
クラウドの普及に伴ってAmazonがその内部アーキテクチャを再設計したデータベース
■Aurora Serverless
※未検証
Amazon Aurora Serverless | AWS
https://aws.amazon.com/jp/rds/aurora/serverless/
待たせたな!噂のAuroraサーバーレスv2がGA。初心者にも分かりやすくまとめてみた - Qiita
https://qiita.com/minorun365/items/2a548f6138b6869de51a
Aurora Serverlessについての整理 | DevelopersIO
https://dev.classmethod.jp/articles/aurora-serverless-summary/
Aurora Serverlessを実際に使ってみたメリットとデメリット | 株式会社PLAN-B
https://service.plan-b.co.jp/blog/tech/28232/
インスタンススケールの管理も含めて対応してくれる
通常のAmazon Auroraに比べると料金は高めみたいだが、
高いスペックで常時稼働させているインスタンスなら、細やかなスケーリングにより費用を抑えられる可能性はありそう
■リードレプリカ
【AWS】知識ゼロから理解するRDS超入門 | 技術ブログ | MIYABI Lab
https://miyabi-lab.space/blog/31
【Amazon RDS】マルチAZとリードレプリカの違い - Qiita
https://qiita.com/1_ta/items/85954500a2c667f0e898
【AWS】RDSのレプリケーションについて解説します。 - Amazon Web Service(AWS)導入開発支援
https://www.acrovision.jp/service/aws/?p=2462
コラム - Amazon Web Servicesを追いかける | 第4回 Amazon RDS リードレプリカの設定|CTC教育サービス 研修/トレーニング
https://www.school.ctc-g.co.jp/columns/strawbag/strawbag04.html
RDSのマルチAZは、あくまでもバックアップのためであって、そのままリードレプリカとして使えるものでは無いみたい?
別途「リードレプリカを作成」の作業を行うことで、リードレプリカのエンドポイントが発行され、接続できるようになるみたい?
(マルチAZで無いRDSでも、「リードレプリカを作成」のメニューは存在する)
ただし「マスター」「スレーブ」「レプリカ」の3台構成になるため、単純なマルチAZに比べると料金が1.5倍になるので注意
要勉強
Amazon Auroraを作成してみた | DevelopersIO
https://dev.classmethod.jp/articles/lim-rds-aurora/
Aurora+MySQLの場合、レプリカを作成しなくてもスレーブに読み込み専用でアクセスできるみたい?
つまりAuroraの方が台数を抑えられるが、1台あたりのコストはAuroraの方が高いらしい
また、パフォーマンスはAuroraの方が高いらしい
Laravelでマスター/スレーブ構成のデータベースに接続するための設定 | I am a software engineer
https://imanengineer.net/laravel-how-to-configure-master-slave-db/
レプリカのデータを参照する場合、原則プログラム側で接続先を切り替える必要がある
Laravelの場合、設定を調整することにより、マスター/スレーブのデータベースに対して、
「SELECTクエリ発行時はスレーブ」「それ以外はwriteマスター」
ができるらしい
■証明書の更新
外部からSSL/TLS接続しないRDSも含めて対応が必要
放置しておくと2020年3月5日に強制アップデートされる
予期しないダウンタイムを避けるためには、手動で設定変更&RDS再起動をする必要がある
【早めに準備を!】2020年にAmazon Relational Database Service (RDS)/Amazon AuroraでSSL/TLS証明書をアップデートする必要が生じます | Developers.IO
https://dev.classmethod.jp/cloud/aws/notification-about-certificate-rotation-for-rds-and-aurora/
RDSとAuroraのSSL/TLS 証明書のメンテナンスアナウンスについて - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2019/10/18/rds-aurora-certificate-maintanance/
■PostgreSQL
RDSを新規に作成する際、「エンジンのタイプ」として「Amazon Aurora」や「MySQL」などとともに「PostgreSQL」が並んでいる
よってMySQLとPostgreSQLを併用するなら、2台のRDSを起動する必要があるみたい
ユーザの権限などハマりどころはあるようなので、使う場合は以下などで改めて確認したい
RDS (PostgreSQL) でデータベースを作成するときの注意点 - Qiita
https://qiita.com/bwtakacy/items/845c193c6da3218a546d
RDS PostgreSQLで参照専用のユーザを作成する(複数のスキーマがあっても一発で) - Qiita
https://qiita.com/Morihaya/items/b4c5c7f28736b95be732
■オートスケーリング
RDSは原則オートスケーリングに対応していない
ただしAurora Serverlessなら対応している
詳細は、前述のファイル内の「Aurora Serverless」を参照
また「ElastiCache (Redis)」内の「オートスケーリング」も参考にする
■Performance Insights
※RDSのパフォーマンスを分析できる
Performance Insights を使用した Amazon RDS データベースの負荷分析 | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/analyzing-amazon-rds-database-workload-with-performance-insight...
パフォーマンスインサイトを利用してWordPressのDB負荷を分析してみた | DevelopersIO
https://dev.classmethod.jp/cloud/aws/wordpressdb-performance-insight/
■サポートしているインスタンスについて
Amazon Aurora DB エンジンとインスタンスクラスでサポートされている Performance Insights - Amazon Aurora
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_PerfInsights.Overview.Engine...
「db.t2 - サポートされていません」「db.t3 - サポートされていません」と書かれている。情報が古い?
Performance Insights が T2 および T3 インスタンスタイプのサポートを開始
https://aws.amazon.com/jp/about-aws/whats-new/2019/02/performance-insights-supports-T2-and-T3/
Performance Insightsは今はt2やt3でもサポートしているみたい。ただし一定以上のスペックにしないと現れないような
以下は2022年8月16日時点で実際に試したもの
・t2・t3ではmedium以上で選択できるようになる。smallだと選択できない
・m5では選択できるが、そもそも最小がlarge。m3も最小がmedium
・色々組み合わせを試している限り、現状は「インスタンスクラスに関係なく利用できるが、スペックはmedium以上」ということか
・費用は無料のようなので、それで間違いなければ標準でONにしておきたい
■設定について
既存の Aurora MySQL インスタンスでパフォーマンススキーマを有効にする方法 | DevelopersIO
https://dev.classmethod.jp/articles/tsnote-amazon-aurora-performance_schema/
「パフォーマンスインサイトの有効化には再起動は必要ありませんが、パフォーマンススキーマの有効化には再起動が必要」らしい
Performance Insightsを有効にした後は、RDSの再起動を行う方が良さそう
■AMI
※インスタンスのイメージを作成し、それをもとに新しいインスタンスを作成できる
※サーバの再起動が発生し、数分程度サービスが止まるので注意
■AMIを作成
EC2 → インスタンス → インスタンスを選択 → イメージとテンプレート → イメージの作成
イメージ名: (任意の名前を入力。「refirio-web1_20180216」など)
イメージの説明: (必要なら、任意の説明を入力)
「イメージの作成」をクリックするとイメージが作成される
作成したイメージは EC2 → AMIs で確認できる
(「pending」が「available」になるまで20分程度かかった)
Amazon EC2編〜SnapshotやAMIを使ったバックアップと運用
http://recipe.kc-cloud.jp/archives/276
AWSでAMIを作成し、そのAMIからEC2インスタンスを作成する方法
http://www.checksite.jp/aws-create-ami/
Amazon EC2 の カスタム AMI を作成し、別リージョンで利用する
http://d.hatena.ne.jp/january/20130917/1379370546
■AMIからEC2を作成
WebサーバのAMIから、もう一つ同じWebサーバを作成するものとする
1. AMI の選択
AMIを選択する際、「マイ AMI」から自分で作成したAMIを選択できる
3. インスタンスの設定
可用性を高めるためのサーバを増やす場合、別のサブネット(アベイラビリティゾーン)に作成するといい
インスタンス一覧で、Availability zone が異なるインスタンスが作成されていることを確認する
Webサーバ2には以下でアクセスできるものとする
http://203.0.113.1/
http://ec2-203-0-113-1.ap-northeast-1.compute.amazonaws.com/
■AMIの共有
「EC2 → AMI」で表示される一覧からAMIを選択し、「アクション → イメージパーミッションの変更」を選択する
イメージは「プライベート」のままで「AWSアカウント番号」に共有先のアカウント番号を入力する
共有先のアカウントでEC2インスタンス作成時、「マイAMI」を表示して「所有権」を「自分と共有」にすると、共有されたAMIを選択できる
立ち上げたEC2にSSHで接続できない場合、接続先ポート番号とセキュリティグループを確認する
(既存のセキュリティグループを使い回すと、SSHのポート番号など別のものが想定されている可能性があるので注意)
AWSで AWS アカウント ID を調べる方法 - フラミナル
https://blog.framinal.life/entry/2018/01/31/132328
AWSアカウント間のAMI共有 - Qiita
https://qiita.com/tanj/items/6c4b01b1e23518d3a57a
AWSでEC2インスタンスを別アカウントに移行する方法
http://exrecord.net/how-to-migrate-ec2-instance
AWS アカウント ID とその別名
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/console_account-alias.html
特定の AWS アカウントと AMI を共有する
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/sharingamis-explicit.html
■EBSスナップショットとAMIの違い
AWS運用におけるスナップショットを用いたバックアップ戦略 | AWS運用最適化サービス cloud link (クラウドリンク)
https://aws.taf-jp.com/blog/26786
スナップショットには AMI のような、インスタンスを構成するための管理情報は含まれていません。
スナップショットの中のデータを利用する場合には、基本的にそのスナップショットを元に EBS ボリュームを作成することになります。
AWS Solutions Architect ブログ: AWSトレーニングでよくいただくご質問シリーズ - 第一回 Amazon Machine Image (AMI) とスナップショットの違い
https://aws.typepad.com/sajp/2014/04/trainingfaqbest10.html
スナップショット = 「EBS ボリュームの中のデータ」を特定のタイミングで取得しS3に保存したもの
AMI = 「EBS ボリュームの中のデータ(スナップショット) とインスタンスを構成する管理情報」を含む起動テンプレート
■バックアップ
※未検証
EC2、EBS、RDSなどをバックアップし、任意の状態に戻せるらしい
[アップデート] AWS BackupのAmazon S3サポートがGAになりました | DevelopersIO
https://dev.classmethod.jp/articles/update-aws-backup-support-amazon-s3/
AWS Backupの新機能、Amazon RDSのデータベースを任意の時点に戻せる「継続的バックアップ」と「Point-in-timeリカバリ」が登場 − Publickey
https://www.publickey1.jp/blog/21/aws_backupamazon_rdspoint-in-time.html
AWS 大阪リージョン - 2021年3月 誕生! | AWS (アマゾン ウェブ サービス)
https://aws.amazon.com/jp/local/osaka-region/
■ロードバランサー
※ロードバランサーを作成できる
※以前は「標準ロードバランサー」のみだったが、後から「Application Load Balancer」が追加された
「標準ロードバランサー」は現在は「Classic Load Balancer」と呼ばれている
「Application Load Balancer」は「L7のルーティング」「HTTP2対応」「WebSocketのサポート」など、色々と強化されている
今新規にロードバランサーを作成する場合、「Application Load Balancer」を選択すればいい
AWS Application Load Balancer のフロントエンド機能が凄すぎる件 | あぱーブログ
https://blog.apar.jp/web/6603/
「Application Load Balancer」に移行したからと言って、コストが跳ね上がることは無さそう。むしろ安くなるかも
計算方法自体が変わるので要確認(ELBはデータ転送量に対して課金、ALBは帯域幅に対して課金)
[AWS]CLBからALBへ移行してコストを安くする[ELB] | Developers.IO
https://dev.classmethod.jp/cloud/clb-to-alb/
※さらに後から「Network Load Balancer」が追加された
ELBは秒間2,000アクセスがいったんの限界だったが、NLBは秒間数百万リクエストに簡単に対応できるらしい
(東京リージョンでも使えるようになっている)
固定IPありとか送信元IPアドレスの保持とか暖機運転不要とか、少し見た限りではとても良さそう
SSLアクセラレーションがない、セキュリティグループの扱いが異なるなど、ALBに置き換わるものでは無いみたいが、CLBは不要になりそう
https://dev.classmethod.jp/cloud/aws/elb-network-load-balancer-static-ip-adress/
実際に導入する場合、SSLで何か問題がないかなど要確認
https://aws.amazon.com/jp/blogs/news/new-network-load-balancer-effortless-scaling-to-millions-of-req...
EC2 → ロードバランサー → ロードバランサーの作成 → Application Load Balancer
1. ロードバランサーの設定
名前: Develop
VPC: 配置したい場所に応じて選択する
アベイラビリティゾーン: AZが異なる複数のサブネットを選択する。基本的に、Webサーバ用のすべてのサブネットを選択すればいい
2. セキュリティ設定の構成
必要に応じて設定する
3. セキュリティグループの割り当て
必要に応じて、あらかじめ設定しておいた Security Group を選択
4. ルーティングの設定
適当な名前を設定する
5. ターゲットの登録
ロードバランサーから処理を振り分けるEC2インスタンスを選択(Web1とWeb2、など)
6. 確認
内容を確認して、問題なければ作成
EC2 → ロードバランサー → に、作成したロードバランサーが表示される
DNS Name でアクセスできるようになるので、セッションやデータベースを共有できているか確認する
(アクセスできるようになるまで数分かかる)
Application Load Balancer の場合、追加したインスタンスの状態は
「EC2 → ターゲットグループ」
から確認できる
以下のようにして、ロードバランサー経由でWebサーバにアクセスできる
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/pdo_mysql.php
Webサーバ1とWebサーバ2にセッションを扱うプログラムをテスト設置する
http://ec2-203-0-113-0.ap-northeast-1.compute.amazonaws.com/session.php
http://ec2-203-0-113-1.ap-northeast-1.compute.amazonaws.com/session.php
それぞれに、ロードバランサーを経由してアクセスする
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/session.php
ELBでスケールアウトする
http://www.atmarkit.co.jp/ait/articles/1407/15/news006.html
ELB配下のEC2アクセスログについてあれこれ
http://dev.classmethod.jp/etc/elb-ec2-log-x-forwarded-for/
Elastic Load Balancerの配下にApacheをぶら下げたときのログ設定
http://qiita.com/skyriser/items/a5461c726a1030ac0aa1
■プレウォーミング
もっとELB(Elastic Load Balancing)を活用する
http://dev.classmethod.jp/cloud/aws/more-elb/
まずゆるやかにトラフィックが変化する場合ですが、これはELBが得意とするパターンなので、特段の考慮事項は必要ありません。
対してピーク性の高いトラフィックを想定した負荷試験は、予めELBを最大規模に合わせてpre-warmしておく必要があります。
大量同時アクセスに備えて ELB を Pre-warming 状態にしておく
http://im-sei.tumblr.com/post/71162021812/%E5%A4%A7%E9%87%8F%E5%90%8C%E6%99%82%E3%82%A2%E3%82%AF%E3%...
自分が試した限りでは、HTTPリクエストは 2000 req/s くらいしか捌けませんでした。
また、転送量も 800 Mbps (100 MB/sec) くらいしか稼げませんでした。
AWS のビジネス以上のサポートプランに入ることで、ELB を Pre-warming (暖機) 状態にしておくサポートが受けられるようになります。
同時大量アクセスに備えて ELB を Pre-warming 状態にしておく
http://blog.uniba.jp/post/71165745511/%E5%90%8C%E6%99%82%E5%A4%A7%E9%87%8F%E3%82%A2%E3%82%AF%E3%82%B...
転送量にもよりますが、ざっくり目安で 1500 ~ 3000 req/s くらいしか捌けません。
また、公式のドキュメントによると、スケールするのに 1〜7 分かかるらしく、これまたざっくりしています。
Pre-warming した複数の ELB を Route 53 で DNS ラウンドロビンする
http://im-sei.tumblr.com/post/73601591352/pre-warming-%E3%81%97%E3%81%9F%E8%A4%87%E6%95%B0%E3%81%AE-...
「大量同時アクセスに備えて ELB を Pre-warming 状態にしておく」を参照すると
「リクエスト数 5 万 req/s、スループット 160 Mbps」で申請できたらしい
これでも足りない場合、Route53でDNSラウンドロビンを設定して、複数のELBにトラフィックを分散するという手がある
また、SSL証明書設定時にELBが止まったり…はあるので、マネージドサービスとは言え可用性の向上として有効かも
ELBの暖機運転申請
http://qiita.com/Yuki_BB3/items/d7ad81cc238b23e6fce9
アクセス数が予測できない場合は、「ELBに参加しているインスタンスの能力いっぱいまで」という依頼を行うことも可能です。
http://www.atmarkit.co.jp/ait/articles/1407/15/news006.html
AWS ALBの運用豆知識
http://blog.father.gedow.net/2017/07/19/aws-alb-knowledge/
■アクセス元IP
初期設定では、Webサーバーに記録されるアクセス元IPアドレスは、ロードバランサーのものになるので注意
(アクセス元をログに記録するには httpd.conf の編集が必要。
PHPからは HTTP_X_FORWARDED_FOR でアクセス元のIPアドレスを取得できる)
/etc/httpd/conf/httpd.conf で
LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
のように設定している箇所を以下のように変更。
(「リクエスト処理時間」「本来のアクセス元IP」「プロトコル」を記録)
LogFormat "%h %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i %{X-Forwarded-Proto}i" combined
■Basic認証
Basic認証を使用する場合、ロードバランサーからアクセスできるようにする必要があるので注意
ヘルスチェック用のファイルを、Basic認証の対象外にするなどの作業が必要になる
もしくは、以下のようにALBとLambdaでBasic認証をかけるという方法もある
ALB + Lambdaでお手軽3分ベーシック認証 - Qiita
https://qiita.com/shonansurvivors/items/422924e720eb3465b865
※HTTPとHTTPSの両方でアクセスされる可能性があるサイトの場合、
ALBのリスナー設定でHTTPとHTTPSの両方に設定する必要があるので注意
以下、実際にBasic認証の設定を試したときのメモ
ただし現在はランタイムが「Node.js 18.x」になる都合上、Lambda関数のコードを若干変更している(詳細は後述)
Lambda → 関数 → 関数の作成
関数名: BasicAuth
ランタイム: Node.js 18.x
実行ロール: 基本的なLambdaアクセス権限で新しいロールを作成
「関数の作成」ボタンをクリック
index.mjsに以下を入力(ロードバランサーにALBを使っていても、ユーザーエージェントは以下のままでいい)
export const handler = async(event, context) => {
const headers = event.headers || {};
// ALB Health check
if (headers['user-agent'] === 'ELB-HealthChecker/2.0') {
return {
statusCode: 200,
statusDescription: '200 OK',
isBase64Encoded: false,
headers: {
'Content-Type': 'text/html'
}
};
}
return {
statusCode: 401,
statusDescription: '401 Unauthorized',
body: 'Authorization Required',
isBase64Encoded: false,
headers: {
'WWW-Authenticate': 'Basic',
'Content-Type': 'text/html'
}
};
};
なお参考までに、デフォルトでは以下が入力されていた
export const handler = async(event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
古い解説では以下のようなコードになっているかもしれないが、これは古い書き方のようなので注意(関数がエラーになる)
exports.handler = async (event, context) => {
// 略
};
ページ中ほどにある「Deploy」ボタンをクリック
EC2 → ターゲットグループ → Create target group
Choose a target type: Lambda function
Target group name: basic-auth
Health checks Enable: On
Health check path: /
「Next」ボタンをクリック
Lambda function: BasicAuth(先ほど作成したものを選択)
Version: $LATEST
「Create target group」ボタンをクリック
以下のとおり、Basic認証のユーザ名とパスワードをBase64エンコードしたものを用意しておく
$ echo -n 'refirio:staging' | base64
cmVmaXJpbzpzdGFnaW5n
EC2 → ロードバランサー → Refirio-Staging-ALB → Listeners → HTTP:80 → Rules → Manage rules
画面上部の「+」をクリック
「ルールの挿入」をクリック
IF: HTTPヘッダー...
Specify header type...: Authorization
値: Basic cmVmaXJpbzpzdGFnaW5n (「Basic 」に続けて、先ほど作成したものを入力)
THEN: 転送先
ターゲットグループ: Refirio-Staging-ALB-TargetGroup
画面上部の「保存」ボタンをクリック
画面上部のペンアイコンをクリック
最後のルールの左側に表示されているペンアイコンをクリック
「THEN」に表示されているペンアイコンをクリック
転送先として先ほど作成したターゲットグループ(basic-auth)を選択
画面上部の「更新」ボタンをクリック
ブラウザからロードバランサーにアクセスし、Basic認証の動作を確認する
■ヘルスチェックのログ
初期設定では、ヘルスチェックのログが大量に記録される
Apacheの場合、httpd.confで
SetEnvIf Remote_Addr 127.0.0.1 no_log
このように設定している箇所の後に以下を追加する。
(ELBからのヘルスチェックをログに記録しない)
SetEnvIf User-Agent "ELB-HealthChecker" no_log
Route53も含めて以下で除外すると良さそう
SetEnvIf User-Agent "ELB-HealthChecker" no_log
SetEnvIf User-Agent "Amazon Route 53 Health Check Service" no_log
nginxの場合、nginx.confで以下のような設定を追加する(ファイル名は環境に合わせる)
location = /health_check.html {
access_log off;
break;
}
ELBのヘルスチェックログを出力しない | technote
http://tech.withsin.net/2016/11/16/elb-healthcheck-nginx/
もしくは以下のような対応も有効。余計なファイルを作らない分スマートか
http {
〜 略 〜
map $http_user_agent $log_ua {
~ELB-HealthChecker 0;
default 1;
}
access_log /var/log/nginx/access.log main if=$log_ua;
〜 略 〜
}
NginxのアクセスログからELBのヘルスチェックを除外する方法 - Qiita
https://qiita.com/masa1246/items/a79051a280ee2a6734c4
NginxでAWS ELBのHealth Checkログを出力させない方法 - Qiita
https://qiita.com/homoluctus/items/7f81ef8e7d23f3c18ffe
■アクセスログの有効化
ロードバランサーへのアクセスログをS3に保存する
ロードバランサーを選択し、「説明 → 属性 → アクセスログ → アクセスログの設定」で
・アクセスログの有効化
・間隔:5分
・s3の場所:s3://refirio-log/alb-logs
として保存する。
■ドメイン割り当て前のアクセステスト
AWSのロードバランサーは負荷状況によってインスタンス数が増えるため、固定IPアドレスを持たない
よって、Windowsのhostsファイルを編集するなどしてロードバランサーにアクセスしたい場合、その時点のIPアドレスを調べる必要がある
例えばロードバランサーのURLが
develop-123456789.ap-northeast-1.elb.amazonaws.com
でブラウザから
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/
でアクセスできる場合、nslookupコマンドを使って以下のようにすればロードバランサーのIPアドレスを調べることができる(digコマンドでも可)
$ nslookup develop-123456789.ap-northeast-1.elb.amazonaws.com
Server: 172.31.0.2
Address: 172.31.0.2#53
Non-authoritative answer:
Name: develop-123456789.ap-northeast-1.elb.amazonaws.com
Address: 203.0.113.1
Name: develop-123456789.ap-northeast-1.elb.amazonaws.com
Address: 203.0.113.2
この場合、ロードバランサーは 203.0.113.1 と 203.0.113.2 のIPアドレスを持つ
よって、Windowsのhostsファイルなどで
C:/windows/System32/drivers/etc/hosts
203.0.113.1 refirio.net
このように設定すると、
http://refirio.net/ でアクセスしたときにロードバランサー経由でアクセスできる
(203.0.113.1 と 203.0.113.2 のどちらを指定してもいい)
■SSLに対応させる
※無料SSL証明書を実際に試したときのメモは「Certificate Manager」を参照
※購入した証明書を使用する場合も、いったんACM(AWS Certificate Manager)に証明書をインポートしてから適用する方が良さそう
(ロードバランサーに直接登録すると、何故かエラーになることが多い。何度か試すと成功するが心臓に悪い。)
詳細は、このファイル内の「Certificate Manager」内の「証明書のインポート」を参照
※SSLを有効にすると、「HTTP/2」を無効にしないとiOSでロードバランサーにアクセスできなくなる
詳細はこのファイルの「iPhoneでAWSのロードバランサーにSSLでアクセスできない場合」を参照
ELBでは、EC2ではなくロードバランサーに対して証明書の設定を行う
443ポートでアクセスするので、まずはロードバランサーのセキュリティグループで443ポートへのアクセスを許可しておく
「EC2」 → 「セキュリティグループ」 → 設定したいセキュリティグループを選択して「インバウンド」から設定
設定できたら引き続き、ロードバランサーにSSL証明書を登録する
「EC2」 → 「ロードバランサー」 → 設定したいロードバランサーを選択して「リスナーの編集」
「HTTPS」を追加。
ロードバランサーのプロトコル : HTTPS
ロードバランサーのポート : 443
インスタンスのプロトコル : HTTPS
インスタンスのポート : 80
※ポートは「443→80」なので、Webサーバ自体にSSL証明書は不要ただし.htaccessやPHPなどでSSLの判定ができないので注意
「443→443」にする場合、Webサーバ自体に証明書の設定などが必要になると思われるので、特に理由がなければ「443→80」でいい
と設定する。さらに「SSL証明書」列の「変更」を選択。
証明書タイプ : 新規のSSL証明書をアップロードする
証明書名 : refirio.net-20161224
プライベートキー : 秘密鍵
証明書本文 : 証明書 SHA256
証明書チェーン : 中間CA証明書
※一度設定しようとするとエラーになった
エラー内容は以下のとおり
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
既存のリスナーを更新しています
既存のポートのポリシーを取得します: 443。
ポートのリスナーを削除しました: 443。
次の SSL 証明書を作成しました: refirio.net-20170410。
ポートのリスナーを作成できませんでした: 443。 Server Certificate not found for the key: arn:aws:iam::580506097674:server-certificate/refirio.net-20170410
ロールバックしています
SSL 証明書をロールバックできませんでしたarn:aws:iam::580506097674:server-certificate/refirio.net-20170410: The specified value for serverCertificateName is invalid. It must contain only alphanumeric characters and/or the following: +=,.@_-
ロールバックが失敗しました
リスナーの変更をロールバックしようとしてエラーが発生しました。ロードバランサーが不整合な状態である可能性があります。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
この時点で、サイトにSSL経由でアクセスできなくなった
再度はじめから行うと、今度は以下のエラーが表示された
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SSL 証明書を作成できませんでした: refirio.net-20170410. The Server Certificate with name refirio.net-20170410 already exists.
リスナーの更新が失敗しました。
変更は正常にロールバックされました。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ページ全体を再読み込みし、再度「リスナーの編集」で「SSL証明書」列の「変更」を選択すると、先ほどアップロードした証明書を選択できるようになった
選択して「保存」すると、SSL経由でアクセスできるようになった
証明書をアップロードしてから実際に使えるようになるまで、若干のタイムラグがあるとか?証明書登録後、5分程度時間を置いてから証明書を選択するとどうか
右クリックで「リスナーの編集」ではなく、ロードバランサーを選択して画面下の「リスナー」から設定するといいとか?
2019年5月時点でも上記の問題が発生するが、原因は特定できていない
【初心者向け】ELBにSSL証明書をインストールする
http://dev.classmethod.jp/cloud/aws/aws-beginner-elb-ssl/
AWSのELBでSSLの証明書を設定する方法(2015年5月版)
http://liginc.co.jp/web/programming/server/164756
どうやら現時点では、コマンドラインからでないと確実に更新できないみたい?
それでも何度も試すとできることがあるのは謎
既存の ELB に SSL 証明書を追加しようとすると Server Certificate not found for the key というエラーになる件の解決方法
http://qiita.com/ynii/items/694d60614b98f73f780f
ELBに証明書を登録できない時はAWS CLIを試す
https://saku.io/use-aws-cli-to-upload-certs-on-elb/
■複数ドメインのSSL証明書を扱う
ALBは対応可、ELBは対応不可…みたい
ALBでの複数証明書は今は対応しているが、設定反映には若干のタイムラグがあるかもしれない(10〜20分程度反映されないことがあったが、他の要因の可能性もある)
ALBで複数SSL証明書 - ナレコムAWSレシピ
https://recipe.kc-cloud.jp/archives/10771
ALBで複数のSSL/TLS証明書を設定できるSNIに対応しました | Developers.IO
https://dev.classmethod.jp/articles/alb-support-sni/
Application Load BalancerがSNIを利用した複数のTLS証明書のスマートセレクションをサポートしました | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/new-application-load-balancer-sni/
ACM を使用して ELB に複数ドメインの証明書をアップロードする
https://aws.amazon.com/jp/premiumsupport/knowledge-center/acm-add-domain-certificates-elb/
複数ドメインのSSL証明書を1つのELB上で扱えますか?
https://forums.aws.amazon.com/thread.jspa?threadID=239338
複数の証明書を1つのELB上で扱うことはできない。ワイルドカードの証明書を使うなどする必要がある
■iPhoneでAWSのロードバランサーにSSLでアクセスできない場合
ALBにてSSLを有効にすると、iOS・macOSでのみ一部画像が読み込めなかったりそもそもページが表示されなかったりする
Apache から出力された Upgrade header がプロキシ経由でブラウザに届くと、失敗したりコネクションを破棄したりしてしまうらしい
解決方法としては、Upgrade header を送らないようにすればいい
EC2 → ロードバランサー → ロードバランサーを選択
説明タブの「属性」で「HTTP/2」が有効になっていたら無効にする
AWS(Amazon Web Services) - iPhoneでAWS上のサイトが見れない|teratail
https://teratail.com/questions/163592
AWSで構築したWebサイトがiPhoneで開けないときに試すこと - Qiita
https://qiita.com/lmatsul/items/b221455b3fd31ac1cc3b
iOS 11, macOS Hight Sierra で The operation couldn't be completed. Protocol error が出る場合の対処 - Qiita
https://qiita.com/ameyamashiro/items/8d4be0f11ffe12472052
■複数のSSL証明書を設定する
Etcetera.txt の「1サーバに複数のSSL証明書を設定する」を参照
■SSLにリダイレクトさせる(CloudFront)
このファイルの「CloudFront」の「SSLにリダイレクトさせる」を参照
■SSLにリダイレクトさせる(ALB)
今はALBだけでSSLの強制ができる
リダイレクトループなどに悩まされることも無いので、この方法で設定するのが無難そう
EC2 → ロードバランサー → ロードバランサーを選択 → リスナー
「HTTP: 80」の「ルールの表示/編集」
「+」をクリックし、表示された「ルールの挿入」をクリック
「IF」で「パス」を選択して「*」を入力
「THEN」で「リダイレクト先」を選択して「HTTPS」「443」「デフォルトホスト、パス、クエリを使用」「301 - 完全に移動しました」を選択
ひととおり設定したら、画面上部の「保存」をクリックする
すぐにリダイレクトが反映された
$ curl -I
http://refirio.net/
HTTP/1.1 200 OK
Date: Mon, 15 Apr 2019 02:15:54 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Server: Apache/2.4.37 ()
X-Powered-By: PHP/7.1.25
Upgrade: h2,h2c
$ curl -I
http://refirio.net/
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Mon, 15 Apr 2019 02:17:50 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Location:
https://refirio.net:443/
[新機能]Webサーバでの実装不要!ALBだけでリダイレクト出来るようになりました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/alb-redirects/
■SSLにリダイレクトさせる(Apache)
一台構成のサーバなら、以下のような .htaccess で対応できる
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$
https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
ただしELBを使う場合、上記の方法ではリダイレクトループになる
代わりに、以下のような .htaccess で対応できる
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Port} !^443$
RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker
RewriteCond %{REQUEST_URI} !=/server-status
RewriteCond %{HTTP:X-FORWARDED-FOR} !^$
RewriteRule ^(.*)?$
https://%{HTTP_HOST}$1 [R=301,L]
ELB配下のApacheで外部はHTTPSにリダイレクトし、内部のサーバのみHTTPで通信させる - Qiita
https://qiita.com/wapa5pow/items/a5c4fc188e5da0ddde1d
AWS EC2で常時SSLを実現する際の注意点 - Qiita
https://qiita.com/michimani/items/88973c5e2ae76a8e84aa
AWSのELBとNginxでhttpアクセスをhttpsにリダイレクトしたい - Qiita
https://qiita.com/snoguchi/items/f5ccb67592f87942480d
■SSLにリダイレクトさせる(nginx)
一台構成のサーバなら、nginxの設定ファイルに以下のような設定を追加して対応できる
# vi /etc/nginx/nginx.conf
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
ssl on;
# ...
}
nginx で http でのアクセスを https にリダイレクト - Qiita
https://qiita.com/kga/items/e30d668ec1ac5e30025b
ELBを使う場合、nginxの設定ファイルに以下のような設定を追加して対応できる
# vi /etc/nginx/nginx.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
#server_name localhost;
server_name refirio.net;
#root /usr/share/nginx/html;
root /var/www/vhosts/refirio/html;
if ($http_x_forwarded_proto = 'http') {
return 301 https://$server_name$request_uri;
}
ELBを使用してHTTPトラフィックをHTTPSにリダイレクトする
https://aws.amazon.com/jp/premiumsupport/knowledge-center/redirect-http-https-elb/
■別のコンテンツ(ドメイン)にリダイレクトさせる
EC2側で行わなくても、ALBだけで別ドメインや別ディレクトリにリダイレクトできる
ロードバランサーはマネージドサービスなので、サーバの死活監視などが不要な分使い勝手が良さそう
以下は www.refirio.net にアクセスされたときに、refirio.net へリダイレクトさせる例
EC2 → ロードバランサー → ロードバランサーを選択 → リスナー
「HTTP: 443」の「ルールの表示/編集」
「+」をクリックし、表示された「ルールの挿入」をクリック
「IF」で「ホストヘッダー」を選択して「www.refirio.net」を入力
「THEN」で「リダイレクト先」を選択して「HTTPS」「443」「カスタムホスト、パス、クエリを使用」を選択
「ホスト」に「refirio.net」を入力。「パス」と「クエリ」は変更せず
「301 - 完全に移動しました」を選択
ひととおり設定したら、画面上部の「保存」をクリックする
すぐにリダイレクトが反映された
[新機能]Webサーバでの実装不要!ALBだけでリダイレクト出来るようになりました! | Developers.IO
https://dev.classmethod.jp/articles/alb-redirects/
[AWS]ALBだけで別ドメインにリダイレクトする - ADACHIN SERVER LABO
https://blog.adachin.me/archives/10697
ALBでwwwなし→wwwありへのリダイレクトを設定する - ハマログ
https://blog.e2info.co.jp/2020/06/13/alb%E3%81%A7http%E2%86%92https%E3%81%B8%E3%81%AE%E3%83%AA%E3%83...
【AWS】ALBのリスナールールでリダイレクトを設定する - ポンコツ.log
https://www.ponkotsu-log.com/entry/2019/04/27/012155
■スティッキーセッション
セッションをElastiCacheやデータベースに保存できない場合、一度アクセスしたサーバに一定時間アクセスさせ続ける必要がある
その場合はスティッキーセッションを有効にする
「EC2 → ターゲットグループ → 設定したいグループを選択して → 説明 → 属性の編集」
「維持設定」を「ロードバランサーによって生成された Cookie の維持を有効化」に変更
「維持設定の期間」は、「1日間」のままで保存
反映まで1分ほどのタイムラグがあるみたい
Classic Load Balancer の場合は設定箇所が違うので、以下を参照
【基礎から学ぶ】ELBのスティッキーセッションについてまとめてみた - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2017/01/05/elb-sticky/
■セキュリティポリシーを変更する
※未検証
デフォルトでは「ELBSecurityPolicy-2016-08」が選択されているが、
例えばTLSバージョンを1.2に固定したければ「ELBSecurityPolicy-TLS-1-2-2017-01」に変更する
(ただしTLS1.0しか使えないブラウザではアクセスできなくなるので、要件に合わせて慎重に検討する
最近のブラウザはTLS1.2に対応しているが、古いブラウザでは対応していないものがある)
変更する場合、
「EC2 → ロードバランサー → 設定したいロードバランサーを選択して → リスナー → 『HTTPS : 443』を編集」
とし、リスナーの編集画面で「セキュリティポリシー」を変更する
ELB のセキュリティポリシー変更はブラウザの対応プロトコルを考慮して慎重に | DevelopersIO
https://dev.classmethod.jp/articles/sugano-028-security/
AWS Classic Load BalancerのTLSバージョンを1.2に固定する方法 - 株式会社Japonline
https://www.japon-line.co.jp/tech/aws-elastic-load-balancer%E3%81%AEtls%E3%83%90%E3%83%BC%E3%82%B8%E...
Template:ウェブブラウザにおけるTLS/SSLの対応状況の変化 - Wikipedia
https://ja.wikipedia.org/wiki/Template:%E3%82%A6%E3%82%A7%E3%83%96%E3%83%96%E3%83%A9%E3%82%A6%E3%82%...
■カナリアリリース
※未検証
[激アツアップデート]ALBだけでカナリアリリース(重み付け)ができるようになりました! | Developers.IO
https://dev.classmethod.jp/cloud/aws/alb-blue-green-deployment/
近年のデプロイ手法について|clonos|Google Cloud Platform の導入支援、構築、監視、運用代行
https://clonos.jp/knowledge/detail14/
■キャッシュ
対応していないので、nginxを併用するなどが必要
Nginx + WordPress ロードバランサー篇
http://blog.serverworks.co.jp/tech/2012/09/28/nginx-04/
■Certificate Manager
自動更新される無料SSL証明書を利用できる
・秘密鍵は取り出せない(AWSにしか使えない)
・ELBかCloudFrontの導入が必要(CloudFrontへの導入は注意が必要みたい)
・ドメイン認証(DV)のみ対応。実在認証(EV)、組織認証(OV)証明書の発行には対応していない
・暗号化方式の変更はできない(古いガラケーに対応できない)
・サイトシールは発行されない(勝手にそれらしいものを作るのも禁止されている)
・認証局はAmazonになる
・ドメイン所有者の確認はドメイン管理者宛のメールのみ…だったが、後にDNS認証が追加された
などに問題なければ、利用を検討する
[ACM] SSL証明書発行時のドメイン認証メールをSESで受け取ってみた
http://dev.classmethod.jp/cloud/aws/acm-verifydomain-ses/
[ACM]AWSの無料SSL証明書サービスCertificate Manager について調べてみた
http://dev.classmethod.jp/cloud/aws/check_acm_specification/
[AWS Certificate Manager]東京でも無料でSSL証明書が使用可能になりました!
http://dev.classmethod.jp/cloud/aws/acm-available-in-tokyo/
AWS Certificate Manager が発行するサーバ証明書を調べてみた
http://blog.manabusakai.com/2016/01/aws-certificate-manager/
ELBの場合はいいが、CloudFrontを使う場合は問題があるみたい
対処方法はあるが、その場合静的なコンテンツしか配信できないみたい
現時点では、証明書の導入先はロードバランサーの一択になりそう
ACMでSSL証明書0円運用ができなかったはなし
http://qiita.com/seiyakubo/items/4bdf7680d677ef7dc327
■証明書の発行
Certificate Manager → 証明書のプロビジョニング → 今すぐ始める
「パブリック証明書のリクエスト」を選択して「証明書のリクエスト」をクリック
ステップ 1: ドメイン名の追加
*.refirio.net と refirio.net ... ワイルドカードの場合(サブドメインなしのドメインも対象にする場合、ドメインを別途追加する)
www.refirio.net ... 特定のサブドメインのみの場合
「この証明書に別の名前を追加」をクリックして他のサブドメインを追加できる
「次へ」をクリック
ステップ 2: 検証方法を選択する
今回は「Eメールの検証」を選択して進む
(2017年11月に「DNSの検証」が追加された。これからは基本的に「DNSの検証」を利用すれば良さそう。メールの場合は1年に1回更新作業が必要だが、DNSの場合は自動更新される)
ステップ 3: タグを追加
必要に応じて設定し「確認」をクリック
ステップ 4: 確認とリクエスト
入力内容を確認して「確定とリクエスト」をクリック
ステップ 3: 検証
検証するために、以下にメールが送信されると確認される
*.refirio.net
administrator@refirio.net
webmaster@refirio.net
privacy@whoisprivacyprotection.info
hostmaster@refirio.net
postmaster@refirio.net
admin@refirio.net
refirio.net
administrator@refirio.net
webmaster@refirio.net
privacy@whoisprivacyprotection.info
hostmaster@refirio.net
postmaster@refirio.net
admin@refirio.net
「続行」をクリック
検証方法で「DNSの検証」を選択した場合、CNAMEレコードに指定の設定を行う
Route53を使用している場合、「検証」画面でドメインをクリックして表示される「Route 53 でのレコードの作成」をクリックするだけで完了する
(もしくは、証明書一覧でドメインをクリックすると、その中に「Route 53 でのレコードの作成」がある)
5分ほど待つと、検証済みになった
Route53以外のサービスでDNSを管理している場合、そのサービスの画面から設定を行う
「_7dc57e806da3de4055c5cb63f4dc14e2」のようなサブドメインを作成し、指定された内容を記述することになる
ACM証明書発行をDNS検証で行う【エンジニアブログより】 | 株式会社サーバーワークス's Blog
https://www.wantedly.com/companies/serverworks/post_articles/101309
ただし、サブドメインの先頭に「_」を指定できないサービスの場合は認証できないので注意(大塚商会など)
と思ったけど、単純に先頭の「_」を省略して登録すればいいみたい
ACM の DNS 認証を Route 53 以外で設定するときに覚えておくと良いこと:値のアンダースコア(「_」)は無くてもOKです! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/acm-dns-validation-without-underscore/
検証方法で「Eメールの検証」を選択した場合、S3のSES用ディレクトリにメールが保存されていることを確認する
今回は admin@refirio.net 宛のメールが届いた
privacy@whoisprivacyprotection.info はwhoisに登録されたドメインの管理者だと思われる
これは受け取れないので、あらかじめメールの受信環境構築は必要
メール内に記載されているURLから認証する
認証後、証明書の「状況」が「発行済み」になる
DNS検証でACMでのSSL/TLS証明書を発行する | MMMブログ
https://blog.mmmcorp.co.jp/blog/2018/01/26/acm_dns_validation/
ACM証明書発行をDNS検証で行う - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2017/12/04/acm-dns/
■証明書のインポート
別途購入したSSL証明書をインポートできる
いきなりロードバランサーに証明書を登録するとエラーになったときが怖いが、これなら稼働中の環境に影響なく取り込める
Certificate Manager → 証明書のインポート
ステップ 1: 証明書のインポート
証明書本文: 発行された「証明書 RSA/SHA-256」を入力
証明書のプライベートキー: 作成した秘密鍵を入力
証明書チェーン: 発行された「中間証明書」を入力
「次へ」をクリック
ステップ 2: タグを追加
特に何も入力せず「レビューとインポート」をクリック
ステップ 3: レビューとインポート
登録内容を確認して「インポート」をクリック
ACMの証明書インポートとELBのSSLリスナー追加
http://dev.classmethod.jp/cloud/aws/acm_import_elb_ssl_listener/
■証明書の適用(ロードバランサーに導入したとき)
EC2 → ロードバランサー → (対象のロードバランサーを選択) → リスナー → リスナーの追加
プロトコル: HTTPS(セキュアHTTP)
ポート: 443
デフォルトアクション: 転送先 → 作成したロードバランサーを選択
デフォルトの SSL 証明書: ACMから(推奨) → 発行された証明書を選択
「保存」をクリック
SSL経由でアクセスできることを確認する(すぐにアクセスできるようになった)
https://refirio.net/
https://www.refirio.net/
アクセスできない場合、セキュリティグループでロードバランサーへのアクセスを禁止していないか確認する
■証明書の適用(ロードバランサーに複数の証明書を導入したとき)
ALBはSNIに対応しているので、複数のSSL証明書を導入できる
ALBで複数のSSL/TLS証明書を設定できるSNIに対応しました | DevelopersIO
https://dev.classmethod.jp/articles/alb-support-sni/
1つのALBで複数のサイトを作る - インフラ(AWS)とアプリ開発
https://rikues2012.hatenablog.com/entry/2021/10/15/195627
上記のとおり対応しているが、今は画面が変わっている
以下、実際に試したときのメモ
EC2 → ロードバランサー → (対象のロードバランサーを選択) → リスナー → HTTPS:443 → Certificates → Listener certificates for SNI → Add certificate
追加導入したい証明書にチェックを入れ、「Include as pending below」ボタンをクリック
下の「Listener certificates for SNI」に追加されることを確認する(下の一覧には2つが表示された状態になる)
その状態で「Add pending certificates」をクリック
この状態だと、もともと証明書がデフォルトの証明書として扱われている
支障は無いかもしれないが、追加導入した証明書をデフォルトに変更しておく
EC2 → ロードバランサー → (対象のロードバランサーを選択) → リスナー → HTTPS:443 → Certificates → Change default
デフォルトにしたいドメインを選択して「Save as default」をクリック
■証明書の適用(インポートした証明書をクラシックロードバランサーに差し替え導入したとき)
EC2 → ロードバランサー → (対象のロードバランサーを選択) → リスナー → HTTPS「SSL証明書」列の「変更」をクリック
証明書タイプ: ACM から証明書を選択する (推奨)
証明書: (先の手順でインポートした証明書を選択)
「保存」をクリック
■証明書の適用(インポートした証明書をアプリケーションロードバランサーに差し替え導入したとき)
EC2 → ロードバランサー → (対象のロードバランサーを選択) → リスナー → HTTPS行にチェックを入れて「編集」をクリック
デフォルトのSSL証明書: ACM から (推奨) → (先の手順でインポートした証明書を選択)
「保存」をクリック
■証明書の発行(CloudFrontに導入したとき)
CloudFrontに設定するので、操作リージョンをあらかじめ「バージニア北部」に変更
Certificate Manager → 今すぐ始める
ステップ 1: ドメイン名の追加
*.refirio.net と refirio.net ... ワイルドカードの場合
www.refirio.net ... 特定のサブドメインのみの場合
「この証明書に別の名前を追加」をクリック
「次へ」をクリック
ステップ 2: 検証方法を選択する
今回は「Eメールの検証」を選択して進む
ステップ 3: 確認とリクエスト
内容を確認して進む。メールが飛ぶ
メール内に記載されているURLから認証する
認証後、証明書の「状況」が「発行済み」になる
■証明書の適用(CloudFrontに導入したとき)
CloudFront → 対象のIDを選択 → General → Edit
「SSL Certificate」を「Custom SSL Certificate (example.com)」
に変更し、下のテキストボックスから先ほど発行した証明書を選択する
「Yes, Edit」をクリック
SSL経由でアクセスできることを確認する(すぐにアクセスできるようになった)
https://refirio.net/
https://www.refirio.net/
■証明書の更新(「DNSの検証」で導入した場合)
※証明書は自動で更新されるので、特に作業は不要
「Your certificate is renewed」という件名で、以下のメールが届いた
SSL証明書の有効期限を確認すると一年伸びていた
Greetings from Amazon Web Services,
This is to notify you that AWS Certificate Manager (ACM) has completed the renewal of an SSL/TLS certificate that certificate includes the primary domain *.refirio.net and a total of 2 domains.
AWS account ID: 123456789012
AWS Region name: ap-northeast-1
Certificate identifier: arn:aws:acm:ap-northeast-1:123456789012:certificate/9cf0027d-87ca-4cf0-82d9-d8c1419ceb2c
Your new certificate expires on Apr 15, 2020 at 12:00:00 UTC.
If you have questions about this process, please use the Support Center at
https://console.aws.amazon.com/support to contact AWS Support. If you don’t have an AWS support plan, post a new thread in the AWS Certificate Manager discussion forum at
https://forums.aws.amazon.com/forum.jspa?forumID=206
This notification is intended solely for authorized individuals for *.refirio.net. To express any concerns about this notification or if it has reached you in error, forward it along with a brief explanation of your concern to validation-questions@amazon.com.
Sincerely,
Amazon Web Services
Amazon Web Services, Inc. is a subsidiary of Amazon.com, Inc. Amazon.com is a registered trademark of Amazon.com, Inc. This message was produced and distributed by Amazon Web Services Inc., 410 Terry Ave. North, Seattle, WA 98109-5210
■証明書の更新(「Eメールの検証」で導入した場合)
※証明書は自動で更新されないので、期限が切れる前に作業を行う
Certificate Manager のページで、作業したい証明書に対して
「アクション → 検証Eメールの再送信」
を実行する
以下の確認が表示されたので、送信ボタンを押した
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
[再送信] をクリックすると、新しい検証 E メールが送信されます。
登録所有者または承認された担当者は、E メールの本文にある指示に従って、ドメイン名の管理権限を検証し、証明書を承認できます。
www.refirio.net
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
以下のメッセージが表示された
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
成功
この証明書について新しい検証 E メールをお送りしました。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
「Certificate renewal for www.refirio.net requires approval」のような件名でメールが届くので、届いたメールで承認作業を行う
AWSのCertificate Managerですぐに確認しても変化はなく、対象ページのSSL証明書期限も変わっていなかった
が、2〜3日程度様子を見ると有効期限が伸びていた
結構タイムラグがあるみたい(その後試すと、1時間程度で反映されたこともあった)
ACMのSSL証明書期限が切れたので対応する - Qiita
https://qiita.com/ezaqiita/items/70cfb11fafa1d5eed59e
メール検証でACMの証明書の更新を行う - 商売力開発ブログ
https://www.prj-alpha.biz/entry/2018/07/14/003815
■サイトシール
サイトシールは発行されない
勝手にそれらしいものを作るのも禁止されている
よくある質問 - AWS Certificate Manager(簡単に SSL/TLS 証明書を作成、管理、配置) | AWS
https://aws.amazon.com/jp/certificate-manager/faqs/
Q: ACM では、ウェブサイトで表示できるセキュアサイトシールやトラストロゴを利用できますか?
いいえ。サイトシールが必要な場合は、サードパーティベンダーから入手できます。
サイトのセキュリティ、ビジネス手法、またはその両方を評価し、それについて証言してくれるベンダーを選択することをお勧めします。
Q: Amazon の商標やロゴを、証明書バッジ、サイトシール、またはトラストロゴとして使用できますか?
いいえ。このようなシールやバッジは、ACM サービスを使用していないサイトにコピーされたり、虚偽の信頼を確立するため不当に使用されたりするおそれがあります。
Amazon のお客様と評価を保護するため、このような方法でロゴを使用することは禁止されています
■お名前.com を例にした参考手順
お名前.com で取ったドメインを使う - Qiita
https://qiita.com/megane42/items/df84f87c0bdcdd015eb6
初心者でも簡単!お名前.comのDNSサーバーを利用する方法 - 既視感ある日々
https://www.dejavuz.com/computer/onamae-com-dns.html
お名前.comでドメインを取得して、AWSで管理して、色々やってみる - Qiita
https://qiita.com/wannabe/items/17060e244c50d5b467cb
EC2+ACM+ALB+お名前.comで設定をしてサブドメインでhttps接続できるようになるまでひととおり - owani.net#markdown
https://owani.net/aws/ec2-acm-alb/768/
DNS関連機能の設定:DNSレコード設定|お名前.com Navi ガイド|ドメイン取るならお名前.com
https://www.onamae.com/guide/p/70
■DNSラウンドロビン
未検証
Amazon Route53編〜Route53でラウンドロビン(simple/weighted)〜
http://recipe.kc-cloud.jp/archives/748
Route53だけでロードバランシング | A Convenient Engineer's Note
http://blog.memolib.com/memo/712/
■NAT
未検証
AWS NATは検証した(「AWS NAT」の項目を参照)
プライベートなサブネットからインターネットに接続したり
Webサーバが複数台構成でも、外へ出て行く際のIPアドレスを統一(固定)したり
NATの冗長化まで考えると大変なので、今なら後述の「AWS NAT」を使う方が管理が楽
natテーブルを利用したLinuxルータの作成 (1/6):習うより慣れろ! iptablesテンプレート集(2) - @IT
http://www.atmarkit.co.jp/ait/articles/0505/17/news131.html
AWS NATインスタンスを作成したメモ - Qiita
https://qiita.com/hc_isobe/items/3520173b1065aeae884b
AWS NAT構成の作り方(NATインスタンス編) - Qiita
https://qiita.com/TK1989/items/ece84500ee87d2d96c4b
■AWS NAT
NATゲートウェイを作成できる
できることは前述の「NAT」と同じだが、AWSのマネージドサービスなので可用性が高い
利用料金や帯域幅については、使用する際に改めて確認する
【新機能】ついに登場!Amazon VPC NAT GatewayでNATがAWSマネージドに
http://dev.classmethod.jp/cloud/aws/introduce-to-amazon-vpc-nat-gateway/
Amazon VPCにNAT Gatewayが追加されたので試してみた
http://yoshidashingo.hatenablog.com/entry/2015/12/18/041217
AWS NAT構成の作り方(NATゲートウェイ編) - Qiita
https://qiita.com/TK1989/items/5d9bd5d49708c02dff3f
AWS NATインスタンスを作成したメモ - Qiita
https://qiita.com/hc_isobe/items/3520173b1065aeae884b
NAT Gatewayによるアクセス元IPアドレスの固定 | DevelopersIO
https://dev.classmethod.jp/articles/fix-sender-ip-address-with-nat-gateway/
【AWS】NATゲートウェイとインターネットゲートウェイの違い - Hanatare's PaPa
https://www.hanatare-papa.jp/entry/technology-aws-natgateway-1-446
NATゲートウェイ構成時の注意事項 | Oji-Cloud
https://oji-cloud.net/2019/09/19/post-3085/
以下、環境構築の検証。以下のような環境を作成する
・VPCはパブリックとプライベートのサブネットを持つ
・パブリックなサブネットに踏み台サーバ、プライベートなサブネットにWebサーバを置く
・WebサーバにSSHでアクセスする場合、踏み台サーバを経由する
・Webサーバにブラウザでアクセスする場合、ロードバランサーを経由する
ロードバランサーを経由しないブラウザアクセス(テスト時など)は、ポートフォワーディングを使用する
・プライベートなサブネットに置かれたWebサーバからインターネットにアクセスする場合、NATゲートウェイを経由する
■VPC環境の作成
このテキストの「VPC」の項目をもとに
・VPCの作成
・サブネットの作成
・インターネットゲートウェイの作成
・ルートテーブルの作成
・セキュリティグループの作成
を行う(RDSやElastiCache用のVPC設定も、必要に応じて行う)
ここまでは通常のVPC作成と同じ
以降はNAT環境のための手順
■踏み台サーバの作成
踏み台用にEC2を作成する
自動割り当てパブリックIPは「有効化」にする。もしくはEIPを割り当てる(外部からアクセスできるようにする)
名前は今回は「Develop-Bastion」とする。EIPは 203.0.113.1 とする
ここではテストのために、まずは最低限Webサーバとして使えるようにする(NATの利用にWebサーバは必須ではない)
あらかじめセキュリティグループで、22番ポートと80番ポートのアクセスを許可しておく
・SSHでサーバ 203.0.113.1 に接続
・必要に応じて日本語設定にしておく
・必要に応じてホスト名を設定しておく(デフォルトでは「ip-10-1-0-87」のようなホスト名。このままでもいい)
・必要に応じてタイムゾーンを設定しておく
・以降は以下を設定
# yum -y install nginx
# service nginx start
# chkconfig nginx on
ブラウザで以下にアクセスできることを確認する
http://203.0.113.1/
SSHの設定ファイルを以下のようにしておけば、「ssh refirio-dev」でアクセスできる
Host refirio-dev
Hostname 203.0.113.1
User ec2-user
IdentityFile C:/Users/refirio/Documents/SSH/refirio/AWS.pem
IdentitiesOnly yes
■NATゲートウェイの作成
VPC → NATゲートウェイ → NATゲートウェイの作成
サブネット: Develop-DMZ-A(作成済みのパブリックなサブネットを選択する)
Elastic IP 割り当て ID: (作成済みのEIPを設定するか、新しく作成する)
と入力してNATゲートウェイを作成する
VPC → ルートテーブル → ルートテーブルの作成
名前タグ: Develop-NAT
VPC : Develop
と入力してルートテーブルを作成する
作成したルートテーブルの「ルート」を編集し、以下を追加する
接続先: 0.0.0.0/0
ターゲット: (作成したNATゲートウェイ)
これで、ルートテーブルに設定されていないIPアドレス宛てのすべてのパケットは、作成したNATゲートウェイに向く
VPC → サブネット
作成済みのプライベートなサブネットを選択し、各サブネットの「ルートテーブル」を上で作成したものに変更する
※NATゲートウェイは、作成してもしばらくは「保留中」となって割り当てたEIPも表示されない
この状態だとNATとして機能していない
5〜10分程度待つと「使用可能」になり、EIPも表示される
■NATゲートウェイの動作確認
パブリックなサーバからtracerouteを試す
curlなどで外部のサーバにアクセスすると、アクセス先のサーバのログにはEC2のIPアドレスが記録されている
$ traceroute www.google.com
traceroute to www.google.com (172.217.25.68), 30 hops max, 60 byte packets
1 ec2-175-41-192-146.ap-northeast-1.compute.amazonaws.com (175.41.192.146) 17.190 ms ec2-175-41-192-148.ap-northeast-1.compute.amazonaws.com (175.41.192.148) 13.897 ms ec2-175-41-192-154.ap-northeast-1.compute.amazonaws.com (175.41.192.154) 17.141 ms
2 100.64.2.206 (100.64.2.206) 13.185 ms 100.64.1.206 (100.64.1.206) 13.061 ms 100.64.2.10 (100.64.2.10) 14.259 ms
3 100.66.2.98 (100.66.2.98) 21.632 ms 100.66.2.10 (100.66.2.10) 17.852 ms 100.66.3.98 (100.66.3.98) 14.524 ms
〜以下略〜
プライベートなサーバからtracerouteを試す
NATゲートウェイのプライベートIPは 10.0.0.154 なので、NATを通じて外にアクセスしていることが分かる
curlなどで外部のサーバにアクセスすると、アクセス先のサーバのログにはNATのパブリックIPアドレスが記録されている
$ traceroute www.google.com
traceroute to www.google.com (172.217.24.132), 30 hops max, 60 byte packets
1 10.0.0.154 (10.0.0.154) 0.244 ms 0.237 ms 0.222 ms
2 ec2-175-41-192-148.ap-northeast-1.compute.amazonaws.com (175.41.192.148) 20.865 ms ec2-175-41-192-144.ap-northeast-1.compute.amazonaws.com (175.41.192.144) 18.352 ms ec2-175-41-192-148.ap-northeast-1.compute.amazonaws.com (175.41.192.148) 20.835 ms
3 100.64.3.14 (100.64.3.14) 16.225 ms 100.64.2.12 (100.64.2.12) 16.641 ms 100.64.1.202 (100.64.1.202) 13.434 ms
〜以下略〜
■Webサーバの作成
名前は今回は「Develop-Web1」とする。プライベートIPは 10.0.2.63 とする
まずは最低限Webサーバとして使えるようにしておく
踏み台サーバからHTTPリクエストを送り、Webサーバにアクセスできることを確認する
$ curl
http://10.0.2.63/
SSHの設定ファイルを以下のようにしておけば、「refirio-dev-web1」でアクセスできる
(Poderosaは多段接続に対応していないようなので、Git Bash や ConEmuで試した)
Host refirio-dev
Hostname 203.0.113.1
User ec2-user
IdentityFile C:/Users/refirio/Documents/SSH/refirio/AWS.pem
IdentitiesOnly yes
Host refirio-dev-web1
Hostname 10.0.2.63
User ec2-user
IdentityFile C:/Users/refirio/Documents/SSH/refirio/AWS.pem
IdentitiesOnly yes
ProxyCommand ssh refirio-dev -W %h:%p
■ポートフォワーディングで確認
Git Bash で以下を実行してポートフォワーディング
ブラウザから
http://localhost/ にアクセスすると、Develop-Web1 サーバの内容が表示される
$ ssh -fNCL 0.0.0.0:80:localhost:80 refirio-dev-web1
■ロードバランサーの作成
以降は通常の手順で大丈夫のはず
■S3
※可用性の高い、オンラインストレージ(ファイルサーバ)を利用できる
「S3 → バケットを作成」からバケットを作成
バケット名: refirio
リージョン: アジアパシフィック(東京)
パブリックアクセス設定: 各チェックを外して公開
バケットポリシー:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::refirio/*"
}
]
}
※Bucket Name は「net.refirio.images」「net.refirio.backup」のように、URLをベースにすると他と重複しなくていいかもしれない
問題なければ「バケット」ボタンを押す
■S3のファイルを直接公開しない
Amazon S3 → happy-ring-production → アクセス許可 → ブロックパブリックアクセス (バケット設定) → 編集
で「パブリックアクセスをすべて ブロック」にチェックを入れて保存した
つまり、S3の画像を直接公開しないようにした
■サーバサイドプログラムからS3にファイルをアップロード
画面右上のアカウント名 → マイセキュリティ資格情報 → Delete your root access keys → Manage Security Credentials
Your Security Credentials ページの Access Keys (Access Key ID and Secret Access Key) でアクセスキーを作成できるので、控えておく
http://j-caw.co.jp/blog/?p=1100 などを参考に、S3にファイルをアップロードできるプログラムを作成して動作確認する
インスタンス一覧からインスタンスを選択し、指定したフォルダ内に指定したファイルをアップロードできているか確認する
ファイルを選択し、Properties → Link で、実際にアップロードされたファイルにアクセスできる
Access Key ID : XXXXX
Secret Access Key : YYYYY
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/s3/
ただし基本的にルートキーは使用せず、限定的な権限を持つユーザーを作成することを推奨
画面右上のアカウント名 → マイセキュリティ資格情報 → ユーザー → ユーザーを追加
ユーザー名: refirio-production
アクセスの種類: プログラムによるアクセス
アクセス権限を設定: 既存のポリシーを直接アタッチ
のようにして、「EC2とS3にだけアクセスできる」のように作成する
awsのs3を操作する為のaccess keyとsecret keyを取得する(IAM) - joppot
https://joppot.info/2014/06/14/1621
ユーザーをいくつも作成する場合、権限をグループで管理するといい
AWSアクセスキー作成 - Qiita
https://qiita.com/miwato/items/291c7a8c557908de5833
PHPプログラムからS3にアップロードする場合、バケットの
「アクセス権限 → パブリックアクセス設定 → 編集」
で各チェックを外して「保存」とすると、SDKでアップロードする際
$client = S3Client::factory(array(
'key' => 'XXXXX',
'secret' => 'YYYYY',
));
$result = $client->putObject(array(
'ACL' => 'public-read',
'Bucket' => 'refirio-staging',
'Key' => 'images/photo01.jpg',
'Body' => file_get_contents('images/photo01.jpg'),
));
のように「ACL」を「public-read」にすればファイルを公開できる
また、バケットのプロパティの
「アクセス許可 → バケットポリシー」で以下を登録すると、「ACL」を「public-read」に指定しなくてもファイルがデフォルトで公開される
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::バケット名/*"
}
]
}
HDDに保存するのはもう古い!Amazon S3を使ってみたら簡単便利すぎてHDDが蒸発した
http://www.4-fusion.jp/randd/2013/05/08/hdd-old-amazon-s3-easy/
AWS SDK for PHPを使ってS3にファイルをアップロードする
http://j-caw.co.jp/blog/?p=1100
Installing via Composer
http://docs.aws.amazon.com/aws-sdk-php/guide/latest/installation.html
AWS SDK for PHP
http://aws.amazon.com/jp/sdkforphp/
Amazon S3 でバケット配下を全て public read にする
http://www.bokukoko.info/entry/2015/02/03/Amazon_S3_%E3%81%A7%E3%83%90%E3%82%B1%E3%83%83%E3%83%88%E9...
■画像の表示
※未検証
S3に配置した画像のURLに直接アクセスすると、ダウンロードダイアログが表示される
(imgタグで呼び出せば普通に画像が表示される)
AWSコンソールからオブジェクトのプロパティを確認すると、「メタデータ」に以下が設定されている
これがデフォルト値だと思われる
タイプ: システム定義
キー: Content-Type
値: binary/octet-stream
例えば画像がJpegの場合、以下のように設定することで、画像のURLに直接アクセスするとブラウザに表示されるようになる
タイプ: システム定義
キー: Content-Type
値: image/jpeg
SDK経由なら、オブジェクトをputする際にメタデータを指定できるみたい
AWS S3 の putObject API でメタデータを設定する - 銀の弾丸
https://takamints.hatenablog.jp/entry/set-metadata-with-aws-s3-putobject
CLI経由でも処理できるみたい
AWS CLI で S3 オブジェクトのメタデータを変更する - michimani.net
https://michimani.net/post/aws-modify-metadata-of-s3-object/
AWS CLIでS3 objectsへメタデータを設定する - Qiita
https://qiita.com/yohachi/items/7b91fcc441b2ccf4da87
【小ネタ】S3オブジェクトのContent-TypeをAWS CLIで一括で変更する | DevelopersIO
https://dev.classmethod.jp/articles/change-content-type-by-aws-cli/
■データ転送量の確認
S3 → バケットを選択 → 管理 → メトリクス
左メニュー内にある鉛筆アイコンをクリック
「リクエストのメトリクス」「データ転送のメトリクス」にチェックを入れて「保存」をクリック
(片方にチェックを付けると、もう片方も強制的にチェックが付いた)
CloudWatch → メトリクス → S3 → 各フィルターのメトリクスをリクエスト
で上で追加したメトリクスを確認できる
表示されていない場合はしばらく待つ。(「リクエストのメトリクス」「データ転送のメトリクス」の設定が反映されるまでに、15分程度のタイムラグがある)
S3データ転送量のアラート設定 | ハックノート
https://hacknote.jp/archives/54254/
■CLIで操作
CLIを使えば、バケットから一括ダウンロードや一括アップロードすることができる
詳細は、このファイル内にある「AWS CLI」の「S3を操作」を参照
■バケットの再作成
バケットを削除した後、すぐに同じ名前でバケットを作成しようとすると
「A conflicting conditional operation is currently in progress against this resource. Please try again.」
のようなエラーになる
複数リージョンに分散配置されたデータが消えるまで時間がかかるようなので、1〜2時間ほどしてから再度試すといい
AWS S3 で bucket を削除した後に再作成を試みるとうまくいかない|Sheeprograming
http://sheeprogramming.iku4.com/Entry/269/
■バージョン管理
※未検証
今さらだけどS3のバージョニングを試してみた。
https://qiita.com/kooohei/items/8775b380632e8b7940a3
■セキュリティ
※未検証。2018年11月18日の記事
S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました | DevelopersIO
https://dev.classmethod.jp/cloud/aws/s3-block-public-access/
■ElastiCache
キャッシュに特化したインスタンスを作成できる
大きく分けて以下3つの使い方がある
・Redis(クラスターモード無効)
・Redis(クラスターモード有効)
・Memcached
Redisについてはそれぞれ後述の「ElastiCache (Redis)」を、Memcachedについては後述の「ElastiCache (Memcached)」を参照
以下、Redisを使用する前提でElastiCacheの概要を記載する
■それぞれの関係性
ElastiCache > クラスター > シャード > ノード
■前提知識
レプリケーションとは、リアルタイムにデータをコピーする技術のこと
プライマリノードへの書き込みを、プライマリノードに紐づくすべてのセカンダリノードへ非同期的に反映する
読み込みの負荷分散や、障害対策のホットスタンバイとして使用される
シャーディングとは、データベースの負荷分散を行う手法の一つ
一つの表(テーブル)を複数の物理コンピュータに分割して記録する方式
各コンピュータは共有資源を持たずに独立しており、データが増大してもコンピュータの台数を増やしていくことで負荷に対応できる
どのデータがどのコンピュータに記録されているか把握する必要があるため、システムが複雑になる
■それぞれの役割
ノードとは、通信の主体となる個々の機器
ElastiCacheの最小単位で、データの保存領域(RAM)を持つ
設定したノードタイプによって、CPU性能や保存領域のサイズが異なる
シャードとは、ノードをまとめるグループ
データはノード間で同期され、2つ以上のノードを用いることでレプリケーションできる
1つのシャードの中には、読み書きができるプライマリーノードを1つと、読み込み専用のセカンダリノード(リードレプリカ)を0〜5個持つ
クラスターとは、シャードをまとめる論理グループ
クラスターモードが有効の場合、クラスターの中に複数(最大15個)のシャードを持つことができる
複数のシャードがあると、名前のとおりデータはシャーディングされる。つまりデータはシャード間で分割される
クラスターモードが無効の場合、クラスターの中に1つのシャードを持つ
この場合、データはもちろん分割されない
■障害時の挙動
プライマリノードで障害が発生した場合、
自動で選択されたリードレプリカがプライマリノードに昇格する
アプリケーションで利用しているエンドポイントは、変更する必要が無い
昇格にかかる数分間、プライマリノードへの書き込みの一部は失われる
リードレプリカで障害が発生した場合、
新しいノードと置き換えらえる
置き換えが行われる際、レプリカが本来行う読み込み処理をプライマリノードが引き受けるため、プライマリノードの負荷が上がる
アプリケーションで利用しているリードレプリカエンドポイントは、変更する必要がある
■ノードタイプなどの変更
クラスターモードが有効の場合、ノードタイプ・シャード数・レプリカ数・エンジンのバージョンを変更できない
変更するには、新たなクラスタを作ってデータを移行する必要がある
…だったが、2021年時点でエンジンのバージョン以外は変更できるらしい?
また2023年3月時点で、エンジンのバージョンも互換性があるバージョンに限って変更できるみたい?
クラスターモードが無効の場合、ノードタイプ・エンジンのバージョンを変更できる
ただし変更中は読み書き処理がブロックされ、インスタンスを利用できない(t2.microをt2.smallにする場合でも、10分ほどかかるみたい)
ノードタイプの変更はスケールアップのみに対応している。スケールダウンは、新しくクラスタを作る必要がある
レプリカの追加は、クラスターを停止することなくできるみたい
■メモ
基本的には「シャード1(クラスターモード無効)、ノード2」でいいかもしれない
RDSでもマルチAZは使っているものの、シャーディングするほどの規模になったことは無い
ただしクラスターモード無効の場合、パフォーマンスの天井が低いらしい。本番環境ではクラスターモード有効が推奨されるらしい
ノードタイプなどの変更には制限があるようなので、例えば意図したインスタンスタイプにスケールダウンしたい場合、
1. ElastiCacheで新たにクラスターを、スケールダウンしたい内容で作成する
2. サーバやアプリケーションの設定を変更し、新しく作成したクラスターを参照させる
3. 問題無ければ、以前のクラスターは削除する
という手順で行う必要があるかもしれない
■参考
ElastiCache + Redis に出てくる概念と、クラスタモードごとの違い - nyamadoriの日記
https://nyamadori.hatenablog.com/entry/2017/09/12/103523
ElastiCache for Redisのクラスターモードについて調べてみる | DevelopersIO
https://dev.classmethod.jp/articles/elasticache-cluster-mode/
シャードのレプリカの数を減らす - Amazon ElastiCache for Redis
https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/decrease-replica-count.html
「Redis (クラスターモードが有効) のシャード、または Redis (クラスターモードが無効) のレプリケーショングループのレプリカ数を減らすことができます。」
「最小の実行として、レプリカを少なくともシャードあたり2つにすることをお勧めします。」
ElastiCache for Redis クラスターのクラスターモードが有効かどうかを一括で確認するワンライナー | DevelopersIO
https://dev.classmethod.jp/articles/elasticache-for-redis-cluster-enabled-check/
クラスターモード無効/有効の比較表がある
ElastiCache のスケーリングについてまとめてみた - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/elasticache-scaling
「クラスターモード無効の場合、パフォーマンスの天井が低いので、本番ワークロードではクラスタモード有効が推奨」
■ElastiCache (Redis)
ElastiCacheでRedisを使用する
ElastiCache + Redis に出てくる概念と、クラスタモードごとの違い - nyamadoriの日記
https://nyamadori.hatenablog.com/entry/2017/09/12/103523
redis-cliについては以下を参照
redis-cliの使い方 - Qiita
https://qiita.com/sawada_masahiko/items/1f60936c421ecab8dfbf
Redis に保存されてる値を見ようと思った時に覚えておきたい redis コマンド | そんなこと覚えてない
https://blog.eiel.info/blog/2014/08/26/remember-redis/
RedisのKeyを全て削除する - Qiita
https://qiita.com/reoring/items/b92cac4c83c88a725faa
PHPのセッションをRedisで扱う方法は以下を参照
AWSでPHP7+ElastiCache(Redis)を利用したセッション保持 | Skyarch Broadcasting
https://www.skyarch.net/blog/?p=11966
【AWS入門】ElastiCache を起動してみる | SONICMOOV LAB
https://lab.sonicmoov.com/development/aws/elasticache/
【Elasticache】ELB配下の複数インスタンス間でのセッション管理【Laravel例】 - 備忘録の裏のチラシ
https://norikone.hatenablog.com/entry/2016/02/08/%E3%80%90Elasticache%E3%80%91ELB%E9%85%8D%E4%B8%8B%...
AWS EC2にredisをインストールする - Qiita
https://qiita.com/stoshiya/items/b8c1d2eb41770f92ffcf
PHPのセッションをRedisクラスターモードで扱う方法は以下を参照
PHPのSESSION管理はRedisではなくRedis Clusterを使いたいという方にだけこっそり教えます - Qiita
https://qiita.com/hayakawatomoaki/items/f667359d028232475d4e
PHP Sessions with Redis Cluster (using AWS Elasticache) - Brandon Checketts
https://www.brandonchecketts.com/archives/php-sessions-with-redis-cluster-using-aws-elasticache
以下、PHPのセッション置き場として使うために検証した内容
■準備: EC2を起動
以下の内容でEC2インスタンスを起動
名前: cache_test
Amazonマシンイメージ: Amazon Linux 2 AMI
インスタンスタイプ: t2.micro
キーペア名: AWS
Network: Develop
サブネット: Develop-DMZ-A
パブリックIPの自動割り当て: 有効化
ファイアウォール: default, ssh, web
ストレージ: 20GiB / 汎用SSD(GP2)
■準備: EC2を設定
$ sudo su -
# localedef -f UTF-8 -i ja_JP ja_JP
# localectl set-locale LANG=ja_JP.UTF-8
# localectl status
# timedatectl set-timezone Asia/Tokyo
# timedatectl status
$ sudo su -
# date
# yum install httpd -y
# systemctl start httpd
# systemctl enable httpd
# usermod -a -G apache ec2-user
# echo 'cache_test' > /var/www/html/index.html
以下にアクセスして確認
http://203.0.113.1/
■準備: PHPをインストール
# amazon-linux-extras install php7.4 -y
# yum install php php-mbstring -y
# php -v
# systemctl restart httpd
# echo '<?php phpinfo() ?>' > /var/www/html/phpinfo.php
以下にアクセスして確認
http://203.0.113.1/phpinfo.php
■準備: PHPセッションを動作確認
# vi /var/www/html/session.php
<?php
session_start();
if (isset($_SESSION["count"])) {
$_SESSION["count"]++;
} else {
$_SESSION["count"] = 1;
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>セッション</title>
</head>
<body>
<h1>セッション</h1>
<p><?php
echo $_SESSION["count"] . "回目のアクセスです。";
?></p>
</body>
</html>
以下にアクセスして確認
http://203.0.113.1/session.php
セッションは以下に保存されている
# ll /var/lib/php/session
合計 4
-rw------- 1 apache apache 10 7月 25 20:04 sess_39iatvd1po1bpbsfl9c0agnijp
# cat /var/lib/php/session/sess_39iatvd1po1bpbsfl9c0agnijp
count|i:5;
■準備: ElastiCache用のサブネットグループを作成
AWS → ElastiCache → サブネットグループ → サブネットグループを作成
名前: develop
説明: for develop.
VPC ID: develop
AWS → ElastiCache → パラメータグループ → パラメータグループを作成
RDSパラメータグループのように、常に変更されるものでは無いか
それなら「必要に応じて作成する」でいいか
■Redis(クラスターモード無効の場合)検証: ElastiCacheを起動
AWS → ElastiCache → Redisクラスター → Redisクラスターを作成
クラスターの作成方法を選択: 新しいクラスターを設定および作成
クラスターモード: 無効
名前: develop
ロケーション: AWSクラウド
マルチAZ: 無効(本番環境なら有効にすべきだと思われる)
エンジンバージョン: 6.2
ポート: 6379
パラメータグループ: default.redis6.x(必要に応じて変更する)
ノードのタイプ: cache.t2.micro
レプリケーション数: 2
サブネットグループ: develop
アベイラビリティーゾーンの配置: 指定がありません
「次へ」をクリック
詳細設定はいったん変更せずに、そのまま「次へ」をクリック
確認画面が表示されるので、そのまま「作成」をクリック
作成されるまで5分ほど待つ
作成されたら、詳細画面からプライマリエンドポイント(接続先)を確認しておく
# amazon-linux-extras install redis6 -y
# systemctl start redis
# systemctl enable redis
# redis-cli -h develop.vjtrrr.ng.0001.apne1.cache.amazonaws.com
> quit
■Redis(クラスターモード無効の場合)検証: PHPセッションをElastiCacheに保存
# yum install php-pecl-redis -y
# vi /etc/php.ini
;session.save_handler = files
;session.save_path = "/tmp"
↓
session.save_handler = redis
session.save_path = "tcp://develop.vjtrrr.ng.0001.apne1.cache.amazonaws.com:6379"
# systemctl restart httpd
変わらない場合、以下などのファイルで値が上書きされていないか確認する
# vi /etc/httpd/conf.d/php.conf
# vi /etc/php-fpm.d/www.conf
以下にアクセスして確認
http://203.0.113.1/session.php
セッションがRedisに保存されていることを確認する
# redis-cli -h develop.vjtrrr.ng.0001.apne1.cache.amazonaws.com
> keys "PHP*"
1) "PHPREDIS_SESSION:39iatvd1po1bpbsfl9c0agnijp"
> get PHPREDIS_SESSION:39iatvd1po1bpbsfl9c0agnijp
"count|i:5;"
■Redis(クラスターモード有効の場合)検証: ElastiCacheを起動
AWS → ElastiCache → Redisクラスター → Redisクラスターを作成
クラスターの作成方法を選択: 新しいクラスターを設定および作成
クラスターモード: 有効
名前: develop
ロケーション: AWSクラウド
マルチAZ: 有効化
エンジンバージョン: 6.2
ポート: 6379
パラメータグループ: default.redis6.x.cluster.on(デフォルトで「cluster.on」が選択されていた)
ノードのタイプ: cache.t2.micro
レプリケーション数: (設定項目が無かった)
シャード数: 3(デフォルト値のまま / 1〜500で指定できる)
シャードあたりのレプリカ: 2(デフォルト値のまま / 0〜5で指定できる)
サブネットグループ: develop
アベイラビリティーゾーンの配置: 均等分散
「次へ」をクリック
詳細設定はいったん変更せずに、そのまま「次へ」をクリック
確認画面が表示されるので、そのまま「作成」をクリック
作成されるまで10分ほど待つ
作成されたら、詳細画面から設定エンドポイント(接続先)を確認しておく
(クラスターモードを有効にした場合、「プライマリエンドポイント」ではなく「設定エンドポイント」を使う)
# amazon-linux-extras install redis6 -y
# systemctl start redis
# systemctl enable redis
# redis-cli -h develop.vjtrrr.clustercfg.apne1.cache.amazonaws.com
> quit
■Redis(クラスターモード有効の場合)検証: PHPセッションをElastiCacheに保存
# yum install php-pecl-redis -y
# vi /etc/php.ini
;session.save_handler = files
;session.save_path = "/tmp"
↓
session.save_handler = rediscluster
session.save_path = "seed[]=develop.vjtrrr.clustercfg.apne1.cache.amazonaws.com:6379"
# systemctl restart httpd
変わらない場合、以下などのファイルで値が上書きされていないか確認する
# vi /etc/httpd/conf.d/php.conf
# vi /etc/php-fpm.d/www.conf
以下にアクセスして確認
http://203.0.113.1/session.php
セッションがRedisに保存されていることを確認する
設定エンドポイントに接続しても、何も記録されていない
# redis-cli -h develop.vjtrrr.clustercfg.apne1.cache.amazonaws.com
> keys "*"
(empty array)
各シャード内にある各ノードを一つずつ調べていくと、0002にだけ記録されていた
(0001〜0003のいずれかに記録されているはず)
# redis-cli -h develop-0001-001.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0001-002.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0001-003.vjtrrr.0001.apne1.cache.amazonaws.com
> keys "*"
(empty array)
# redis-cli -h develop-0002-001.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0002-002.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0002-003.vjtrrr.0001.apne1.cache.amazonaws.com
> keys "*"
1) "PHPREDIS_CLUSTER_SESSION:2f0867jmhpd912v5tohlvlj7os"
develop-0002-001.vjtrrr.0001.apne1.cache.amazonaws.com:6379> get PHPREDIS_CLUSTER_SESSION:2f0867jmhpd912v5tohlvlj7os
"count|i:5;"
# redis-cli -h develop-0003-001.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0003-002.vjtrrr.0001.apne1.cache.amazonaws.com
# redis-cli -h develop-0003-003.vjtrrr.0001.apne1.cache.amazonaws.com
> keys "*"
(empty array)
シャーディングされたデータなので、
・現状、自身のアクセスは常に0002に対して読み書きされる
・他ユーザのアクセスは0001や0003で読み書きされる可能性がある
となっている
■Redis検証: AmazonLinux1に php-pecl-redis をインストール
AmazonLinux1の場合、yumではインストールできなかった
# yum install php-pecl-redis
1007 packages excluded due to repository priority protections
パッケージ php-pecl-redis は利用できません。
エラー: 何もしません
# yum install php-pecl-redis --enablerepo=epel
1007 packages excluded due to repository priority protections
パッケージ php-pecl-redis は利用できません。
エラー: 何もしません
以下にある手順でインストールできた
かなり前の記事なので、「今はCentOS6系には提供されていない」などではなく、当時からyumではインストールできなかったのだと思われる
Amazon LinuxにPHP + memcached + Redisをインストール - WonderPlanet Developers’ Blog
https://developers.wonderpla.net/entry/2013/10/01/190555
# cd
# git clone
https://GitHub.com/nicolasff/phpredis.git
# cd ./phpredis
# phpize
# ./configure && make && make install
# vi /etc/php.d/redis.ini
; Enable redis extension module
extension=redis.so
# service httpd reload
これでPHPからRedisを利用できるようになった
なお、最初は以下のエラーになった
# yum install php-pecl-redis --enablerepo=epel
It was impossible to connect to the Red Hat servers.
This could mean a connectivity issue in your environment, such as the requirement to configure a proxy,
or a transparent proxy that tampers with TLS security, or an incorrect system clock.
Please collect information about the specific failure that occurs in your environment,
using the instructions in:
https://access.redhat.com/solutions/1527033 and open a ticket with Red Hat Support.
yumのレポジトリが httpsかつ証明書が不正な場合の無理やり許可する。 - Qiita
https://qiita.com/iitenkida7/items/cbf0ce48632c84db3c80
上記の記事を参考に
# vi /etc/yum.repos.d/webtatic-testing.repo
sslverify=0 … 3箇所に追記する
としたが、解消できなかった
さらに
【AWS/EC2/Amazon Linux2】curl: (60) SSL certificate problem: certificate has expired - Qiita
https://qiita.com/wadakatu/items/80919711bb05d0142cd5
上記の記事を参考に
# yum install
https://cdn.amazonlinux.com/patch/ca-certificates-update-2021-09-30/ca-certificates-2018.2.22-65.1.2...
としてTLSのエラーは解消できたが、そもそも php-pecl-redis のパッケージは見つからなかった
よって上記のとおり、GitHubからソースコードを入手して手動でインストールした
■オプション
weightなどのオプションを指定する場合、以下が参考になりそう
PHPセッションをPhpRedisに保存する - Qiita
https://qiita.com/zurazurataicho/items/a71437412410955afd44
以下も参考になりそう
Amazon ElastiCache Redis の各パラメータについてまとめてみた | DevelopersIO
https://dev.classmethod.jp/articles/amazon-elasticache-redis-param/
■費用
公式の見積もりツールによると、cache.t2.small をノード数2で追加すると$70ほど上がった
ノート数を3にすると、さらに$40ほど上がった
■Redis とMemcached
基本的にはRedisを使っておけば良さそう
Redis とMemcached | AWS
https://aws.amazon.com/jp/elasticache/redis-vs-memcached/
【AWS入門】Amazon ElastiCacheとは?redisとmemcachedの違いやユースケース、料金について解説 | よくわかるAWS・クラウド
https://cloudnavi.nhn-techorus.com/archives/4270
Amazon ElastiCacheとは?RedisとMemcachedの違いとは | SunnyCloud
https://www.sunnycloud.jp/column/20210428-01/
ElastiCacheはMemcachedとRedisのどっちを選ぶ? | DevelopersIO
https://dev.classmethod.jp/articles/which-choice-redis-memcached/
PHPアプリケーションのセッション管理にAWS ElastiCacheを使う | DevelopersIO
https://dev.classmethod.jp/articles/php-session-elasticache/
AWS運用 ElastiCache Redis で PHP のセッション情報を保存してみよう | AWS運用最適化サービス cloud link (クラウドリンク)
https://aws.taf-jp.com/blog/38956
■スペックの変更
スペックの変更を試した。
「ElastiCache → Redis クラスター」の画面で作業対象を選択し、「アクション → 変更」を実行
今回はノードのタイプ「cache.t2.micro」を「cache.t2.small」に変更してみる
20:00 に変更作業を実行した。ステータスが「Modifying」に変わった
20:18 に変更作業が完了した。ステータスが「Available」に変わった
基本的には20分ほどかかるということで良さそう
「cache.t2.small」を「cache.t2.micro」に戻したときも、同じくらいの時間で完了した
セッション数がリセットされたりは無かった
ときどきアクセスして確認したが、ダウンタイムは見られなかった。ただし数秒のダウンは発生すると思っておく
ダウンタイムについては、以下を総合すると「瞬断は発生します」くらいの案内で良さそう
以下は cache.m5.large を cache.t2.small に変更(スペックダウン)した時のメモ
Cronエラーが来たので、瞬断は発生したと思われる
18:51 変更
18:51 ステータスが「Modifying」になった
19:08 キャッシュに接続できなくなった(画面では確認できていないが、Cronからエラーが来た)
19:09 キャッシュに接続できるようになった
19:10 ステータスが「Available」になった
ElastiCache Redisのサービス更新時のダウンタイムを調査した - karakaram-blog
https://www.karakaram.com/elasticache-service-update-downtime/
「ダウンタイムは数秒と記載あり」
ElastiCacheのスケールアップは本当にダウンタイムなしでできるのか検証してみた! #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/can-elasticache-onlinescalingup-without-downtime/
「ミリ秒単位で観測するとわずかにリクエストに影響があるようです。」基本的にはダウンタイムは無いみたい?
Amazon MemoryDB for Redisのシャード数を変更してみた | DevelopersIO
https://dev.classmethod.jp/articles/amazon-memorydb-for-redis-change-shard/
「キー数やシャード数によりますが、変更に数時間かかることもあるようです。(今回は20分程度かかりました)」
「シャード数」や「シャードあたりのレプリカ」の変更は、別画面で行う。以下を参照
Amazon MemoryDB for Redisのシャード数を変更してみた | DevelopersIO
https://dev.classmethod.jp/articles/amazon-memorydb-for-redis-change-shard/
■オートスケーリング
ElastiCache for Redis クラスターの Auto Scaling - Amazon ElastiCache for Redis
https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/AutoScaling.html
Elasticache for RedisでAutoScalingを利用できるようになりました | DevelopersIO
https://dev.classmethod.jp/articles/autoscaling-elasticache-for-redis/
ElastiCache のスケーリングについてまとめてみた - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/elasticache-scaling
ElastiCache for Redisはオートスケーリングに対応しているらしい
それなら
・RDSはオートスケーリング無しで作成する
・ElastiCache for Redisはオートスケーリングありで作成する
・負荷が問題になりそうな部分は、
「RDSからの参照結果をElastiCacheに保存する」「書き込みたい内容を一時的にElastiCacheに保存し、後からRDSに登録する」
のような対応はできそう
ただしキャッシュなので、突発的にデータが消えることは常に考えておく必要はありそう
また、これで大量のアクセスに耐えられるとしても、別途クラウド破産対策は必要
どんなアクセス数にも耐えられるのは、それはそれで問題になる可能性はある
CloudFrontやWAFなどで、一定以上のアクセスが来たら「しばらくお待ちください」画面を出すように制御するくらいか
■要検証
詳細設定に「スローログ」がある。以下などを参考にしたい
「エンジンログ」というのもあるが、Redis自体の動作ログのことか
[アップデート] ElastiCache for RedisのスローログをCloudWatch LogsやKinesis Data Firehoseにパブリッシュできるようになりました! | DevelopersIO
https://dev.classmethod.jp/articles/amazon-elasticache-now-supports-publishing-redis-slow-logs/
アップデートが多いとクラスターモードは無効の方がいい?
セッションはアップデートが非常に多いと言えるので、クラスターモード無しでもいいか
Amazon ElastiCacheってなんだろ?
https://zenn.dev/mn87/articles/6de8deb3b02f26
■トラブル: 「プライマリエンドポイント」が表示されない
クラスターモードを有効にした場合、「プライマリエンドポイント」ではなく「設定エンドポイント」を使って読み書きする
■トラブル: PHPからセッションを扱えない1
/etc/php.ini の設定ではなく、以下などのファイルの設定が優先されていないか確認する
/etc/httpd/conf.d/php.conf
/etc/php-fpm.d/www.conf
■トラブル: PHPからセッションを扱えない2
接続先を間違えると、以下のエラーになる
ブラウザで画面は表示されるが、セッションの値はカウントされない
[Wed Jul 27 21:37:01.543078 2022] [php7:warn] [pid 4251] [client 203.0.113.1:60324] PHP Warning: session_start(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /var/www/html/session.php on line 3
[Wed Jul 27 21:37:01.543144 2022] [php7:warn] [pid 4251] [client 203.0.113.1:60324] PHP Warning: session_start(): Failed to read session data: redis (path: tcp://test.vjtrrr.clustercfg.apne1.cache.amazonaws.com:6379) in /var/www/html/session.php on line 3
■トラブル: クラスターモードでPHPからセッションを扱えない
以下のエラーになる
ブラウザで画面は表示されない(「このページは動作していません」になる)
[Wed Jul 27 21:23:41.752235 2022] [php7:warn] [pid 4037] [client 203.0.113.1:60002] PHP Warning: session_start(): Failed to read session data: redis (path: tcp://test.vjtrrr.clustercfg.apne1.cache.amazonaws.com:6379) in /var/www/html/session.php on line 3
[Wed Jul 27 21:23:41.752294 2022] [php7:error] [pid 4037] [client 203.0.113.1:60002] PHP Fatal error: Uncaught RedisException: MOVED 6734 10.1.2.103:6379 in /var/www/html/session.php:3\nStack trace:\n#0 /var/www/html/session.php(3): session_start()\n#1 {main}\n thrown in /var/www/html/session.php on line 3
■ElastiCache (Memcached)
※可用性の観点で、MemcachedよりもRedisの方がが優れているとされている
基本的にはRedisを使っておけば良さそう
Redisに関しては「ElastiCache (Redis)」を参照
Amazon ElastiCacheとは?RedisとMemcachedの違いとは | SunnyCloud
https://www.sunnycloud.jp/column/20210428-01/
ElastiCacheはMemcachedとRedisのどっちを選ぶ? | DevelopersIO
https://dev.classmethod.jp/articles/which-choice-redis-memcached/
本当は怖いMemcached - Qiita
https://qiita.com/taruhachi/items/a844bf373623991873ff
それでもMemcachedを使いたいあなたに - Qiita
https://qiita.com/taruhachi/items/b4c938dce1646aeb7204
以下はMemcachedを試したときのメモだが、初期に1度試しただけなので現状とは差異が大きいかもしれない
ElastiCache → Get Started Now もしくは ElastiCache → Launch Cache Cluster からインスタンスを作成
Step 1:Select Engine
Memcached を選択
Step 2:Specify Cluster Details
Cluster Name: cacheinstance
Node Type: cache.m3.medium
Number of Nodes: 1
Step 3:Configure Advanced Settings
マルチAZに対応させる場合、Availability Zone(s) を Spread Nodes Across Zones にする
必要に応じて、あらかじめ設定しておいた Security Group を選択
Step 4:Review
内容を確認して、問題なければ Launch
WebサーバからMemcachedにアクセスするための設定を行っておく
ElastiCacheのエンドポイントが以下の場合、
xxxxx.cache.amazonaws.com:11211
例えばWebサーバのPHPを以下のようにすればElastiCacheでセッション管理ができる
# yum install memcached php-pecl-memcache
# vi /etc/php.ini
;session.save_handler = files … コメントアウト(先頭に ; を付加)
;session.save_path = "/var/lib/php/session" … コメントアウト(先頭に ; を付加)
# vi /etc/php.d/memcache.ini
… phpの設定ファイルを編集
session.save_handler=memcache … コメントアウトを外す(先頭の ; を削除)
session.save_path="tcp://localhost:11211?*******" … コメントアウトを外す(先頭の ; を削除 / ?以下は不要)
session.save_path="tcp://xxxxx.cache.amazonaws.com:11211" … ElastiCacheエンドポイントの設定例
# service httpd restart
… httpdを再起動
# service memcached start
… memcacheを起動
セッションを扱うPHPプログラムを作成し、動作確認をする
PHPアプリケーションのセッション管理にAWS ElastiCacheを使う
http://dev.classmethod.jp/cloud/aws/php-session-elasticache/
phpのセッションをmemcachedに変える | CoDE4U
http://blog.code4u.org/archives/422
phpのsessionを複数のmemcacheサーバに保存するお話 - Qiita
https://qiita.com/motoki-ok@github/items/a6459c6efaa0ac2a417a
PHPでクラスタ構成のmemcachedサーバを利用するときに気をつけること - Road To Nowhere
http://kazumaryu.hatenablog.com/entry/20130125/1359044488
※ElastiCacheはレプリケーションに対応していないので、複数のAZをまたいでいるときはPHPのセッションとしては使えない
ElastiCacheが複数のAZをまたいでいるとき、レプリケーションが働かずにセッションがバラバラになることがある
Redisはレプリケーションに対応しているみたいだけど、PHP用の定番ライブラリがない
なので、異なるAZに別々にElastiCacheを配置し、その両方にキャッシュするようにPHPに設定する
php.iniでキャッシュ先を複数設定しておけば、利用先が先頭から順に決定される
もし先頭のElastiCacheがダウンしても、次のElastiCacheが使われる。という仕組みで対処
(セッションが切れる可能性はあるが、大きな問題にはならなさそう)
2014年7月にマルチAZ配置に対応したようだが、それは「レプリケーションが働かずにセッションがバラバラになる」の状態みたい?
かっぱのほげふが | ElastiCache for memcached の分散処理をどうするか悩む
http://hogehuga.inokara.com/2014/04/26/elasticache-benchmark.html
【ElastiCache】memcachedのMulti-AZ配置(ゾーンをまたいだノード分散配置)が来ました!!!
http://dev.classmethod.jp/cloud/aws/elasticache-multi-az-memcached/
ElasticCache典型的な利用構成 | TechCrowd
https://www.techcrowd.jp/elasticcache/configurations/
■ElastiCache (スペックダウン)
ElastiCacheはスペックダウンの操作に制限があるようなので、実際のスペックダウンを試したときのメモ
「シャード: 3 / ノードの数: 9」で作成したものに対し、シャードとノードの数を減らそうとしている
■シャードの削除
AWSコンソールの
「ElastiCache → Redisクラスター → (削除したいElastiCacheを選択) → シャードとノード」
でシャードとノードの数を変更できそうなので試す。
「develop-0003」にチェックを入れ、「アクション → シャードの削除」で削除
以下の警告が表示されるので「シャードを削除」をクリック
develop のシャードを削除しますか?
これらのシャードを削除してよろしいですか?
develop-0003
クラスターをスケールインすると選択したシャードが削除され、これらのシャードに属していたスロットはクラスター内の残りのシャードに移行されます。
これにより、クラスター内のインメモリ容量が減少します。
メモリ容量が不足するとクラスターのパフォーマンスおよび可用性に影響が出ます。
減少後の容量がワークロードの要件に対して十分であるようにしてください。
クラスターはオンラインのままですが、このオペレーションには数分間から数時間程度かかる場合があります。
所要時間は、データのサイズ、クラスターの受信リクエストレート、およびシャード間で移行を必要とするスロット数によって異なります。
[キャンセル] [シャードを削除]
削除を実行すると、各シャードのステータスが「Modifying」に変わった(3つとも変わった)
また、Redisクラスターの一覧画面や詳細画面で「Modifying (32.24% 完了)」のように進捗が表示されている
削除実行から10分ほどで「Modifying」に変わった(パーセンテージが非表示になった)
削除実行から15分ほどで「develop-0003」のステータスが「Deleting」に変わった
削除実行から20分ほどで「develop-0003」が削除された(一覧に表示されなくなった)
削除実行から22分ほどで各シャードとElastiCacheのステータスが「Available」に変わった
作業中、PHPのセッションが途切れることは無かった
作業後は「シャード: 2 / ノードの数: 6」となった
■シャードの削除(続き)
「develop-0002」にチェックを入れ、「アクション → シャードの削除」で削除
つまり、シャードを1つにしてみる
流れは同じだが、削除完了まで30分ほどかかった
「シャード3つ → シャード2つ」よりも「シャード2つ → シャード1つ」の方が、移行すべきデータが多いからか
■ノードの削除
ノードの削除を試す
「develop-0001-003」「develop-0002-003」にチェックを入れ、「アクション → ノードの削除」で削除できるか
…を試したが、両方にチェックを入れると削除できない(削除を選択できない)
「develop-0002-003」のみにチェックを入れ、「アクション → ノードの削除」で削除
以下の警告が表示されるので「削除」をクリック
develop-0002-003 を削除しますか?
このノードを削除してよろしいですか?
develop-0002-003
警告: 高可用性に適した設計にするには、シャードあたり少なくとも 3 ノードを確保することをお勧めします (プライマリノードが 1 つ、レプリカノードが 2 つ)。
[キャンセル] [削除]
「Cannot delete the given replicas as there needs to be nodes in two Availability Zones for this Multi-AZ enabled Replication Group」
というエラーが表示された
ノードの途中削除は不可ということか
■ノードの削除(続き)
シャードが1つの状態で、再度ノードの削除を試す
「develop-0001-003」にチェックを入れ、「アクション → ノードの削除」から、普通に削除が開始された
ノードのステータスが「Modifying」に変わった。ElastiCacheやシャードのステータスは「Available」のまま
…が、すぐにノードのステータスも「Available」に変わった
「develop-0001-003」は削除されていないまま
再度削除を試しても同じ
ノードを削除するには何か条件があるということか
■EFS (Elastic File System)
複数のサーバにマウント可能な共有ストレージサービス
RDSのHDD版のようなもの。と思われる
■料金
EFS使ってみた 基礎編 | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/5958
AWS EFSのプロビジョンドスループットについて | 株式会社なないろ 京都でNo1を目指すWeb制作・システム開発クリエイティブ集団
https://www.7-16.co.jp/laboratory/2370
AWSのストレージサービスの違いを解説(S3、EBS、EFS) | 理系男子のIoTライフ
https://rikei-danshi.work/entry/2018-08-26-aws
EFSのバーストクレジットが減ると速度が非常に遅くなる
プロビジョンドスループットによって速度を向上できるようだが、料金が跳ね上がるので注意
ただしEFSの作成画面には
「ほとんどのファイルシステムには、バーストスループットモードをお勧めします。
バーストスループットで許可されるよりも多くのスループットを必要とするアプリケーションには、プロビジョンドスループットモードを使用します。」
と紹介されている
アクセス数が非常に多いサイトでなければ、プロビジョンドスループットのことは考えなくていいかも
要検証
「AWS EFSのプロビジョンドスループットについて」のページでは
「EFSに少し大きなファイルを置くことで、バーストクレジットが増えるらしい。」
「ダミーファイルを30GBほど置くことで、1.5(MiB)がデフォルトで出る。」
「EFSにファイルを置くことで少し費用発生するが、プロビジョニング済みにするよりは費用は抑えられる」
のように紹介されている。やはり要検証
■EFSの作成
AWS → EFS → ファイルシステムの作成
ステップ 1: ファイルシステムアクセスの設定
作成済みのVPCを選択
作成済みのサブネットを選択(プライベートなサブネットを作成しておく必要があるかも)
ステップ 2: オプション設定の構成
必要に応じてタグを追加
パフォーマンスは「汎用」のままでいい
(「最大 I/O」は「数十、数百、または数千のEC2インスタンスがファイルシステムにアクセスするアプリケーション」を想定しているとある)
スループットは「バースト」のままでいい
(「プロビジョニング済み」にすると速度が向上するようだが、料金が跳ね上がる)
ステップ 3: 確認と作成
内容を確認して作成する
作成するとファイルシステム一覧の画面に遷移する
VPCの設定で「DNS解決の編集」と「DNSホスト名の編集」の両方が「はい」になっている必要がある
「はい」になっていなければその旨が案内されるので設定する
■EC2にマウント
通常の手順でEC2を作成し、以下の手順でマウントを行う
「fs-f4048ed6」のようなIDはAWSコンソールで確認できる
(/var/www の外にマウントして公開用ディレクトリにすると、DocumentRootの変更が厄介そうなので注意)
# yum install -y amazon-efs-utils
# mkdir /var/www/efs
# mount -t efs fs-f4048ed6:/ /var/www/efs
以下のコマンドでマウントを確認できる
ファイルタイプは「nfs4」となり、容量は8エクサバイトとなる
# df -Th
Filesystem Type Size Used Avail Use% Mounted on
devtmpfs devtmpfs 475M 0 475M 0% /dev
tmpfs tmpfs 492M 0 492M 0% /dev/shm
tmpfs tmpfs 492M 456K 492M 1% /run
tmpfs tmpfs 492M 0 492M 0% /sys/fs/cgroup
/dev/xvda1 xfs 8.0G 1.2G 6.9G 15% /
tmpfs tmpfs 99M 0 99M 0% /run/user/1000
fs-f4048ed6.efs.ap-northeast-1.amazonaws.com:/ nfs4 8.0E 0 8.0E 0% /var/www/efs
参考までに、エクサバイトは以下の要領を表す単位で、GBで表すなら10億GBとなる
バイト(Byte)
キロバイト(KB)
メガバイト(KB)
ギガバイト(GB)
テラバイト(TB)
ペタバイト(PB)
エクサバイト(EB)
エクサバイトとは - 意味の解説|ITトレンドのIT用語集
https://it-trend.jp/words/exa_byte
以下のように公開用ディレクトリとファイルを作成し、ApacheのDocumentRootを変更し、Apacheを再起動する
# vi /var/www/efs/html/index.html
# service httpd restart
■自動マウント
自動でマウントするには別途設定が必要みたい
以下などを要確認
Amazon EFSをEC2から使ってみたメモ - Qiita
https://qiita.com/miyanaga/items/c393c29c6d29bd1aaecf
Amazon EFS ファイルシステムの自動マウント - Amazon Elastic File System
https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mount-fs-auto-mount-onreboot.html#mount-fs-auto-moun...
# vi /etc/fstab
fs-f4048ed6:/ /var/www/efs efs defaults,_netdev 0 0
この状態でEC2を複製すれば、rsyncなどを考えなくても容易にファイル共有ができる
■Ansible
以下のページではEFSの作成もAnsibleで行っているようだが、
ネットワークとEFSはあらかじめ作成済みにしておいて、それからAnsibleでEC2を構築してEFSをマウントする
…という手順にするか
マウント直後は所有者がrootになるみたいだが、中のファイルがどうなのかは要検証
所有者を再帰的にすべてapacheにすべきか否かは要検討
mountモジュールを使えば、自動マウントの設定も含めて行ってくれる
optはAWSの推奨値を指定すると良さそうだが、省略すると推奨値になるみたい?
AnsibleでAmazon EFSの作成からマウントするまで - Qiita
https://qiita.com/comefigo/items/cb2a959f1a5149ef8ec4
■懸念点
Amazon EFS を利用して WordPress サーバーを冗長化したかった | ハックノート
https://hacknote.jp/archives/38636/
■WordPressを使ってみた所感
Apache+PHP+MySQLを使えるようにした上で、/var/www/efs にEFSをマウントした以降の手順
WordPress用の領域を作成する
# cd /var/www/efs/html
# mkdir /var/www/efs/html/wordpress
# chown apache. /var/www/efs/html/wordpress
# chmod 777 /var/www/efs/html/wordpress
# chmod g+s /var/www/efs/html/wordpress
MySQLにアクセスできるようにする
$ mysql -u root -p
mysql> CREATE USER webmaster@localhost IDENTIFIED BY 'qazwsxedc';
mysql> GRANT ALL PRIVILEGES ON test.* TO webmaster@localhost;
$ mysql -u webmaster -p
WordPressを導入してログイン
http://3.112.57.115/wordpress/
admin / ttBFZ!NEHdplPxtd6R
EFSでsimpleテーマを使用
ユーザ画面を表示 ... 2.5〜3.2秒程度
管理画面を表示 ... 3.0〜4.2秒程度
# cd /var/www/html
# mkdir /var/www/html/wordpress
# chown apache. /var/www/html/wordpress
# chmod 777 /var/www/html/wordpress
# chmod g+s /var/www/html/wordpress
EBSでsimpleテーマを使用
ユーザ画面を表示 ... 0.2〜0.3秒程度
管理画面を表示 ... 0.3〜0.4秒程度
桁を見間違えるくらいには速度差が顕著
費用がどうこう、バーストクレジットがどうこう、以前に元が遅すぎる
現状、EFSで丸ごとコンテンツを配置したり…には使えないかもしれない
CloudFrontやS3やキャッシュの仕組みを駆使すれば早くなるかもしれないが、複雑化するので素直にrsyncで同期する方が容易かも
【東京リージョン対応】Amazon EFS の速度計測してみた結果【祝】 | ハックノート
https://hacknote.jp/archives/38521/
■参考
[速報] EFS(Elastic File System)が2018年7月に東京リージョンで提供開始! #AWSSummit | DevelopersIO
https://dev.classmethod.jp/cloud/aws/efs-in-tokyo-region/
ついにきた!EFS(Elastic File System)が東京リージョンで利用可能になりました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/elastic-file-system-ga-in-tokyo/
Amazon EFS を使ってみた | cloudpack.media
https://cloudpack.media/43376
AWS EFS をEC2にマウントしてみる - Qiita
https://qiita.com/tandfy/items/829f9fcc68c4caabc660
以下、東京リージョンでのリリース前の情報
Amazon Elastic File System 東京リージョン 一般提供開始のお知らせと利用上の留意点のまとめ | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/amazon-elastic-file-system-tokyo/
[速報] EFS(Elastic File System)が2018年7月に東京リージョンで提供開始! #AWSSummit | Developers.IO
https://dev.classmethod.jp/cloud/aws/efs-in-tokyo-region/
NFSでマウント可能な「Amazon Elastic File System」(Amazon EFS)、AWS東京リージョンで利用可能に − Publickey
https://www.publickey1.jp/blog/18/nfsamazon_elastic_file_systemamazon_efsaws.html
【新サービス】共有ストレージ(EFS)が発表!EFSの良い点、気になる点 #AWSSummit | Developers.IO
https://dev.classmethod.jp/cloud/elastic-file-system/
【新機能】Amazon Elastic File System (Amazon EFS)がついにGA (一般利用可能)に! | Developers.IO
https://dev.classmethod.jp/cloud/aws/amazon-elastic-file-system-is-generally-available/
以下、2021年1月に改めて調べたときの情報
Amazon EFS 東京リージョンの限界を試す - Qiita
https://qiita.com/zakky/items/08e6aa876f24bda69eb1
EFS使ってみた ~ EBSとEFSの書き込み速度を比較編 ~ | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/6015
Amazon Elastic File System (Amazon EFS) におけるバーストとプロビジョニングの変更を自動化する | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2019-08-26-132438/
AWS EFSを使ってみよう 東京リージョンリリース記念!│システムガーディアン株式会社
https://sys-guard.com/post-16347/
以下のページで
1, サービス紹介のような最小構成でEFSを利用する場合は、コンテンツ配布およびWEBアクセスで数秒以上の遅延は覚悟する必要があります。
2, 大容量のNFSを利用する大規模顧客で、EC2+NFSで冗長性が不安だと思っている人向けのサービスみたいです。
3, もしくはあまりコンテンツの更新がなく、アクセスが遅くとも問題の無いサービス向けかと。
と紹介されているので、WordPressやECCubeのサイトで普通のHDD代わりに使うものでは無いかもしれない
技術者の備忘録: EFS導入で夢が広がると思ったら、現実を突き付けられた話
http://laporz.blogspot.com/2018/11/efs.html?m=1
■Elastic IPs
※EC2のIPアドレスを固定できる
※外部からアクセスを許可しないサブネットに配置した場合、固定IPを設定しても外部からはアクセスできないので注意
※IPアドレスを6つ以上作る場合、上限緩和の申請が必要
EC2 → Elastic IPs → Allocate New Address からIPアドレスを作成
作成されたIPアドレスを選択し、「Allocate Address」をクリックする
「Instance」で関連付けたいインスタンスを選択し、「Allocate」をクリックする
これで固定IPアドレスでEC2インスタンスにアクセスできる
Web1:
http://203.0.113.2/
Web2:
http://203.0.113.3/
Elastic IP アドレス(EIP)
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html
EC2インスタンスに固定IPアドレスを割り当てる
http://www.agilegroup.co.jp/technote/ec2-elastic-ips.html
Amazon EC2 インスタンスに固定 IP を割り当てる
http://d.hatena.ne.jp/january/20130918/1379457703
Elastic IP は、EC2に1つ割り当てている分には料金が発生しない
割り当てずに置いておいたり、割り当てたEC2を停止させていたり、1つのEC2に2つ以上割り当てたりすると料金が発生する
オンデマンドインスタンスの料金 - Amazon EC2 (仮想サーバー) | AWS
https://aws.amazon.com/jp/ec2/pricing/on-demand/#Elastic_IP_%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9
EIPで料金発生するパターンとしないパターン #AWS | DevelopersIO
https://dev.classmethod.jp/cloud/aws/cost-of-eip/
RDS や ElastiCache にはEIPは不要
Amazon RDSにElastic-IPは紐づけられない(はず): ●○hinata_hisa○●
http://drawing-hisa.seesaa.net/article/403402885.html
■固定IPの割り当てと解除を繰り返したときの挙動
※EIPの関連付けにより、過去の自動取得IPアドレスではアクセスできなくなる
関連付けを解除すると、新たに別のIPアドレスが自動取得される。以前のIPアドレスに戻るわけでは無い
IP自動割り当てでEC2を作ると、以下のIPアドレスが設定された。SSHとHTTPで接続を確認した
13.115.230.96
以下のEIPを関連付けた。以前のIPではSSHでもHTTPでもアクセスできなくなった。プライベートIPに変化は無い
52.193.221.232
関連付けを解除した。新たに以下のIPアドレスが設定された。以前のIPではどちらもアクセスできなくなった。プライベートIPに変化は無い
54.95.212.88
■プライベートIPの指定
指定できるが、あまり推奨されないみたい
[小ネタ] プライベートIPアドレスを指定して EC2 インスタンスを起動する方法 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/201903_ec2-with-custom-private-ip-address/
■Route 53
ムームードメインなどでドメインを管理している場合、そこからDNSをEC2などに向ければいい
ただしロードバランサーを扱う場合など、AWSの機能をフルに利用するならRoute 53で管理できるようにしておくといい
Amazon Route 53(スケーラブルなドメインネームシステム (DNS))| AWS
https://aws.amazon.com/jp/route53/
AWS再入門2018 Amazon Route 53(DNS)編 | Developers.IO
https://dev.classmethod.jp/articles/2018-aws-re-entering-route53/
注意:
すべてのドメインをRoute 53で扱えるわけでは無いかもしれないので注意
以下によると「co.jp」などは扱えない?さすがにそんなことはない?「.jp」とみなされて登録できる?(要調査)
Amazon Route 53 に登録できるドメイン - Amazon Route 53
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/registrar-tld-list.html
注意:
ルートドメイン(「www」とかサブドメインのないもの)への設定は、場合によっては扱えないので注意
詳細は後述の「ロードバランサーに独自ドメインを設定」の「注意」を参照
注意:
サブドメインにピリオドを含むものは避ける方が無難かもしれない
登録できてHTTPアクセスもできるようになるが、AWS発行のワイルドカード証明書にてSSLアクセスしようとすると、
「test.refirio.net」にはアクセスできたが「test1.test.refirio.net」にはアクセスできなかった(「この接続ではプライバシーが保護されません」の表示になった)
個別に「test1.test.refirio.net」に対して証明書を発行すれば、アクセスできる可能性はあるかもしれないが未検証
また、できたとしても別途証明書が必要なら、管理の手間が増えるのでやはり避けておきたい
■EC2に独自ドメインを設定(ムームードメインの例)
※参考までに、Route 53を使わずに直接AレコードをEC2に向ける方法
Elastic IP でIPアドレスを固定しておく
それ以降は、さくらVPSに設定する場合と同じ。wwwの省略も可
ムームードメイン → ドメイン管理 → ドメイン一覧 → (ドメインを選択) → ネームサーバ設定変更 → セットアップ → カスタム設定 → 設定2
名前 種別 内容
A 203.0.113.1
www A 203.0.113.1
しばらく待って、EC2に独自ドメインでアクセスできることを確認する
EC2とムームードメインで独自ドメイン運用【ムームーDNSで簡単設定】
http://hivecolor.com/id/3
■Route53の使用を開始する(ムームードメイン+Route53の例)
Route 53 → ホストゾーン → ホストゾーンの作成
から設定
ドメイン名: refirio.net
タイプ: パブリックホストゾーン (変更せず)
のように入力して「ホストゾーンの作成」ボタンを押す
画面を更新すると、一覧にドメイン名が表示される
ドメイン名をチェックで選択 → レコードセットに移動
デフォルトでNSレコードとSOAレコードが登録されているが、これらは編集する必要はない
が、必要に応じてNSレコードで「TTL(Seconds)」を900秒にしておくといい(設定内容の反映が早くなる)
ドメイン一覧にはじめから表示されているNSレコードの内容をメモしておく
これで Route 53 側での設定は完了。以降はムームードメイン側で設定する
ムームードメイン → ドメイン管理 → ドメイン一覧 → (ドメインを選択)
ネームサーバ設定変更画面で「取得したドメインで使用する」を選択し、ネームサーバを以下のように設定する
(NSレコードでは最後にピリオド「.」が表示されているが、これは入力する必要が無い。最後のピリオド「.」は削除して登録する)
ネームサーバ1: ns-1234.awsdns-56.com
ネームサーバ2: ns-7890.awsdns-12.org
ネームサーバ3: ns-345.awsdns-67.net
ネームサーバ4: ns-8901.awsdns-23.co.uk
「ネームサーバ設定変更」ボタンを押す
もし設定時に「ネームサーバ設定中にエラーが発生しました。」というエラーが表示されたら、アドレスの最後にピリオド「.」を付けていないか確認する
それでも駄目なら、Whois情報が変更中になっていないか確認する
ムームードメインでネームサーバー設定変更しようとしたらのエラーが出るときの原因と解消方法 - ホームページ伊藤のブログ
https://mako110.com/2019/11/26/%E3%83%A0%E3%83%BC%E3%83%A0%E3%83%BC%E3%83%89%E3%83%A1%E3%82%A4%E3%83...
Whois情報が変更処理中だとネームサーバー変更が出来ない | アナライズギア開発ブログ
https://analyzegear.co.jp/blog/961
なお、登録先のサービスによっては大文字変換されて登録されるようだが問題ない(DNSの仕様上、大文字小文字は区別されない)
■ロードバランサーに独自ドメインを設定する(ムームードメイン+Route53の例)
Elastic Load Balancing は固定IPアドレスを持たないため、独自ドメインを設定する場合はAレコードではなくCNAMEレコードを使用する必要がある
つまりCNAMEで「develop.refirio.net → develop-123456789.ap-northeast-1.elb.amazonaws.com」のように設定する
ただし、CNAMEはルートドメイン(「www」とかサブドメインのないもの)に設定することはできない仕様なので注意
ワイルドカード「*」に対しては設定できるので、そのドメインで色々なことをしない場合はルートドメインに設定できるかも(要検証・余計なトラブルを避けるためにも、この方法は推奨されないかも)
ドメインを管理しているサービスによっては、CNAMEだけで独自ドメインを設定できないことがある
また、S3に独自ドメインを割り当てたり、ができない
【DNS】www.ありもなしもCNAMEの設定をして同じWebサイトを表示したい at softelメモ
https://www.softel.co.jp/blogs/tech/archives/5638
そのワイルドカード必要ですか?CloudFront の CNAME でワイルドカード指定時の制限を理解する | DevelopersIO
https://dev.classmethod.jp/cloud/aws/cloudfront-wildcard-cname/
これらは、AWSのRoute53を使えば解決できる
対象ホストゾーンの画面で「レコードセットの作成」ボタンを押し、以下の内容で登録する
名前: (空欄のまま)
タイプ: A - IPv4 address
エイリアス: Yes
エイリアス先: develop-123456789.ap-northeast-1.elb.amazonaws.com (ELBのAレコードを選択。「dualstack.」が自動で付く)
同じ流れで以下も登録する
名前: www
タイプ: A - IPv4 address
エイリアス: Yes
エイリアス先: develop-123456789.ap-northeast-1.elb.amazonaws.com (ELBのAレコードを選択。「dualstack.」が自動で付く)
しばらく待って、ロードバランサーに独自ドメインでアクセスできることを確認する
[AWS]CakePHP+Elastic Beanstalk+Route53+ムームードメインで独自ドメインを使用する方法
http://arkmemo.blogspot.jp/2013/05/awscakephpelastic-beanstalkroute53.html
営業でも簡単!Route 53の基本設定
http://blog.serverworks.co.jp/tech/2013/03/08/route53_basic/
Elastic IP アドレスの設定とRoute 53から独自ドメインの割当
http://ja.amimoto-ami.com/2013/11/29/elastic-ip-and-route-53/
AWSで独自ドメインを設定したい。
http://qiita.com/mochizukikotaro/items/eb4a8d6cd3b184eaf42a
ドメイン名を使ってEC2を運用していたら、ELBのスケールアウトで苦労した話
http://mugenup-tech.hatenadiary.com/entry/2014/05/12/104009
ホスト名では大文字と小文字が区別されますか?
https://qastack.jp/server/261341/is-the-hostname-case-sensitive
ドメイン名のしくみ - JPNIC
https://www.nic.ad.jp/ja/dom/system.html
■ロードバランサーに独自ドメインを設定(2020年8月時点の手順メモ)
※UIが大きく変わっていたので、現時点での手順をメモしておく
※すでにRoute53を使っている状態で、ロードバランサーにサブドメインを割り当てたときのメモ
ホストゾーン → refirio.net → レコードを作成
「シンプルルーティング」を選択して「次へ」
「シンプルなルーティング」をクリック
レコード名: test
エンドポイントを選択: Application Load Balancer と Classic Load Balancer へのエイリアス
リージョンを選択: アジアパシフィック(東京)[ap-northeast-1]
ロードバランサーを選択: dualstack.refirio-staging-1234567890.ap-northeast-1.elb.amazonaws.com
レコードタイプ: A
として「シンプルなレコードを定義」をクリック
さらに「レコードを作成」をクリック
5分ほど待つと、以下でアクセスできるようになった
http://test.refirio.net/
■S3に独自ドメインを設定(ムームードメイン+Route53の例)
独自ドメインを含んだ名前のBucketにする
具体的には、data.refirio.net のような Bucket Name で Bucket を作成する
標準では
http://s3-ap-northeast-1.amazonaws.com/data.refirio.net/images/brownie.jpg
http://data.refirio.net.s3-ap-northeast-1.amazonaws.com/images/brownie.jpg
のような名前でアクセスできる
EC2 → Route 53 → Get Started Now → ホストゾーンの作成 から設定
Name: data
Type: CNAME - Canonical name
Alias: No
Value: data.refirio.net.s3-ap-northeast-1.amazonaws.com
のように入力して「Create」ボタンを押す
画面を更新すると、一覧にドメイン名が表示される
しばらく待って、以下のようなURLでアクセスできることを確認する
http://data.refirio.net/images/brownie.jpg
■別のAWSアカウントにサブドメインの管理権限を委譲する
本番環境用と検収環境用でAWSアカウントを分ける際、例えば
「本番環境は refirio.net というドメイン、検収環境は test.refirio.net というドメイン」
にするとする
この場合、検収環境のDNSを調整したければ、本番環境用のAWSアカウントから作業する必要がある
これを「サブドメイン test の管理は検収環境のAWSアカウントで行う」ができるようにする
[Route 53] 別のAWSアカウントでサブドメインを使えるように権限移譲する | DevelopersIO
https://dev.classmethod.jp/articles/route53-transfer-hostedzones-2021/
本番環境用AWSアカウントのRoute53で、すでにホストゾーン refirio.net が登録されているものとする
検収環境用AWSアカウントで作業
Route 53 → ホストゾーン → ホストゾーンの作成
から設定
ドメイン名: test.refirio.net
タイプ: パブリックホストゾーン (変更せず)
と入力して「ホストゾーンの作成」ボタンを押す
画面を更新すると、一覧にドメイン名が表示される
ドメイン名をチェックで選択 → レコードセットに移動
ドメイン一覧にはじめから表示されているNSレコードの内容をメモしておく
続いて、本番環境用AWSアカウントで作業
ホストゾーン → refirio.net → レコードを作成
レコード名: test.refirio.net
レコードタイプ: NS
値: (上の手順でメモしたNSレコードの内容。ただし最後のピリオド「.」は削除せずに登録する)
「レコードを作成」ボタンを押す
■CloudFront
CDN(Content Delivery Network)で、日本語にするならコンテンツ配信サービス
世界中にエッジサーバ(データをキャッシュする、ユーザの近くにあるサーバ)があり、
最寄りのエッジサーバに誘導することで高速な配信ができる
コンテンツのキャッシュにより、オリジンサーバの負荷も減らすことができる
AWS再入門 Amazon CloudFront編 | Developers.IO
http://dev.classmethod.jp/cloud/cm-advent-calendar-2015-aws-re-entering-cloudfront/
制限 - Amazon CloudFront
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html
AWS WAFを使うためシステムにCloudFrontを導入した時の注意点まとめ | Developers.IO
http://dev.classmethod.jp/cloud/aws/setup-amazon-waf-and-cloudfront/
いますぐ使う CloudFront - Qiita
https://qiita.com/sasasin/items/0f0ec1a90af6295589f9
※60秒のタイムアウト制限があるので注意
巨大ファイルのアップロード受け付けるなど、長時間の処理が必要な場合はCloudFrontがネックになる
詳しくは「タイムアウト時間を調整する」を参照
※以前は、WAFを使うにはCloudFrontを導入する必要があった
ただし現在は、ALBに対してWAFを設定できるようになっている
※2019年4月8日以降、HTTPのみで使用する場合でもSSL証明書が必要になっている
Amazon CloudFront の代替ドメイン名(CNAMEs)設定に SSL 証明書が必須になりました | DevelopersIO
https://dev.classmethod.jp/cloud/aws/201904_enhancing-domain-security-on-cloudfront/
■費用について
S3にCloudFrontを通すことで月20万ぐらい節約した話 - Qiita
https://qiita.com/katsunory/items/2663baef6a14550078d9
S3から直接配信せずに、CloudFrontを挟むことで大幅に費用を削減できたという話
ただ、本当にCloudFrontを挟むだけで安くなるのかは疑問
単純にCloudFrontを挟むと、むしろS3からの直接配信より若干高額になるのでは
ただし以下のサイトによると月の配信容量が150TBを超えるくらいからCloudFrontの方が安くなるらしいので、
上の話は相当な容量の動画を配信しているサイトのことなのかもしれない
S3ウェブホスティングとS3 + CloudFront構成の料金比較 - Qiita
https://qiita.com/yamamoto_y/items/c58ae2083a792d8b7b0f
gzipを使うことで削減する方法はあるみたい
[超簡単]cloud frontの料金を最大1/5に減らす節約方法 | YongJin Kim's Blog
https://yongjinkim.com/%E8%B6%85%E7%B0%A1%E5%8D%98cloud-front%E3%81%AE%E6%96%99%E9%87%91%E3%82%92%E6...
AWSのCloudFrontでアセットをHTTP2 & gzipで高速に配信する - Clueit Developersブログ
http://cluex-developers.hateblo.jp/entry/cloudfront-with-http2-and-gzip
以下は公式ツールによる試算
見積もり:
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=files/calc-2dbf71fce105f5593d...
上記の見積もりで、「Amazon S3 → データ転送」の「データ転送送信」を「10 GB/月」から変更してみる
10 GB/月 ... 月額 $ 162.29(デフォルト)
100 GB/月 ... 月額 $ 172.55
1000 GB/月 ... 月額 $ 275.15
10000 GB/月 ... 月額 $ 1301.15
上記の見積もりで、S3を変更せずに「Amazon CloudFront → データ転送の「データ転送送信」を「10 GB/月」から変更してみる
10 GB/月 ... 月額 $ 162.29(デフォルト)
100 GB/月 ... 月額 $ 172.64
1000 GB/月 ... 月額 $ 276.09
10000 GB/月 ... 月額 $ 1310.58
CloudFrontからの配信の方が、若干高額であることが判る
また、月に1TBくらいの動画配信なら、大体10,000〜12,000円くらいであることも判る
以下のページで「1TBで月額$116」となっているので、公式の試算とも一致する
オンデマンド動画配信のためのクラウド構成と料金試算例 | AWS
https://aws.amazon.com/jp/cdp/cdn/
■EC2の構築(準備)
203.0.113.1 ... ごく普通の設定でApache+PHPが動いているとする
203.0.113.9 ... アクセス元のIPアドレスとする
http://203.0.113.1/
http://203.0.113.1/sample/
※ブラウザでアクセスすると、当然ながら REMOTE_ADDR にはIPアドレス 203.0.113.9 が入る
■ロードバランサーを導入(準備)
「ロードバランサー → EC2」
という構成を作成。
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/sample/
※REMOTE_ADDR には 10.0.0.71 が入る(ロードバランサーのIPアドレス)
HTTP_X_FORWARDED_FOR に 203.0.113.9 が入る(アクセス元のIPアドレス)
■CloudFrontを導入(キャッシュさせない設定でEC2に導入する場合)
EC2(ロードバランサー)にCloudFrontを導入し、キャッシュさせずに配信する
CloudFront → Create Distribution → Web → Get Started
Origin Domain Name: 作成したロードバランサーを選択
Origin ID: 自動的に入力されるので変更せず
以下、キャッシュさせないための設定
Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
Forward Headers: All (Allにすると、Minimum TTL・Maximum TTL・Default TTL は 0 として扱われるみたい)
Forward Cookies: All
Query String Forwarding and Caching: Forward all, cache based on all
2017年11月に確認すると、「Forward Headers」の設定が無くなっている
以下の設定のみでいいかも
[AWS] Amazon CloudFrontのキャッシュ無効化(TTL設定) | Developers.IO
https://dev.classmethod.jp/server-side/aws-amazon-cloudfront-no-cache-by-ttl-setting/
Object Caching: Use Origin Cache Headers
Minimum TTL: 0
Maximum TTL: 31536000
Default TTL: 86400
↓
Object Caching: Customize
Minimum TTL: 0
Maximum TTL: 0
Default TTL: 0
「Create Distribution」ボタンを押す
Distributionの一覧が表示されるので、「Status」が「Deployed」に変わるのを待つ
(完了までに15分程度かかる)
一覧からIDを選択し、その後表示される「Domain Name」にあるURLにアクセスすると、
オリジナルサーバと同じ内容が表示される。キャッシュされていないことも確認する
(「Status」が「Deployed」に変わってからも、数分間はアクセスできなかった)
http://123456789.cloudfront.net/
http://123456789.cloudfront.net/sample/
可能なら、TTLは「0」よりも「1」の方がいいかも
(0だとそのままオリジンにアクセスされるため、大量アクセスからの保護のためにも1秒にしておくといいみたい)
AWS CloudFrontで極力キャッシュさせたくない時の話 - Qiita
https://qiita.com/shogomuranushi/items/a2367350ea54a8f41257
※REMOTE_ADDR には 10.0.1.120が入る(ロードバランサーのIPアドレスと思われる)
HTTP_X_FORWARDED_FOR に 203.0.113.9, 204.246.186.45 が入る
(1つ目はアクセス元のIPアドレス、2つ目はCloudFrontのIPアドレスと思われる)
■CloudFrontを導入(キャッシュする設定でS3に導入する場合)
S3にCloudFrontを導入し、キャッシュしつつ配信する
今回参照するバケットは以下のとおり
https://refirio-test.s3-ap-northeast-1.amazonaws.com/
CloudFront → Create Distribution → Web → Get Started
Origin Domain Name: refirio-test.s3.amazonaws.com
Origin ID: 自動的に入力されるので変更せず
「Create Distribution」ボタンを押す
Distributionの一覧が表示されるので、「Status」が「Deployed」に変わるのを待つ
(完了までに10分程度かかる)
一覧からIDを選択し、その後表示される「Domain Name」にあるURLにアクセスする
Distribution ID: EVEVZHDVZEK34
ARN: arn:aws:cloudfront::123456789012:distribution/EVEVZHDVZEK34
Domain Name: 123456789.cloudfront.net
オリジナルサーバと同じ内容が表示される
https://refirio-test.s3-ap-northeast-1.amazonaws.com/images/brownie.jpg
https://refirio-test.s3-ap-northeast-1.amazonaws.com/movie/flower.mp4
https://123456789.cloudfront.net/images/brownie.jpg
https://123456789.cloudfront.net/movie/flower.mp4
キャッシュされていることも確認する(test1.txt を更新しても、CloudFront経由だと反映されない)
https://refirio-test.s3-ap-northeast-1.amazonaws.com/test1.txt
https://123456789.cloudfront.net/test1.txt
■CloudFrontのキャッシュを削除する場合
※キャッシュの削除は「1ヶ月に1000回まで無料」となっている
頻繁に削除が必要な設計にしないように注意する
CloudFront → 対象のIDを選択 → Invalidations → Create Invalidation
「Object Paths」に以下のように入力し、「Invalidate」をクリック
/test1.txt
/test2.txt
Invalidateの一覧が表示されるので、「Status」が「Completed」に変わるのを待つ
(完了までに1分程度かかるが、9割ほどは5秒程度で削除される)
https://refirio-test.s3-ap-northeast-1.amazonaws.com/text/test1.txt
https://123456789.cloudfront.net/text/test1.txt
「Object Paths」に以下のように入力し、「Invalidate」をクリック
/text/test1.txt
/text/test2.txt
「Object Paths」に以下のように入力し、「Invalidate」をクリック
/text/*
AWS CloudFrontのキャッシュを削除する - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2019/05/15/cloudfront-cache-clear/
【朗報】Amazon CloudFrontのキャッシュ削除(Invalidation)が速くなりました【5秒で90%】 | Developers.IO
https://dev.classmethod.jp/articles/cloudfront-fast-invalidation/
■エラーのキャッシュ時間を変更する
CloudFrontはデフォルト設定では、エラーを5分間キャッシュする
つまりPHPの編集時などに500エラーを発生させてしまうと、修正しても5分間はアクセスできないままになる
開発初期は念のため、10秒程度にしておくといいかも
キャッシュの設定は以下の方法で設定できる
CloudFront → 対象のIDを選択 → Error Pages → Create Custom Error Response
HTTP Error Code: 500 Internal Server Error
Error Caching Minimum TTL (seconds): 任意の秒数
Customize Error Response: 専用のエラーページを表示したい場合に設定
500エラー以外も、同じ手順で設定できる
Amazon CloudFront で HTTP 4xx 5xx ステータスコードのキャッシュ時間を変更する | Developers.IO
https://dev.classmethod.jp/cloud/aws/amazon-cloudfront-error-caching-minimum-ttl/
■独自ドメインに対応させる
CloudFront → 対象のIDを選択 → General → Edit
Alternate Domain Names(CNAMEs)
にドメインを設定する(例:www.refirio.net)
設定しないと以下のエラーになる
キャッシュのタイミングによっては、しばらくアクセスできているように見えるかも
ERROR
The request could not be satisfied.
Bad request.
■ドメイン割り当て前のアクセステスト
CloudFrontは固定IPアドレスを持たない
よって、Windowsのhostsファイルを編集するなどしてCloudFrontにアクセスしたい場合、その時点のIPアドレスを調べる必要がある
例えばCloudFrontのURLが
123456789.cloudfront.net
でブラウザから
http://123456789.cloudfront.net/
でアクセスできる場合、nslookupコマンドを使って以下のようにすればCloudFrontのIPアドレスを調べることができる(digコマンドでも可)
$ nslookup 123456789.cloudfront.net
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: dmmhiae2wjxfb.cloudfront.net
Address: 203.0.113.1
Name: dmmhiae2wjxfb.cloudfront.net
Address: 203.0.113.2
Name: dmmhiae2wjxfb.cloudfront.net
Address: 203.0.113.3
Name: dmmhiae2wjxfb.cloudfront.net
Address: 203.0.113.4
この場合、ロードバランサーは 203.0.113.1 と 203.0.113.2 と 203.0.113.3 と 203.0.113.4 のIPアドレスを持つ
よって、Windowsのhostsファイルなどで
C:/windows/System32/drivers/etc/hosts
203.0.113.1 refirio.net
このように設定すると、
http://refirio.net/ でアクセスしたときにCloudFront経由でアクセスできる
(203.0.113.1 と 203.0.113.2 と 203.0.113.3 と 203.0.113.4 のどれを指定してもいい)
エラーになる場合、「独自ドメインに対応させる」の設定を行なっているか確認する
■SSLに対応させる
※無料SSL証明書を実際に試したときのメモは「Certificate Manager」を参照
ACMで証明書を発行し、CloudFrontに設定する…という流れで設定できる
CloudFrontとELB間をSSLで通信させる | Developers.IO
http://dev.classmethod.jp/cloud/aws/cloudfront_elb_ssl_traffic/
[ACM] AWS Certificate Manager 無料のサーバ証明書でCloudFrontをHTTPS化してみた | Developers.IO
https://dev.classmethod.jp/cloud/aws/acm-cloudfront-ssl/
ただし、現状色々と注意点があるみたい
・古い環境でアクセスできなくなる
・S3との連携には制限がある
・CloudFront の証明書は、バージニア北部リージョンに入れる必要がある
・CloudFrontとELBで同じFQDNを使う場合、ELB側のACMは自動更新できない恐れがある
・外部で購入したSSL証明書は、CDNでの使用が許されてるか要確認。オリジンのサーバ数だけライセンス購入が必要なことがある
管理画面から証明書を登録できない…と解説されていることがあるが、ごく最近の解説では触れられていない
今は大丈夫なのかも?
CloudFrontで独自ドメインのSSL設定する方法 | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/3181
以下、その他参考になりそうなページ
代替ドメイン名 (CNAME) を使用する - Amazon CloudFront
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html
CloudFront に SSL 証明書を導入する際のポイントまとめ - Qiita
https://qiita.com/koseki/items/4462b09f1527ad07bdce
CloudFrontの下でWordpressを実行する時に色々ハマった話 前編 - Qiita
https://qiita.com/kunitaya/items/1a78cd2d4d2971394e0d
CloudFront × WordPressで格安高速エンジニアブログを作ってみた | TABI LABO TECH BLOG
https://tech.tabilabo.co.jp/40/
[GitHub Pages] 独自ドメインをCloudFrontでSSL化 - onox blog
https://onoxeve.com/posts/github-pages-ssl-certificate/
Route53でドメイン買ってACMでSSL証明書発行してCloudFrontでGithub Pageと買ったドメインと紐付けた - Qiita
https://qiita.com/yamanoku/items/c4f9c28d79f981afc40f
■SSLにリダイレクトさせる
httpでアクセスされたとき、httpsにリダイレクトする
EC2側で「SSLか否か」を判定しようとしても、CloudFront以降はhttpでアクセスされることが多いので判定が難しい
CloudFrontの設定で対応できる
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
「Viewer Protocol Policy」を「Redirect HTTP to HTTPS」に変更
CloudFrontでhttpリクエストをhttpsにリダイレクトできるようになった - yoshidashingo
http://yoshidashingo.hatenablog.com/entry/2014/03/06/144345
CloudFront とカスタムオリジンとの間の通信に HTTPS を必須にする - Amazon CloudFront
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-https-cloudfront-to-c...
■ヘッダ情報を転送
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
「Cache Based on Selected Request Headers」を「Whitelist」に変更
「Accept」「CloudFront-Forwarded-Proto」「Referer」を追加
(必要なら、さらに追加する)
さらに、一覧上部のテキストボックスに「User-agent」を入力して「Add Custom >>」で追加
(設定していない場合、UserAgentは常に「Amazon CloudFront」になる)
CloudFrontを導入してもUser-agentの値は書き換えられないようにする方法。 - Qiita
https://qiita.com/kooohei/items/4dcdb506745a6a1eef66
■Basic認証に対応
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
「Cache Based on Selected Request Headers」を「Whitelist」に変更
「Authorization」を追加
CloudFrontでベーシック認証 | TF Lab - クラウド開発記録 -
https://lab.taf-jp.com/cloudfront%E3%81%A7%E3%83%99%E3%83%BC%E3%82%B7%E3%83%83%E3%82%AF%E8%AA%8D%E8%...
■バーチャルホストに対応
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
「Cache Based on Selected Request Headers」を「Whitelist」に変更
「Host」を追加
[新機能] Amazon CloudFrontでHostヘッダを転送する | Developers.IO
https://dev.classmethod.jp/cloud/cloudfront-host-header-forward/
■POSTでエラーになる
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
Allowed HTTP Methods
を
GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
に設定する
■Cookieを有効にする
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
Forward Cookies
を
All
に設定する
■画面が正しく表示されない
ブラウザによっては一部画面のCSSが反映されない
そもそも、今はキャッシュさせない設定のはずでは
外部ファイルを読み込めていない?以下が真っ白
http://www.refirio.net/wp-admin/load-styles.php?c=0&dir=ltr&load%5B%5D=dashicons,buttons,forms,l10n,login&ver=4.9
以下がより細かくキャッシュさせる設定みたい
これで正しく表示された
CloudFront → 対象のIDを選択 → Behaviors → 対象を選択 → Edit
Query String Forwarding and Caching
を
Forward all, cache based on all
に設定する
■ログを記録する
CloudFront → 対象のIDを選択 → General → Edit
一例だが、以下のように設定する
しばらく待つと、S3にログが保存され始める
Logging: On
Bucket for Logs: ログ出力先のS3バケット
Log Prefix: cf-logs/
Amazon CloudFront編〜アクセスログを取得してみよう!〜|S3 バケット ログ収集 CDN 使用方法 | ナレコムAWSレシピ
https://recipe.kc-cloud.jp/archives/2624
■タイムアウト時間を調整する
Webアプリケーションからの巨大ファイルのアップロードなどで、処理がタイムアウトしてしまう問題について
・PHPの設定を変更しても、その上位で60秒の制限があるので解除が必要。
・nginxに制限があるが、設定を変更することで600秒などに伸ばすことが可能。
・ロードバランサーにも制限があるが、設定を変更することで600秒などに伸ばすことが可能。
・CloudFrontにも制限があるが、デフォルトで30秒。これは60秒以上に伸ばすことができない。
いますぐ使う CloudFront - Qiita
https://qiita.com/sasasin/items/0f0ec1a90af6295589f9
Amazon CloudFrontのオリジンタイムアウトが変更できるようになりました | Developers.IO
https://dev.classmethod.jp/cloud/aws/change-cloudfront-origin-timeouts/
ディストリビューションを作成または更新する場合に指定する値 - Amazon CloudFront
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-spe...
対処1:
AWSに例えば600秒に伸ばすように申請する(可否は要検証だが、無限に伸ばせるわけでは無いかもしれないので注意)
対処2:
CloudFrontを外す
対処3:
一部の処理のみ、CloudFrontを経由しない(あまり良い方法では無いかもしれない)
■CloudFrontの経由を強制
※未検証
【アップデート】Amazon CloudFront を経由しないアクセスのブロックが簡単になりました | DevelopersIO
https://dev.classmethod.jp/articles/amazon-cloudfront-managed-prefix-list/
■署名付きURLで限定配信
CloudFrontの署名付きURLでS3にアクセスする方法 - Qiita
https://qiita.com/jeayoon/items/c148a8637a177c0f8c9f
CloudFront+S3で署名付きURLでプライベートコンテンツを配信する
http://dev.classmethod.jp/cloud/aws/cf-s3-deliveries-use-signurl/
Amazon CloudFront で HLS動画のプライベートオンデマンド配信を行う方法
http://akiyoko.hatenablog.jp/entry/2015/08/24/192618
URLに特定の文字列が含まれていないとアクセスできないようにする
また、そのURLにはアクセスできる期間も指定できる
コンテンツの限定配信に使える
以下の手順はCloudFrontを無視してS3に直接アクセスできるので、できればそちらも制限したい(CloudFront側にそのような設定がある)
以下のバケットを参照するものとする
https://develop-123456789.ap-northeast-1.elb.amazonaws.com/
CloudFront → Create Distribution → Web → Get Started
Origin Domain Name: develop-123456789.s3.amazonaws.com
Origin ID: 自動的に入力されるので変更せず
「Create Distribution」ボタンを押す
Distributionの一覧が表示されるので、「Status」が「Deployed」に変わるのを待つ
(完了までに10分程度かかる)
https://123456789.cloudfront.net/brownie.jpg
CloudFront → 対象のIDを選択 → Behaviors → 対象のオリジンを選択 → Edit
以下のように変更して「Yes, Edit」をクリックする
Restrict Viewer Access (Use Signed URLs or Signed Cookies): Yes
… アクセスの際に署名付きURLか署名付きCookieを求める
https://123456789.cloudfront.net/brownie.jpg
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>MissingKey</Code>
<Message>Missing Key-Pair-Id query parameter or cookie value</Message>
</Error>
これだとアクセスできないだけなので、署名付きURLを使えるようにする
rootアカウントでAWSコンソールにサインインする
マイセキュリティ資格情報 → CloudFrontのキーペア → 新しいキーペアの作成
キーペアが作成されるので、
「プライベートキーファイルのダウンロード」と「パブリックキーファイルのダウンロード」
からそれぞれのキーをダウンロードしておく
今回は以下のファイルがダウンロードできた
プライベートキーファイル ... pk-APKAIRZZSSNKVA5FUH6X.pem
パブリックキーファイル ... rsa-APKAIRZZSSNKVA5FUH6X.pem
ダイアログを閉じるとキーペアの一覧が表示され、作成日やアクセスキーIDなどを確認できる
アクセスキーIDは「APKAIRZZSSNKVA5FUH6X」となっていた(後で使用する)
検証のために、以下のPHPプログラムを作成
署名付きURLを発行し、10秒間だけ test1.txt にアクセスできるようにする
アクセスキーとシークレットアクセスキーは無くても実行できた。別途プライベートキーを使っているからだと思われる
プライベートキーは上でダウンロードしたもの
<?php
require 'vendor/autoload.php';
use Aws\CloudFront\CloudFrontClient;
try {
$client = new Aws\CloudFront\CloudFrontClient([
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
$result = $client->getSignedUrl([
'url' => 'https://123456789.cloudfront.net/test1.txt', // 表示するファイル
'expires' => time() + 10, // URLの期限は10秒
'private_key' => 'cloudfront-kids/pk-APKAIRZZSSNKVA5FUH6X.pem', // プライベートキー
'key_pair_id' => 'APKAIRZZSSNKVA5FUH6X' // アクセスキーID
]);
print_r($result);
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
署名付きURLでアクセスできるようになった
バケットポリシーのアクセス制限については要確認
https://develop-123456789.s3-ap-northeast-1.amazonaws.com/test1.txt
https://123456789.cloudfront.net/test1.txt
https://123456789.cloudfront.net/test1.txt?Expires=1587352798&Signature=dt3PhFcUqsRyDgIaYCMOseAa...
動画の配信もテスト
特に問題は無さそう
https://develop-123456789.s3-ap-northeast-1.amazonaws.com/test/1.mp4
https://123456789.cloudfront.net/test/1.mp4
https://123456789.cloudfront.net/test/1.mp4?Expires=1587353157&Signature=izvCUYMq4NwgA2HfxyaMIAI...
機能しているが、S3へのリダイレクト扱いになっている
…が、これは24時間待てば自動で解決した
S3+CloudFrontでS3のURLにリダイレクトされてしまう場合の対処法 | Developers.IO
https://dev.classmethod.jp/articles/s3-cloudfront-redirect/
■レスポンスヘッダの設定
※未検証
L@EとCF2が不要に?!CloudFront単体でレスポンスヘッダーが設定できるようになりました | DevelopersIO
https://dev.classmethod.jp/articles/cloudfront-support-response-headers-policies/
■データ転送量の確認
CloudFront → Reports & analytics → Usage
で、リクエスト数や転送量などを確認できる
また詳細を確認したい
CloudFront 使用状況レポート - Amazon CloudFront
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/usage-charts.html
■WordPressでCloudFrontを使う場合の参考ページ
WordPressサイトをCloudFrontで配信する - Qiita
https://qiita.com/Ichiro_Tsuji/items/38592e737257cb45ca13
WCT2016:WordPressのCDN設定/Cloudfront レベル2 | J-Stream CDN情報サイト
https://tech.jstream.jp/blog/meeting/wct2016cloudfront-l2/
WCT2016:WordPressのCDN設定/Cloudfront レベル3 | J-Stream CDN情報サイト
https://tech.jstream.jp/blog/meeting/wct2016cloudfront-l3/
■大量アクセスを捌くときの参考ページ
Amazon CloudFront の デフォルト上限値が更に大幅にアップしました!(2016秋) | Developers.IO
https://dev.classmethod.jp/cloud/aws/cloudfront-limit-update-201610/
CloudFrontを使ったサイト公開のハマりどころ | HAWSクラウドサービス
http://haws.haw.co.jp/tech/cloudfront-site-publish/
Cloud front limit increase
https://www.slideshare.net/AmazonWebServicesJapan/cloud-front-limit-increase
■WAF
Web Application Firewall
CloudFrontやロードバランサーにファイヤーウォールを設定し、不正なアクセスをブロックできる
SQLインジェクションなどに対応できる
セキュリティグループとは特性の違う攻撃の対策になる
ただしセキュリティグループとは違って若干お金はかかる
AWS WAFでSQLインジェクションをブロックしてみた | Developers.IO
http://dev.classmethod.jp/cloud/aws/aws-waf-sqli/
AWS WAFがALB(Application Load Balancer)で利用出来るようになりました
http://dev.classmethod.jp/cloud/aws/aws-waf-alb-support/
AWS WAF を急に導入することになったときに参考にした資料まとめ | DevelopersIO
https://dev.classmethod.jp/articles/blog-links-for-aws-waf-configuration/
※以前はCloudFrontが必須だったが、現在はALBでも使えるようになっている
ELBを導入済みの場合、ALBに変更することでWAFを使えるようになる
以下にVer2の解説がある
操作方法が大きく変わっているので注意
AWS WAFを完全に理解する ~WAFの基礎からv2の変更点まで~ | Developers.IO
https://dev.classmethod.jp/cloud/aws/fully-understood-aws-waf-v2/
以下、Ver2で検証したもの
■テストページ
index.php:
<html>
<meta charset="UTF-8">
<head>
<title>ログイン画面</title>
</head>
<body>
<form action="db.php" method="post">
<table>
<tr>
<td>ユーザID</td>
<td><input type="text" name="uid"></td>
</tr>
<tr>
<td>パスワード</td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="ログイン">
</form>
</body>
</html>
db.php:
<html>
<meta charset="UTF-8">
<head>
<title>ログイン処理</title>
</head>
<body>
<pre><?php
$uid = $_POST['uid'];
$pass = $_POST['password'];
print("SELECT email FROM users WHERE uid='$uid' AND passwd='{$pass}'");
?></pre>
</body>
</html>
ブラウザからindex.phpにアクセスし、
ユーザID: test
パスワード: test
で認証すれば通常通り処理されるが、
ユーザID: test
パスワード: ' OR 'A' = 'A
で認証すれば「403 Forbidden」と表示される(WAFで入力を弾いている)
…となるように以降で設定する
■WAFを導入
SQLi と XSS を防ぐための AWS WAF ルール
https://aws.amazon.com/jp/premiumsupport/knowledge-center/waf-rule-prevent-sqli-xss/
WAF & Shield → Create web ACL
Step 1: Describe web ACL and associate it to AWS resources
Name: test
CloudWatch metric name: test(自動で入力される)
Resource type: Regional resources(CloudFrontに対して設定したい場合、「CloudFront distributions」にする)
Region: Asia Pacific (Tokyo)
Associated AWS resources: study(ここでは、テストで作成したALBを選択した)
「Next」ボタンを押す
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック
Rule type: Rule builder
Name: SQL-injection
Type: Regular rule
If a request: matchs the statement
Inspect: Body(HTMLフォームを検査する)
Content type: Plain text
Match type: Contains SQL injection attacks
Text transformation: URL decode(URLデコードを行った後で検査する)
Oversize handling: Continue
Sensitivity level: Low
Action: Block
「Add rule」をクリックし、ページ上部の「Rules」部分にルールが追加されたことを確認する
Default action: Allow(デフォルトのまま)
「Next」ボタンを押す
Step 3: Set rule priority
そのまま「Next」ボタンを押す
Step 4: Configure metrics
そのまま「Next」ボタンを押す
Step 5: Review and create web ACL
内容を確認して「Create web ACL」ボタンを押す
■動作確認
http://203.0.113.1/waf/ ... ALBを経由しないアクセスなのでWAFは無効になっている
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/ ... ALBに対して設定したのでWAFが有効になっている
WAFは、なるべく後ろにある方が良さそう
基本的にCloudFrontに対してよりも、ALBに対してWAFを設定すると良さそう
(AWSへの直接アクセスを禁止するなら、CloudFrontへの設定でいい)
WAFが機能しない場合、意図したAWSリソースが選択されているかなどを確認する
■XSS対策の例
「WAFを導入」と基本的には同じ手順で導入できる
その際、「Step 2」の操作内容は以下のようにする
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック
Rule type: Rule builder
Name: XSS-injection
Type: Regular rule
If a request: matchs the statement
Inspect: Body(HTMLフォームを検査する)
Content type: Plain text
Match type: Contains XSS injection attacks
Text transformation: URL decode(URLデコードを行った後で検査する)
Oversize handling: Continue
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する
これで
ユーザID: test
パスワード: <script>window.alert(1)</script>
で認証すれば「403 Forbidden」と表示される(WAFで入力を弾いている)
■IP制限の例
AWS WAFV2でIPアドレス制限してみた | DevelopersIO
https://dev.classmethod.jp/articles/how-to-use-aws-waf-v2-to-filter-incoming-traffic-based-ip-addres...
練習を兼ねて&即座にIP制限ができるように、IP制限の設定だけは最初にしておくといい
以下は設定を試したときのメモ
この場合、「192.0.2.1」からのアクセスが拒否される
WAF & Shield → IP sets → Create IP set
IP set name: Black-List
Region: Asia Pacific (Tokyo)
IP version: IPv4
IP addresses: 192.0.2.1/32
以降は「WAFを導入」と基本的には同じ手順で導入できる
その際、「Step 2」の操作内容は以下のようにする
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック
Rule type: IP set
Name: IP-Restriction
IP set: Black-List(上の手順で作成したものを選択)
IP address to use as the originating address: Source IP address
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する
これで「Black-List」のIPアドレスを更新することで、IP制限を行うことができる
(反映には、10〜20秒ほどのタイムラグがある)
制限対象とするIPアドレスは、「WAF & Shield → IP sets → Black-List」の画面から追加削除できる
■大量アクセスを自動的にIP制限する例
AWS WAF でアクセス数が一定回数を超えた IP アドレスを自動的にブラックリストに追加させる方法 | DevelopersIO
https://dev.classmethod.jp/articles/tsnote-aws-waf-autoblock/
「WAFを導入」と基本的には同じ手順で導入できる
その際、「Step 2」の操作内容は以下のようにする
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック
Rule type: Rule builder
Name: DoS-Protection
Type: Rate-based rule
Rate limit: 100(最小値が100)
IP address to use for rate limiting: Source IP address
Criteria to count request towards rate limit: Consider all requests(特定パス配下にのみ設定したければ「Only consider requests that match the criteria in a rule statement」を選択し、追加で必要な設定を行う)
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する
これで大量アクセスすると自動でブロックされる
Web ACLs「test」の「Overview」で「DoS-Protection BlockedRequests 200」を確認できる。200回ブロックされたということだと思われる
$ curl -I
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
HTTP/1.1 200 OK
Date: Thu, 12 Jan 2023 10:41:33 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Server: Apache/2.4.54 ()
X-Powered-By: PHP/8.1.12
Upgrade: h2,h2c
$ ab -n 10 -c 1
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 10
Failed requests: 0
$ ab -n 100 -c 1
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 100
Failed requests: 0
$ ab -n 200 -c 1
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 200
Failed requests: 0
$ ab -n 300 -c 1
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 300
Failed requests: 0
以下のように403エラーが返されるようになったが、上記のように「Failed requests」にはカウントされないみたい
また、403エラーが返されるようになるまで数分のタイムラグがあった
$ curl
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/ --verbose
* Trying 203.0.113.1:80...
* Connected to develop-123456789.ap-northeast-1.elb.amazonaws.com (203.0.113.1) port 80 (#0)
> GET /test/ HTTP/1.1
> Host: develop-123456789.ap-northeast-1.elb.amazonaws.com
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: awselb/2.0
< Date: Fri, 13 Jan 2023 06:25:44 GMT
< Content-Type: text/html
< Content-Length: 118
< Connection: keep-alive
<
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>
* Connection #0 to host develop-123456789.ap-northeast-1.elb.amazonaws.com left intact
ブロックされたリクエストは、Web ACLs「test」の「Overview」の「Sampled requests」で確認できるみたい
IPアドレスや対象URLなどを確認できる
(受信したリクエストから、AWS WAFがランダムに選択したものが表示されるみたい
すべてのログを記録する場合、「Logging and metrics」タブから設定できるみたい)
また、このIP制限は一定時間が経過すると自動で解除される
30分ほどで自動解除されていることは確認できた(大量アクセスが落ち着いたら時点で解除されるのかもしれない)
■その他の制限例
AWS WAFで日本国外からのアクセスをブロックする - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/aws-waf-block-from-overseas-countries
AWS WAF で Bot からのアクセスを管理する Bot Control が利用可能になりました! | DevelopersIO
https://dev.classmethod.jp/articles/aws-bot-control/
[アップデート]AWS WAFのBot Controlルールグループに検査レベル「Targeted」が追加され、新たに4つのインテリジェントなルールが利用可能になりました | DevelopersIO
https://dev.classmethod.jp/articles/aws-waf-targeted-bot/
レートベースルールで検知したIPをIP Setに登録する | DevelopersIO
https://dev.classmethod.jp/articles/add-ratebase-rule-deny-ip/
■ブロック時の画面をカスタマイズする
WAFで制限されると、そのリクエストの画面には「403 Forbidden」とだけ表示される
これだけだと何の影響でエラーになっているのか判りづらいので、問い合わせ対応のためにも独自のメッセージを表示させておくといい
AWS WAFの機能だけでブロック時にカスタムエラーページを表示させてみた | DevelopersIO
https://dev.classmethod.jp/articles/aws-waf-custom-response_bodies_html/
WAFの設定画面でルールを追加する際、Actionで「Block」を選択してCustom response内で以下のように設定する
Enable: (チェックを入れる)
Response code: 403
Choose how you would like to specify the response body: Create a custom response body
すると「Create a custom response body」というダイアログが開くので、以下のように登録する
Response body object name: 403
Content type: HTML
Response body: (任意のHTML)
登録した内容は、次回からは「Choose how you would like to specify the response body」の選択肢に表示される
「任意のHTML」は4KB以内で作成する
また、ヘッダでUTF-8を宣言しておくといい
以下は具体的なHTMLの例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>403 Forbidden</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
</head>
<body>
<h1>403 Forbidden</h1>
<p>ウェブアプリケーションファイアウォールによりアクセスが遮断されました。</p>
<p><a href="/">トップページへ戻る</a></p>
</body>
</html>
■マネージドルール
ルールを追加する際、「Add my own rules and rule groups」ではなく「Add managed rule groups」を選択するとマネージドルールの選択画面になる
あらかじめ定義されたルールを適用できるので、運用を楽にすることはできそうだが、利用料金がかかるので注意
AWS WAF向けマネージドルールのおすすめは?種類別サービス7選|アスピック
https://www.aspicjapan.org/asu/article/11671
■誤検知対策
ロリポップのWAFは、有効にするとWordPressなどがまともに動かなくなるらしい
記事投稿時にWAFをOFFにするか、常にWAFをOFFにするか…のように紹介されている
WordPress403 Forbiddenの原因はWAF!対処し解決する方法!:ロリポップ、さくら、ヘテムルのサーバー
http://bibabosi-rizumu.com/403error-forbidden/
ロリポップ+WordPress+Contact Form 7でWAFが誤動作してForbiddenになるんだけどどういうことなの | texst.net
http://texst.net/lolipop-waf-wordpress-cf7-forbidden/
AWSのWAFも同じことになる可能性はあるが、
「AWS Black Belt Tech Webinar 2015 ‐ AWS WAF」レポート | Developers.IO
http://dev.classmethod.jp/cloud/aws/blackbelt2015-waf/
にて
「これまでのWAF: 誤検知 (false positive) が増えて悩むことになった」
「AWS WAFには、次のような特長がある: ルールを柔軟にカスタマイズできる」
のように紹介されている。柔軟にカスタマイズすることで、誤検知の対策はできるのかも。要勉強
本番環境でWAFを導入する場合、テスト段階でも導入して動作確認しておかないと、
アプリケーションが正しく動作しない可能性がありそうなので注意
…と思いつつ案件に本格導入しようとしたが、検収環境での検証時に「ファイルをアップロードできない」という問題が発生した
AWS WAF によってブロックされたファイルのアップロード
https://aws.amazon.com/jp/premiumsupport/knowledge-center/waf-upload-blocked-files/
【AWS】特定のURIリクエストのみAWS WAFルールを適用させない方法 - Qiita
https://qiita.com/yokoo-an209/items/7037aed6fbe18fb4c659
WordPress + AWS WAF設定時の注意点 - Qiita
https://qiita.com/hirai-11/items/252705c33914dcab000c
AWS上のWebシステムへのファイルアップロード時にAWS WAFでブロックされる。
https://teratail.com/questions/heafxwwa3541vz
AWS WAFのマネージドルールでありがちな予期せぬブロック(随時更新) - mazyu36の日記
https://mazyu36.hatenablog.com/entry/2023/02/21/191736
AWS WAF を本適用の前にカウントモードで試用したい - DENET 技術ブログ
https://blog.denet.co.jp/aws-waf-count/
現状「ファイルアップロードは除外」などは対応不可らしい
対応するなら「WAFに対して(あらかじめ安全だと確認できている)特定のURI時のリクエストに対してブロックルールを適用しない」とする必要があるらしい
…が、本番環境に導入したら
「特定のURLから投稿できない。ルールの調整を忘れていた」
「ここは問題無いと思っていたがWAFに引っかかった」
が時々発生して障害になりそうな。他にも、新たな問題が発覚したりはありそうな
よって、2023年3月時点では導入を見送った
■メモ
AWS Shield はDDoS攻撃を緩和させるサービス
Standardは自動で適用されているため、ユーザ側での設定は不要
Advancedにするには、AWSサポートのビジネスレベルかエンタープライズレベルである必要がある
5分で分かるAWS Shield
https://recipe.kc-cloud.jp/archives/9009
ただし運用していてDos攻撃を受けることはあるので、どの程度機能しているのかは不明
以下などのように、攻撃してきたIPアドレスを自動で弾くなどの対策が必要そう
AWS WAFを使って簡単にDoS攻撃を防いでみよう【セキュリティ対策】 | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/4070
■ネットワークACL
攻撃を受けたのでIPアドレスでアクセス制限…としようとしても、
CloudFrontやロードバランサーがある場合などIPアドレスの判定が厄介なことがある
ネットワークACLを使えば「このVPCへのアクセスを制限」という制限ができるみたい
また、セキュリティグループはホワイトリスト方式のみだが、ネットワークACLはブラックリスト方式にも対応している
特定アクセスの制限に便利そう
VPC → ネットワーク ACL
対象のネットワークACLを選択して「インバウンドルール」タブを選択する
(慌てて別のネットワークACLで作業しないように注意)
Rule # Type Protocol Port Range Source Allow / Deny
100 すべてのトラフィック すべて すべて 0.0.0.0/0 ALLOW
* すべての トラフィック すべて すべて 0.0.0.0/0 DENY
以下のように1行目を追加すると、203.0.113.1 からのアクセスが拒否される(VPC自体にアクセスできなくなる)
ルール番号は、番号の若いものから順に評価される
Rule # Type Protocol Port Range Source Allow / Deny
50 すべてのトラフィック すべて すべて 203.0.113.1/32 DENY
100 すべてのトラフィック すべて すべて 0.0.0.0/0 ALLOW
* すべての トラフィック すべて すべて 0.0.0.0/0 DENY
AWSでポチポチっとアクセス制限 - Qiita
https://qiita.com/anoworl/items/8323ad42ec05014917eb
AWS :Network ACLとSecurity Groupの違い? | The Business Infosec
https://genrsa.wordpress.com/2015/03/01/aws-%EF%BC%9Anewtwork-acl%E3%81%A8security-group%E3%81%AE%E9...
AWSのネットワークACLとセキュリティグループの違い - プログラマでありたい
https://blog.takuros.net/entry/20131218/1387356888
Amazon VPCのネットワークACLについて | DevelopersIO
https://dev.classmethod.jp/cloud/amazon-vpc-acl/
■ネットワークファイアウォール
※未検証
インターネットゲートウェイ、NATゲートウェイ、VPC、DirectConnectなど、VPCの境界でトラフィックをフィルタリングできる
セキュリティグループやネットワークACLとは別に、ファイヤーウォールが追加されている?
また詳細を確認しておく
AWS ネットワークファイアウォール - VPC 用の新しいマネージド型ファイアウォールサービス | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/aws-network-firewall-new-managed-firewall-service-in-vpc/
[新サービス] VPC 向け AWS マネージドファイアウォールサービス「AWS Network Firewall」がリリースされました | DevelopersIO
https://dev.classmethod.jp/articles/aws-network-firewall/
■Trusted Advisor
https://aws.amazon.com/jp/premiumsupport/plans/
AWSコンソールに「Trusted Advisor」がある
ベーシックプランのアカウントだと
推奨されるアクション情報: 0
調査が推奨されます情報: 0
非表示のチェック項目: 0
となっていた
ただし「セキュリティ」の一部の項目を除いた、ほとんどの項目は使えなくなっている
(ビジネスサポートにすると使えるのだと思われる)
■Inspector
Amazon Inspector (自動化されたセキュリティ評価サービス) | AWS
https://aws.amazon.com/jp/inspector/
以下を参考に、エージェントなしの診断を試してみる
Amazon Inspectorで診断してみる
https://blog-asnpce.com/technology/1605
Inspector → 今すぐ始める
「Welcome to Amazon Inspector」の画面が表示されるので「 Run weekly (recommended)」をクリック
Confirmation of Assessment Runs
You have chosen to run the following assessments:
Network Assessments
1. Check for ports reachable from outside the VPC
Host Assessments
1. Check for vulnerabilities in software (CVE)
2. Host hardening benchmarks (CIS)
3. Security best practices for configuration
The assessment will be run weekly, starting now.
Agent Deployment: Inspector assessments require an agent to be installed on your EC2 instances. We will automatically install the agent for instances that allow System Manager Run Command. Learn more about Inspector Agent and how to manually install agent.
Pricing: Pricing is based on the monthly volume of usage.
とダイアログが表示され、OKボタンを押すと
SUCCESS
Run command successfully issued to install the Amazon Inspector Agent.
You can check the agent status by choosing the Preview Target button or by viewing the Systems Manager Run Command console for more details.
と表示される
以降は最初にダッシュボードが表示されるようになる
なお、上の選択はダッシュボードで「Help me create an Assessment」をクリックすると再選択できる
エージェントなしの診断を行うため、いったん「Network Assessments (Inspector Agent is not required)」にチェックを入れ、
「Advanced setup」をクリックして診断をしてみる
評価ターゲットの定義:
すべてのインスタンスを対象にしてみるので、「All Instances」はチェックを入れたまま
エージェントはインストールせずに実行したいので「Install Agents」はチェックを外す
「続行」をクリック
評価テンプレートの定義:
診断内容の定義
特に変更せずに「続行」をクリック
確認:
内容を確認して「作成」をクリック
ダッシュボードに戻ると「Recent Assessment Runs」で開始準備中になっているのが確認でき…るかと思ったが、何も反映されていなかった
が、ページを再読込すると「データを収集中」となっていた。反映までは若干のタイムラグがあるのかも
1〜2分程度で「分析完了」になった
左メニューから「結果」をクリック
以下のような診断結果が表示された
エージェントなしの初期設定診断だとポートスキャンくらいしかされないのか、サーバがきちんと設定されているから大して表示されないのか
On instance i-026fdca7, TCP port 21 which is associated with 'FTP' is reachable from the internet
On instance i-0feb0c623972fbf9f, TCP port 22 which is associated with 'SSH' is reachable from the internet
■参考
Amazon Inspectorの導入 - Qiita
https://qiita.com/s5601026/items/91ab636c9867b76c2414
Amazon Inspector を使って毎月自動で EC2 インスタンスのセキュリティ評価を実施する | DevelopersIO
https://dev.classmethod.jp/cloud/aws/sugano-018-inspector/
Amazon Inspector で定期的なセキュリティ評価の実行をスケジュールする - Qiita
https://qiita.com/hayao_k/items/7d40d795582db32b082a
■CloudWatch
※インスタンスを監視できる
※無料枠では10メトリクス、10アラームまで(詳細監視を有効にすると大量のメトリクスが作られる?)
※ログの保存は最長14日間…だったが「最長15ヶ月」に変更された
EC2 → インスタンス → 監視したいインスタンスを選択 → CloudWatchのMonitoring → アラームの追加/編集
アラーム詳細が開くので「アラームの作成」をクリック
一例として、以下の内容で登録する
通知の送信先: (通知先を選択)
次の時: 平均でCPU使用率(%)
が: >= 80 パーセント
アラーム名: web1.refirio.net CPU Utilization
「アラームの作成」ボタンを押すとアラームが作成される
追加した内容は CloudWatch からまとめて確認できる
警告メールが送られる際、「アラーム名」で指定したものが使われる
ただし警告メールの件名には日本語が使われないので、日本語を除いた件名になる
よって英語のみで意味のあるタイトルにしておくといい
作成したアラームを選択し、「変更」ボタンを押すと登録内容を修正できる
EC2の画面からだけでなく、
CloudWatch → アラーム → アラームの作成
からも作成できる
RDSはインスタンスを選択し、右上のアイコンから「Show Multi-Monitoring View」を選択し、
「CloudWatch Alarms」のC「Create Alarm」ボタンからアラームを作成できる
ELBも同様の手順で監視できる
Amazon EC2編〜EC2インスタンスを監視するには〜
http://recipe.kc-cloud.jp/archives/258
■標準メトリクスで監視
Amazon EC2編〜EC2インスタンスを監視するには〜
http://recipe.kc-cloud.jp/archives/258
通知先
refirio: info@refirio.net
対象 Name Threshold
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ELB refirio.net ELB Host Unhealthy UnHealthyHostCount >= 1 for 5 minute
ELB refirio.net ELB Client Error 4XX HTTPCode_ELB_4XX >= 10 for 5 minute (Sum ELB 4XXs)
ELB refirio.net ELB Server Error 5XX HTTPCode_ELB_5XX >= 10 for 5 minute (Sum ELB 5XXs)
ELB refirio.net HTTP Client Error 4XX HTTPCode_Backend_4XX >= 30 for 5 minute (Sum HTTP 4XXs)
ELB refirio.net HTTP Server Error 5XX HTTPCode_Backend_5XX >= 30 for 5 minute (Sum HTTP 5XXs)
Web web1.refirio.net CPU Utilization CPUUtilization >= 80 for 5 minute
Web web2.refirio.net CPU Utilization CPUUtilization >= 80 for 5 minute
RDS refirio.net RDS Storage Free Space FreeStorageSpace <= 1,000,000,000 for 5 minutes
RDS refirio.net RDS CPU Utilization CPUUtilization >= 80 for 5 minutes
またEC2インスタンスを選択し、
Actions → Cloud Watch Monitoring → Enable Detailed Monitoring
で詳細なモニタリングができる
(Detailed Monitoring や Disk Reads などが監視できるようになる)
ELBの場合「ELB メトリクス」内に「UnHealthyHostCount」があるが、
ALBの場合「ApplicationELB メトリクス」に同等の項目が無いので注意
ターゲットグループ用の項目になっているので、「Per AppELB, per TG Metrics」内の「ASIMS2 ALB Host Unhealthy」「ASIMS2 ALB Host Unhealthy」を使用する
【新機能】新しいロードバランサー Application Load Balancer(ALB)が発表されました | Developers.IO
https://dev.classmethod.jp/cloud/aws/alb-application-load-balancer/
■標準メトリクスでインスタンスのステータスを監視
原則「StatusCheckFailed が1以上か否か」という監視を付けておくと良さそう
【小ネタ】CloudWatchの「StatusCheckFailed_Instance」と「StatusCheckFailed_System」について | DevelopersIO
https://dev.classmethod.jp/articles/cloudwatch-metrix-memo-1/
OSがハングしたら自動再起動する設定AWS Cloudwatchアラームアクション | puti se blog
https://blog.putise.com/os%E3%81%8C%E3%83%8F%E3%83%B3%E3%82%B0%E3%81%97%E3%81%9F%E3%82%89%E8%87%AA%E...
インスタンスの利用可能な CloudWatch メトリクスのリスト表示 - Amazon Elastic Compute Cloud
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html
■カスタムメトリクスで監視
AWS提供のスクリプトを使用して、メモリとディスクの使用率を監視する方法
AWSでメモリやディスクの使用率とか監視する - Qiita
https://qiita.com/zaburo/items/98388ef35aa2e7a477e0
使用するアクセスキーに対して、あらかじめ EC2FullAccess と CloudWatchFullAccess の権限を与えておく
# yum install perl-Switch perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https -y
… 依存ライブラリをインストール
# yum install perl-Digest-SHA -y
… mon-put-instance-data.pl を実行して「Can't locate Digest/SHA.pm in @INC」のエラーになる場合これもインストール
# sudo mkdir /usr/local/cloudwatch
… スクリプト用ディレクトリを作成
# cd /usr/local/cloudwatch
# curl
https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip -O
… スクリプトのダウンロード
# unzip CloudWatchMonitoringScripts-1.2.2.zip
# rm CloudWatchMonitoringScripts-1.2.2.zip
# cd aws-scripts-mon
# cp awscreds.template awscreds.conf
… 設定ファイルの作成
# vi awscreds.conf
AWSAccessKeyId=XXXXX … アクセスキーID
AWSSecretKey=YYYYY … シークレットアクセスキー
# ./mon-put-instance-data.pl --mem-util --swap-util --disk-space-util --disk-path=/ --verify
… テスト実行
# vi /etc/crontab
… Cronに登録
#Mmemory Utilization
*/5 * * * * root /usr/local/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl --mem-util --swap-util --disk-space-util --disk-path=/ --from-cron
CloudWatch → メトリクス
の「カスタム名前空間」に「Linuxシステム」が追加される
上の例の場合、「Filesystem, InstanceId, MountPath」に「DiskSpaceUtilization」が、
「InstanceId」に「MemoryUtilization」「SwapUtilization」が追加されていた
それぞれの意味は以下のとおり
・DiskSpaceUtilization
… ディスク使用率
・MemoryUtilization
… メモリ使用率
・SwapUtilization
… スワップ使用率
対象 Name Threshold
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Web web1.refirio.net Disk Utilization DiskSpaceUtilization >= 80 for 5 minute
Web web1.refirio.net Mmemory Utilization MemoryUtilization >= 80 for 5 minute
Web web1.refirio.net Swap Utilization SwapUtilization >= 80 for 5 minute
記録されていない場合、以下のように「--verbose」を付けて実行するとエラー内容を確認できる。例えば
「ERROR: Failed to call CloudWatch: HTTP 400. Message: AccessDeniedException","Message":"User: arn:aws:iam::1234567890:user/production is not authorized to perform: cloudwatch:PutMetricData」
と表示される場合、使用しているアクセスキーの権限が不足している
# /usr/local/cloudwatch/aws-scripts-mon/mon-put-instance-data.pl --mem-util --swap-util --disk-space-util --disk-path=/ --verbose
2015年時点では以下の記事を参考にして設定した
AWS EC2でメモリ利用率をCloud Watchで監視する
http://qiita.com/masarufuruya/items/212adbfb285476683c47
【AWS】カスタムメトリクスを使ったプロセス監視(Linux編)【CloudWatch】 - Qiita
https://qiita.com/koomaru/items/ac274f96fd541ffe4c31
はじめてのCloudWatch(AWS) 〜カスタムメトリクスを作って無料枠でいろいろ監視する〜 - Qiita
https://qiita.com/hilotter/items/5d5c7cddb5e580bd7aa5
AWS CloudWatchでEC2を監視する (プロセス死活監視、ディスク使用率、iノード使用率を監視してアラートメールを送信する) - Qiita
https://qiita.com/na0AaooQ/items/9dc3649e0bf4b0193ef9
■アラーム状態からの復旧を通知
「アクションの設定」で「通知」を登録する際、デフォルトでは「アラーム状態」になったときの通知設定になっている
ここで「OK」になったときの通知設定を追加することで、アラーム状態からの復旧を通知できる
■時差について
AWSコンソールのCloudWatch画面では、日時は「2021-10-20 18:06:55 UTC」のように表示されている
UTCは「協定世界時」で、日本との時差は9時間ある
上記の場合、日本時間では「2021-10-21 03:06:55」となるので注意
ただしその後、CloudWatch画面の上部「Custom」のメニューから「UTC」か「Local time」かを選択できるようになっていた
(次回アクセス時や他ユーザのログインなど、すべてに恒久的に反映されるかは要検証)
Etcetera.txt の「時差」も参照
■CloudWatch Logs
※ログファイルを転送して一元管理できる
Amazon CloudWatchとは:これからAWS監視を始める人へ
http://cloudtriage.terilogy.com/20150716/
Amazon CloudWatchの得意なこと苦手なこと:これからAWS監視を始める人へ その2
http://cloudtriage.terilogy.com/20150804-03/
Amazon CloudWatch Logsによるログの収集とフィルタとアラーム設定
http://dev.classmethod.jp/cloud/cloudwatch-logs/
CloudWatch Logsをさわってみた
http://qiita.com/mechamogera/items/a01c9d78d6b1842c4ded
CloudWatch LogsでAmazonLinux上のApacheエラーログを監視する
http://dev.classmethod.jp/cloud/cloudwatch-logs-apache/
ログファイルのモニタリング
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/DeveloperGuide/WhatIsCloudWatchLogs.html
ログの保持期間の変更
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/DeveloperGuide/SettingLogRetention.html
Zabbixを使えば柔軟な監視ができるが、ELBやRDSの監視は難しい(エージェントをインストールできないため)
CloudWatchとZabbixの併用がいいかも
yumでインストールした場合とawslogs-agent-setupでインストールした場合で、アクセスキーの設定方法などが異なるみたい(未検証)
どちらでインストールしても良いみたいだが、他の人がインストールしたものの設定を変更する場合を考えて、両方の概要を把握しておくほうが好ましい
# yum install -y awslogs
… インストール
# vi /etc/awslogs/awscli.conf
… 設定変更
[plugins]
cwlogs = cwlogs
[default]
#region = us-east-1
region = ap-northeast-1 … 東京リージョンに変更
aws_access_key_id = XXXXX … キーには CloudWatchLogsFullAccess もしくは必要に応じた権限が必要
aws_secret_access_key = YYYYY
# vi /etc/awslogs/awslogs.conf
… 監視対象を追加する場合
[/var/log/messages] … もとからある設定
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/messages
[/var/log/secure] … 認証に関するログ
datetime_format = %b %d %H:%M:%S
file = /var/log/secure
buffer_duration = 5000
log_stream_name = {instance_id}_secure
initial_position = start_of_file
log_group_name = /var/log/secure
[/var/log/audit/audit.log]
file = /var/log/audit/audit.log
buffer_duration = 5000
log_stream_name = {instance_id}_audit_log
initial_position = start_of_file
log_group_name = /var/log/audit/audit.log
[/var/log/httpd/access_log] … Apacheのアクセスログ
datetime_format = %d/%b/%Y:%H:%M:%S
file = /var/log/httpd/access_log*
buffer_duration = 5000
log_stream_name = {instance_id}_httpd_access_log
initial_position = start_of_file
log_group_name = /var/log/httpd/access_log
[/var/log/httpd/error_log] … Apacheのエラーログ
datetime_format = [%a %b %d %H:%M:%S %Y]
file = /var/log/httpd/error_log*
buffer_duration = 5000
log_stream_name = {instance_id}_httpd_error_log
initial_position = start_of_file
log_group_name = /var/log/httpd/error_log
[/var/log/maillog] … メールに関するログ
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/maillog*
buffer_duration = 5000
log_stream_name = {instance_id}_maillog
initial_position = start_of_file
log_group_name = /var/log/maillog
# systemctl start awslogsd
… 起動
# systemctl enable awslogsd
… awslogsの自動起動を設定
# vi /var/log/awslogs.log
… awslogsのログを確認
Amazon Linux 2 以前の場合、以下で起動できる
# service awslogs start
# chkconfig awslogs on
■サーバのログを確認
EC2はSSHで通常どおり確認できる
もしくはCloud Watch Logs からも確認できる
「CloudWatch」→「ログ」
■ログの長さ制限
32742 byte 以下ではそのまま表示され、32743 byte を閾値に TRUNCATED に置き換わるようなので注意
以下のようなメッセージが
production.ERROR: ShippingMappingDataService:createMappingHeaderData {"url":null,"ip":null,"agant":null,"userId":null,"error":"[object] (Illuminate\\Database\\QueryException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '20341540' for key 'PRIMARY' (SQL: insert into `deliveries` (`arrival_day`, `arrival_time_code`, 以下略
丸ごと以下のようなメッセージに置き換わる
「ログにこういう文字列が含まれていれば警告」のような仕組みに支障をきたすので、長いメッセージは、
「一定文字数ごとに改行して記録する」「ログ出力時に短くして記録する」「本来のログと並べて、短い版のログも記録する」
などの対応が必要そう
[TRUNCATED MESSAGE] 1231496 bytes are truncated.
Amazon Web Services Japan によるスライドでも
「1 Log Event の最大サイズは 32KBです。 →32KBを超えると、ログがトランケートされてしまいます。」
という制限が紹介されている
CloudWatch Logsエージェントを検証してみた | mooapp
https://moomindani.wordpress.com/2014/07/16/cloudwatch-logs-5point-investigation/
AWS Black Belt Techシリーズ AWS CloudTrail & CloudWatch Logs
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-tech-aws-cloudtrail-cloudwatch-logs
■ログの保存期間
デフォルトではログは無制限に保持される
必要に応じて、3ヶ月〜1年程度に設定しておくといい
ログ保存期間は、「CloudWatch → ロググループ」で、各ログの「保持」をクリックすることで変更できる
Amazon CloudWatch Logs とは - Amazon CloudWatch Logs
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html
Amazon CloudWatch Logsの保持期間を簡単に変更する方法 | DevelopersIO
https://dev.classmethod.jp/articles/how-to-easily-change-the-retention-period-of-amazon-cloudwatch-l...
CloudWatch Logs の保持期間を作成時に変更する | DevelopersIO
https://dev.classmethod.jp/articles/create-loggroup-change-retention/
ちなみにCloudWatchのグラフ表示は遡れるのが2週間までだったが、
かなり以前に15ヶ月に延長されている
[CloudWatch] メトリックの保持期間が14日→15ヶ月に延長されて、グラフ機能も強化されました | DevelopersIO
https://dev.classmethod.jp/articles/cloudwatch-extended-15months/
■利用料金
料金 - Amazon CloudWatch | AWS
https://aws.amazon.com/jp/cloudwatch/pricing/
【AWS】CloudWatchの料金体系を調べてみた - echo("備忘録");
https://makky12.hatenablog.com/entry/2022/11/21/120500
CloudWatch Logsの利用料金は以下のようになっている
また5GBの無料利用枠がある
収集 (データの取り込み) ... 0.76USD/GB
保存 (アーカイブ) ... 0.033USD/GB
分析 (Logs Insights のクエリ) ... スキャンしたデータ 1 GB あたり 0.0076USD
必要なログが1ヶ月あたり5GB以内なら、収集に関する課金は気にする必要が無さそう
保存に関しても、6ヶ月分保存するなら30GBほどのデータになるが、1ドル(0.033USD/GB × 30GB)程度で収まりそう
無料利用枠があるので、一般的なサイトなら無料もしくは微々たる金額で利用できそう
■Zabbix エージェント
AWS EC2インスタンスをZabbixエージェントで監視する為の準備作業
http://www.checksite.jp/ec2-zabbix-agent/
通常の手順でEC2にインストールできるが、ListenIPを設定するとエージェントを起動できないみたい
何も設定せずに動作させる
$ vi /etc/zabbix/zabbix_agentd.conf
Server=203.0.113.1 … zabbix.refirio.net のIPアドレス
Hostname=zabbix.refifio.net
監視サーバからは、対象としてElasticIPのアドレスを指定する
■Zabbix サーバ
※Amazon Linuxにはyumでインストールできないみたい。CentOS6かCentOS7を使うのが無難みたい
■参考
AWS上でCentOS 7にZabbix 3.2を構築してみた | Developers.IO
http://dev.classmethod.jp/cloud/aws/aws-centos7-zabbix3_2-setup/
これを参考に、Amazon Linux にインストールを試みる
■事前調査
2017/08/10時点での最新バージョンは3.2.7。
http://repo.zabbix.com/zabbix/
http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/
http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-server-pgsql-3.2.7-1.el7.x86_64.rpm
だが、zabbix-release-3.2-1.el7.noarch.rpm は 3.2-1 が最新でいいみたい
http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm
■インストール
# rpm -ivh
http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm
# yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-web-japanese zabbix-get
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28(GNUTLS_1_4)(64bit)
エラー: パッケージ: zabbix-server-mysql-3.2.7-1.el7.x86_64 (zabbix)
要求: libnetsnmp.so.31()(64bit)
エラー: php56-common conflicts with php-common-5.3.29-1.8.amzn1.x86_64
エラー: パッケージ: zabbix-server-mysql-3.2.7-1.el7.x86_64 (zabbix)
要求: systemd
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28()(64bit)
エラー: httpd24-tools conflicts with httpd-tools-2.2.32-1.9.amzn1.x86_64
エラー: php56 conflicts with php-5.3.29-1.8.amzn1.x86_64
エラー: php56-cli conflicts with php-cli-5.3.29-1.8.amzn1.x86_64
エラー: httpd24 conflicts with httpd-2.2.32-1.9.amzn1.x86_64
問題を回避するために --skip-broken を用いることができます。
これらを試行できます: rpm -Va --nofiles --nodigest
# httpd -v
Server version: Apache/2.2.32 (Unix)
Server built: Jun 21 2017 19:11:57
# php -v
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
HTTPDとPHPのバージョン問題?
Apache2.4とPHP5.6をインストール
# yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-web-japanese zabbix-get
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28(GNUTLS_1_4)(64bit)
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28()(64bit)
エラー: パッケージ: zabbix-server-mysql-3.2.7-1.el7.x86_64 (zabbix)
要求: libnetsnmp.so.31()(64bit)
エラー: パッケージ: zabbix-server-mysql-3.2.7-1.el7.x86_64 (zabbix)
要求: systemd
問題を回避するために --skip-broken を用いることができます。
これらを試行できます: rpm -Va --nofiles --nodigest
# yum install --enablerepo=epel iksemel
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28(GNUTLS_1_4)(64bit)
エラー: パッケージ: iksemel-1.4-2.el7.centos.x86_64 (zabbix-non-supported)
要求: libgnutls.so.28()(64bit)
問題を回避するために --skip-broken を用いることができます。
これらを試行できます: rpm -Va --nofiles --nodigest
Zabbixインストールエラー。libgnutls.so.13()(64bit) とlibgnutls.so.13(GNUTLS_1_3)(64bit) の不足について。 | 日本Zabbixユーザー会
http://www.zabbix.jp/node/1840
「ZABBIX-JPのyumリポジトリでは、RHELとCentOS
で利用できるrpmしか公開していませんので、ZABBIX-JPのyumリポ
ジトリを利用してのインストールは、各種ライブラリのバージョン
や依存関係が異なりますのでインストールできません。
昔のAmazon Linuxのバージョンであれば、RHEL 6用を利用できたの
ですが、現時点では上記の通り、各種パッケージのバージョンが新
しくなってしまっていたり、依存関係が異なるのです。」
インストールできないみたい
■Cloud9
ブラウザのみでコードを記述、実行、デバッグできるクラウドベースの統合開発環境
AWS Cloud9(Cloud IDE でコードを記述、実行、デバッグ)| AWS
https://aws.amazon.com/jp/cloud9/
AWSのCloud9での開発とは?利点10個や利用するステップも紹介 | ITエンジニアの派遣なら夢テクノロジー
https://www.yume-tec.co.jp/column/awsengineer/4595
AWS Cloud9の開発環境を作ってみる | ファブリカコミュニケーションズ
https://www.fabrica-com.co.jp/techblog/technology/4807/
■作成
Cloud9 → Create environment
「Name environment」の画面になるので、以下を入力
Name: Test
Description: (空欄のまま)
「Next step」をクリック
「Configure settings」の画面になるので、以下を入力
Environment type: Create a new EC2 instance for environment (direct access)
Instance type: t2.micro (1 GiB RAM + 1 vCPU)
Platform: Amazon Linux 2 (recommended)
Cost-saving setting: After 30 minutes (default)
IAM role: AWSServiceRoleForAWSCloud9
すべてデフォルト設定のままとした
必要に応じて「Network settings (advanced)」でVPCとSubnetを選択する(接続先に合わせて設定するといい)
「Next step」をクリック
確認画面が表示されるので「Create environment」をクリック
1〜2分程度で、Cloud9の画面が表示された
また、EC2のインスタンス一覧で「aws-cloud9-Test-098b318d3e39493ea674ec9c114bcc92」というインスタンスが起動されていた
Cloud9 → Your environments → (対象の環境を選択) → Delete
で、作成した環境を削除できる
起動されたインスタンスも削除される
■調査中メモ
環境作成時の「Network settings」でVPCを指定しないと、希望するEC2を操作できないなどはあるかも
Cloud9画面下部にbashコンソールが表示されている。ここでSSH操作ができそう
コードの貼り付けは、ブラウザ側での設定が必要かも
Apacheは動いているようだが、セキュリティグループの都合か外部から80番ポートでアクセスできない
キーペアを指定していないからか、外部からSSHでの直接アクセスはできない(でもキーペアを指定する項目自体無かったような)
以下によると、手動でキーを作成して配置すればアクセスできるみたい
とは言え余計な穴を開けずに、原則AWSコンソールから操作すべきか
AWS Cloud9作成時のEC2へssh接続してみる - Qiita
https://qiita.com/daisuke8000/items/9e1343e0d92541f89fa9
デフォルトでは30分使わないと停止するみたい?
手動で都度停止したりも大丈夫か。も含めて改めて確認したい
AWS Cloud9のインスタンスの自動停止機能?を確認した件 - memorandums
https://memorandums.hatenablog.com/entry/2020/07/09/085910
■AWS CloudShell
AWS対応のシェルプロンプトの作業を簡単かつセキュアにし、できるだけ手間を少なくする
AWS CloudShell - AWS リソースへのコマンドラインアクセス | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/aws-cloudshell-command-line-access-to-aws-resources/
待望の新サービス AWS CloudShell がリリースされました! #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/new-service-aws-cloudshell-reinvent-2020/
東京リージョンでAWS CloudShellを使ってみた | DevelopersIO
https://dev.classmethod.jp/articles/lim_aws_cloudshell/
AWSコンソールから、ブラウザで、AWS CLIを実行できる
AWS CLIを使ってちょっとした作業をするとき、実行環境を用意しなくてもいい
AWS CloudShell を早速使ってみました - Qiita
https://qiita.com/hirosys-biz/items/ede1bce935e7d922c979
CloudShell経由でEC2に接続できなくも無いようだが、推奨されない方法かもしれない
Cloud ShellとAWS Cloud9を比較してみた - Qiita
https://qiita.com/tora470/items/1fac2ddd03c6a4a86e68
Cloud9でも大体同じことができるみたい
■AWS CLI(Amazon Linux で使用する場合)
AWSのサービスをコマンドラインで操作できる
Amazon Linux にはプリインストールされている
$ aws --version
… CLIのバージョンを確認
aws-cli/1.10.56 Python/2.7.10 Linux/4.4.16-27.56.amzn1.x86_64 botocore/1.4.46
$ aws ec2 describe-security-groups
… CLIの設定を行っていないので実行できない
You must specify a region. You can also configure your region by running "aws configure".
$ aws configure
… CLIの設定を行う
AWS Access Key ID [None]: XXXXX
… アクセスキーを入力
AWS Secret Access Key [None]: YYYYY
… シークレットアクセスキーを入力
Default region name [None]: ap-northeast-1
… デフォルトで使用するリージョンを入力
Default output format [None]: text
… 実行結果の出力形式を入力(「text」「json」「table」のいずれか)
$ aws ec2 describe-security-groups
… EC2を一覧表示(CLIの設定を行ったので実行できる)
SECURITYGROUPS default VPC security group sg-30240955 default 123456789012 vpc-f11d9094
IPPERMISSIONS -1
USERIDGROUPPAIRS sg-30240955 123456789012
IPPERMISSIONSEGRESS -1
IPRANGES 0.0.0.0/0
〜略〜
SECURITYGROUPS for ssh. sg-5e270a3b ssh 123456789012 vpc-f11d9094
IPPERMISSIONS 10022 tcp 10022
IPRANGES 203.0.113.9/32
IPPERMISSIONS 22 tcp 22
IPRANGES 172.31.0.0/16
IPPERMISSIONSEGRESS -1
IPRANGES 0.0.0.0/0
$ ll ~/.aws/
… 設定ファイルを確認
合計 8
-rw------- 1 ec2-user ec2-user 48 8月 25 18:19 config
… リージョンと出力形式の設定が保存されている
-rw------- 1 ec2-user ec2-user 116 8月 25 18:19 credentials
… アクセスキーの設定が保存されている
■オプション指定例(条件指定&絞り込み)
$ aws ec2 describe-instances
… EC2を一覧表示
$ aws ec2 describe-instances --filters "Name=private-ip-address,Values=10.0.0.150"
… filtersで検索条件を指定
$ aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId'
… queryで出力結果を絞り込み(インスタンスIDを表示)
$ aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,PrivateIpAddress]'
… queryで出力結果を絞り込み(インスタンスIDとIPアドレスを表示)
■S3を操作
$ aws s3 ls refirio/images/
… S3の特定フォルダの内容を一覧表示
2015-10-30 20:20:01 0
2017-11-16 13:21:40 5115 photo01.jpg
2015-10-30 20:21:40 8853 photo02.jpg
2017-11-16 14:12:57 12008 photo03.jpg
$ aws s3 cp s3://refirio/test/ /home/ec2-user/s3/test/ --recursive
… S3の特定フォルダの内容をダウンロード
S3バケットにアップロードしたファイルを一括ダウンロードする方法 - *いしのなかにいる*
https://teleporter.hateblo.jp/entry/bulk-download-from-s3
$ aws s3 sync /home/ec2-user/sync_test s3://refirio/sync_test/ --delete
… S3の特定フォルダの内容と同期
「aws s3 sync」を実行すると、「/home/ec2-user/sync_test」の内容が正しいとして「s3://refirio/sync_test/」の内容が同期される
つまりEC2側にファイルを作成して「aws s3 sync」を実行するとS3側にファイルが作成され、
S3側にファイルを作成して「aws s3 sync」を実行するとS3側のファイルは削除される
MySQLを毎日バックアップして、S3に同期するシェルスクリプト - Qiita
https://qiita.com/taiko19xx/items/215b9943c8aa0d8edcf6
「aws s3 sync」でバックアップの仕組みを作る場合、うっかりファイルを削除するとそれも同期されてしまう
S3側でバージョン管理を有効にしておく必要はありそうだが、永久に残らないようにライフサイクルの設定が必要
今さらだけどS3のバージョニングを試してみた。 - Qiita
https://qiita.com/kooohei/items/8775b380632e8b7940a3
今さらだけどS3のライフサイクルを試してみた。 - Qiita
https://qiita.com/kooohei/items/645deeb08cd1a6f4948a#_reference-f9f014ed309e5ecc614a
以下のようにバケットを指定することで、バケット間で直接コピーもできるみたい(未検証)
cpコマンドでも同様にできるか、なども含めて要検証
$ aws s3 sync s3://DOC-EXAMPLE-BUCKET-SOURCE s3://DOC-EXAMPLE-BUCKET-TARGET
Amazon S3 バケット間でオブジェクトをコピーする
https://aws.amazon.com/jp/premiumsupport/knowledge-center/move-objects-s3-bucket/
■AWS CLI(WSL2 + Ubuntu 20.04 で使用する場合)
WSL2 + Ubuntu 20.04 環境に AWS CLI をインストールして使用する
Windows10+WSL2環境のLinuxディストリビューションにAWS CLIをインストールしてみた | DevelopersIO
https://dev.classmethod.jp/articles/awscli_on_wsl2/
AWS CLI バージョン 2 のインストール、更新、アンインストール - AWS Command Line Interface
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2.html
依存パッケージをインストールしておく
$ sudo apt install unzip
AWS CLI をインストール
UbuntuなのでLinux用をインストールすればいい
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version
$ aws --version
aws-cli/2.2.44 Python/3.8.8 Linux/5.10.16.3-microsoft-standard-WSL2 exe/x86_64.ubuntu.20 prompt/off
設定ファイルを作成する
アクセスキーはあらかじめ発行したものを設定する
$ mkdir .aws
$ vi .aws/credentials
[default]
aws_access_key_id=XXXXX
aws_secret_access_key=YYYYY
$ vi .aws/config
[default]
region=ap-northeast-1
output=json
以上で設定完了
以下などを実行して、意図した結果をjsonで得られることを確認する
$ aws ec2 describe-instances
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
以下略
■AWS SDK(バージョン3)
AWS SDK for PHP | AWS
https://aws.amazon.com/jp/sdk-for-php/
「AWS SDK for PHP v3」を使ったS3へのアップロード・ダウンロード処理 | 株式会社ビヨンド
http://beyondjapan.com/blog/2017/04/%E3%80%8Caws-sdk-for-php-v3%E3%80%8D%E3%82%92%E4%BD%BF%E3%81%A3%...
2017/11/16時点で、この方法ならPHPからS3にアップロードできた。
■インストール
composer require aws/aws-sdk-php
■証明書エラー
phpからAWS S3にアクセスしようとしたときに「SSL certificate problem: unable to get local issuer certificate」となった場合の対応
https://www.scriptlife.jp/contents/programming/2017/09/18/php-curl-certificate-failed/
証明書エラーになったが、以下のように設定すれば解消した
C:\xampp\php\php.ini
curl.cainfo = "C:\Program Files\Git\etc\pki\ca-trust\extracted\openssl\ca-bundle.trust.crt"
■稼働中のEC2を取得する例
<?php
require_once 'vendor/autoload.php';
use Aws\Ec2\Ec2Client;
use Aws\Ec2\Exception\Ec2Exception;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new Ec2Client([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// インスタンスの情報を取得
$result = $client->describeInstances([
'Filters' => [
[
'Name' => 'instance-state-name',
'Values' => ['running'],
],
],
]);
// 結果を出力
foreach ($result['Reservations'] as $reservation) {
$instance = $reservation['Instances'][0];
echo 'InstanceId ... ' . $instance['InstanceId'] . '<br />';
echo 'PrivateIpAddress ... ' . $instance['PrivateIpAddress'] . '<br />';
echo '<hr />';
}
} catch (Ec2Exception $e) {
exit('Ec2Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3のディレクトリを一覧する例
<?php
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new S3Client([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// バケットとディレクトリを指定して取得
$result = $client->listObjects([
'Bucket' => 'ZZZZZ',
'Prefix' => 'blog/',
'Delimiter' => '/',
]);
// ディレクトリを表示
foreach ($result['CommonPrefixes'] as $prefix) {
echo $prefix['Prefix'] . '<br>';
}
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3のファイルを一覧する例
<?php
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new S3Client([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// バケットとディレクトリを指定して取得
$result = $client->listObjects([
'Bucket' => 'ZZZZZ',
'Prefix' => 'blog/photo/',
'Delimiter' => '/',
]);
// ファイルを表示
foreach ($result['Contents'] as $content) {
echo $content['Key'] . '(' . $content['LastModified'] . ')' . '<br>';
}
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3のファイルを取得する例
<?php
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new S3Client([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// バケットとファイルを指定して取得
$result = $client->getObject([
'Bucket' => 'ZZZZZ',
'Key' => 'images/photo01.jpg',
]);
// ファイルを表示
header('Content-Type: image/jpeg');
echo $result['Body'];
exit;
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3にファイルを保存する例
<?php
require_once 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new S3Client([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// バケットにファイルを保存
$result = $client->putObject(array(
'Bucket' => 'ZZZZZ',
'Key' => 'images/photo01.jpg',
'Body' => file_get_contents('img/image.jpg'),
));
exit;
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3に認証なしでアクセス
※未検証
バケットの公開設定によっては、認証情報なしでアクセスできるみたい
AWS SDK (PHP) での認証なしの S3 へのアップロード - Qiita
https://qiita.com/mangano-ito/items/d368e3e46048e2139936
■CloudWatchLogsのデータを取得する例
<?php
/*
FilterLogEvents - Amazon CloudWatch Logs
https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_FilterLogEvents.html
「The start of the time range, expressed as the number of milliseconds after Jan 1, 1970 00:00:00 UTC. 」
↑時間の指定はUNIXタイムスタンプのミリ秒で行う
PHPを使って、CloudWatch Logsからデータを取得します。
https://gist.github.com/yusukemurayama/0d0a81cad039cc68964b
「filterPattern」の指定例がなかなか見つけられないが、上記では使われている
<?php
require_once '../libs/vendor/autoload.php';
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Aws\CloudWatchLogs\Exception\CloudWatchLogsException;
try {
$client = new CloudWatchLogsClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
$result = $client->filterLogEvents([
'logGroupName' => '/var/log/nginx/access.log',
'startTime' => (time() - 60 * 60) * 1000, // 開始時間(UNIXタイムスタンプのミリ秒)
'endTime' => time() * 1000, // 終了時間(UNIXタイムスタンプのミリ秒)
'filterPattern' => '[httprequest != "*.ico*" && httprequest != "*.xml*"]',
]);
foreach ($result->get('events') as $event) {
echo $event['message'];
echo '<hr>';
}
} catch (CloudWatchLogsException $e) {
exit('CloudWatchLogsException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■認証情報の外部ファイル化
あらかじめ credentials.ini を作成して認証情報を記載しておくと、
[default]
aws_access_key_id=XXXXX
aws_secret_access_key=YYYYY
CredentialProviderを使用して、認証情報を読み込むことができる
<?php
require_once 'vendor/autoload.php';
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Aws\CloudWatchLogs\Exception\CloudWatchLogsException;
use Aws\Credentials\CredentialProvider;
try {
$ini = './credentials.ini';
$iniProvider = CredentialProvider::ini('default', $ini);
$iniProvider = CredentialProvider::memoize($iniProvider);
$client = new CloudWatchLogsClient([
'credentials' => $iniProvider,
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
また認証情報を ~/.aws/credential で管理していて「[default]」の定義を使用する場合、以下のように簡略化できる(未検証)
<?php
require_once 'vendor/autoload.php';
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Aws\CloudWatchLogs\Exception\CloudWatchLogsException;
use Aws\Credentials\CredentialProvider;
try {
$client = new CloudWatchLogsClient([
'credentials' => CredentialProvider::defaultProvider(),
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
[PHP]aws-sdkでS3にファイルをアップロードする | akamist blog
https://akamist.com/blog/archives/4426
■AWS SDK(バージョン2)
AWSのサービスをプログラムで操作できる
AWS SDK for PHP
https://aws.amazon.com/jp/sdk-for-php/
AWS SDK for PHP v2 で S3 にファイルをアップロード
http://tetsuwo.tumblr.com/post/102677580377/aws-s3-image-upload
2015/12/09時点で、この方法ならPHPからS3にアップロードできた。
■バージョン2の廃止
バージョン2は2019年6月24日に廃止されるので注意
できるだけ早くバージョン3に移行する
【超重要】対応しないと使えなくなるかも?!今、全S3ユーザがチェックすべき署名バージョン2の廃止について | DevelopersIO
https://dev.classmethod.jp/cloud/aws/s3-sigv2-abolition/
廃止予定のS3署名バージョン2によるアクセスを調査する方法まとめ | DevelopersIO
https://dev.classmethod.jp/cloud/aws/how-to-check-s3-signature-ver2/
入っているAWS SDK for PHPのバージョンを雑に調べる - Qiita
https://qiita.com/inouet/items/83ae7bdedd5d7810232f
…だったが、2019年6月15日になって延期された
2020年6月24日以降に作成された新しいバケットは対応が必要となるが、既存のバケットは引き続きそのまま使えるとのこと
Amazon S3 アップデート - SigV2 の廃止時期、延期と変更 | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/amazon-s3-update-sigv2-deprecation-period-extended-modified/
S3の署名バージョン2(SigV2)の廃止スケジュールが延期、2020年6月以降も既存のS3バケットはSigV2が継続サポートとなりました!! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/s3-sigv2-deprecation-period-extended-20200624/
■稼働中のEC2を取得する例
<?php
require_once 'Aws/vendor/autoload.php';
use Aws\Common\Aws;
try {
//アクセスキーとシークレットアクセスキーとリージョンを指定して接続
$aws = Aws::factory(array(
'key' => 'XXXXX',
'secret' => 'YYYYY',
'region' => 'ap-northeast-1',
));
$client = $aws->get('ec2');
//インスタンスの情報を取得
$result = $client->describeInstances(array(
'Filters' => array(
array(
'Name' => 'instance-state-name',
'Values' => array('running'),
),
)
));
//結果を出力
foreach ($result['Reservations'] as $reservation) {
$instance = $reservation['Instances'][0];
echo 'InstanceId ... ' . $instance['InstanceId'] . '<br />';
echo 'PrivateIpAddress ... ' . $instance['PrivateIpAddress'] . '<br />';
echo '<hr />';
}
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■S3のファイルを取得する例
<?php
require_once 'Aws/vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
try {
//アクセスキーとシークレットアクセスキーを指定して接続
$client = S3Client::factory(array(
'key' => 'XXXXX',
'secret' => 'YYYYY',
));
//バケットとファイルを指定して取得
$result = $client->getObject(array(
'Bucket' => 'ZZZZZ',
'Key' => 'images/sample.jpg',
));
//ファイルを表示
header('Content-Type: image/jpeg');
echo $result['Body'];
exit;
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■CloudFormation
ネットワークをテンプレートで管理できる
同一ネットワークの再現が容易になり、gitなどで変更履歴を管理することもできるようになる
■ネットワークの構築(aws_cloudformation/test/vpc_only.template にテンプレートの例がある)
CloudFormation → スタックの作成
ステップ1 テンプレートの指定
テンプレートの準備
テンプレートの準備完了
テンプレートの選択
テンプレートファイルのアップロード → テンプレートファイルを選択
ステップ2 スタックの詳細の指定
スタックの名前
SampleVPC
ステップ3 スタックオプションの設定
削除保護
有効(必要なら)
※その他必要に応じて設定
ステップ4 確認
内容を確認して「スタックの作成」をクリック
エラーがなければ1分程度で構築が完了し、Statusが「CREATE_IN_PROGRESS」から「CREATE_COMPLETE」に変わる
その後VPCなどを確認すると反映されていることを確認できる
■ネットワークの変更(aws_cloudformation/test/vpc_network.template にテンプレートの例がある)
CloudFormation → スタックを選択 → アクション → スタックの更新
編集したテンプレートを選択すると、その変更分が反映される
エラーがなければ1分程度で構築が完了し、Statusが「UPDATE_IN_PROGRESS」から「UPDATE_COMPLETE」に変わる
その後VPCなどを確認すると反映されていることを確認できる
■ネットワークの削除
CloudFormation → スタックを選択 → アクション → スタックの削除
そのスタックで作成されたリソースはすべて削除されるので注意
例えばスタックにEIPが含まれていた場合、スタックを削除して作りなおすとIPアドレスが変わってしまう
SSHの接続先やメール送信制限解除申請など、諸々の作業もやり直す必要があるので注意
スタックの削除時「スタックを削除すると、すべてのスタックリソースが削除されます。」と表示されているが、
スタックの削除中にエラーになって止まった?
「関連する○○がある」という旨のエラーでどうしても削除できない場合、手動でVPCを削除すると大丈夫のことがある
■インスタンスの起動(aws_cloudformation/instance.template)
vpc_network.template でVPCを構築
その後 instance.template でインスタンスを作成
SSHで接続
インスタンスに手動でEIPを設定
22番ポートを開放したセキュリティグループを作成して割り当て
自動作成されたルートテーブルを調整
送信先 : 0.0.0.0/0
ターゲット : 自動作成されたインターネットゲートウェイ
SSHで接続を確認
HTTPで接続
セキュリティグループを調整して80番ポートを開放
SSHで接続し、rootのパスワードを設定&Apacheをインストール
HTTPで接続を確認
※EIPやセキュリティグループの調整などもテンプレートで管理できる…はず。要勉強
※UserDataでApache自動インストール(aws_cloudformation/instance_httpd.template)は何故か反応せず…。要勉強
■変更の検出
CloudFormationで構築した後に手動で行った変更を、検出できるようになったとのこと
ただし解説を読むかぎり、まだ検出できない内容もあるみたいなので注意
またサブネットを削除すると、そのサブネットに属するEC2なども削除されるかも。気軽に変更を行うのはリスクがありそうなので注意
AWS CloudFormationで手動で行った変更が検出可能になりました!!! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/cloudformation-support-drift-detection/
CloudFormation → スタックを選択 → アクション → ドリフトの検出
手動で変更した内容を検出できる
コードになおすとどうなるのかも表示してくれるので、それをもとにテンプレートを調整できる
■注意
コンソールでできるすべての操作が、CloudFormationに対応しているとは限らないので注意
また、更新をすべてCloudFormationで管理すると手間が増える可能性があるので注意
「初期構築にCloudFormationを使用し、以降の更新はコンソールから手動で行う」のような手法も検討するといい
【AWS】CloudFormationの作成ノウハウをまとめた社内向け資料を公開してみる | DevelopersIO
https://dev.classmethod.jp/cloud/aws/cloudformation-knowhow/
【CloudFormation入門1】5分と6行で始めるAWS CloudFormationテンプレートによるインフラ構築 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/cloudformation-beginner01/
■基本的なネットワークの作成
aws_cloudformation/create_vpc.yaml
で基本的なネットワークを作成できる
■メモ
【AWS初学者向け・図解】CloudFormationの組み込み関数を現役エンジニアがわかりやすく解説? | エンジニア女子の生態ログ
https://o2mamiblog.com/aws-cloudformation-intrinsic-function-beginner-1/
■複数台構成でEC2インスタンスを追加する手順の例
前提
web1サーバのAMIは作成済みで、これをもとにweb2サーバを作るものとする
VPCは作成済みで、サブネットとしてweb1とweb2が作成されているものとする
確認
操作対象のリージョンを確認する
「EC2」→「ロードバランサー」→ 作成済みのロードバランサーを選択 →「インスタンス」
で、各サーバが正常に動作していることを確認する
インスタンスの作成
「EC2」→「インスタンス」→「インスタンスの作成」から作成する
AMI の選択
「マイ AMI」から、あらかじめ作成しておいたAMIを選択する
インスタンスタイプの選択
原則として、すでに存在する他のEC2インスタンスと同じインスタンスタイプにする
インスタンスの詳細の設定
ネットワークを、あらかじめ作成したVPCに設定
サブネットを設定(1台目がweb1に追加されているなら2台目はweb2に追加する。3台以上追加する場合、web1とweb2の交互に追加していく)
誤った削除から保護する(必要なら)
CloudWatch 詳細モニタリングを有効化(必要なら)
ネットワークインターフェイスは自動で追加されているので、変更せずにそのまま
ストレージの追加
必要に応じてサイズを調整する。原則として、すでに存在する他のEC2インスタンスと同じサイズにする
インスタンスのタグ付け
「web2」など
セキュリティグループの設定
既存のセキュリティグループから選択。default, ssh, web など
作成
既存のキーペアを選択した状態で、インスタンスを作成
固定IPアドレスの割り当て(必要なら)
新規にIPアドレスを取得する場合
「EC2」→「Elastic IP」→「新しいアドレスの割り当て」→「関連付ける」→「閉じる」でIPアドレスを取得
既存のIPアドレスを再利用する場合
再利用したいアドレスを選択して「アクション」→「アドレスの関連付けの解除」を選択
一覧から、作成したIPアドレスを選択 →「アクション」→「アドレスの関連付け」を選択
作成したインスタンスを入力(選択)し、「関連付ける」ボタンを押す
※固定IPを無駄遣いしないために、もっとサーバが増えたら固定IPなしで運用する方がいいかも
その場合、SSH直接接続のために固定IPが必要なので、踏み台用のサーバが必要
追加設定(稼働のために最低限必要な設定)
作成したEC2にSSHでログインする。IPアドレス以外はWeb1サーバと同じ情報で認証できる
AMI作成時に初期化されている項目(言語設定など)や、複製元サーバの情報になっている項目(hostnameなど)を調整する
日本語を使えるようにする(Basis.txt 参照)
sudo vi /etc/sysconfig/i18n
hostnameを調整(Basis.txt 参照)
sudo hostname web2.refirio.net
sudo vi /etc/hosts
sudo vi /etc/sysconfig/network
Apacheの設定でサーバ名を調整(Web.txt 参照)
sudo vi /etc/httpd/conf/httpd.conf
Zabbixの設定でサーバ名を調整(Tool.txt 参照)
sudo vi /etc/zabbix/zabbix_agentd.conf
スワップ領域の割り当て
メモリサイズの2倍を、スワップ領域に割り当てる(必要に応じて作業。基本的に他のインスタンスとサイズを合わせる)
yumで自動アップデートさせる場合、一部のアップデートを再開する(必要に応じて作業。/etc/yum.conf で除外設定をしている場合)
sudo vi /etc/yum.conf
yumのアップデートをする(必要に応じて作業)
sudo yum -y update
yumで自動アップデートさせる場合、一部のアップデートを停止する(必要に応じて作業。/etc/yum.conf で除外設定をしていた場合)
sudo vi /etc/yum.conf
設定したEC2を、コンソール画面から一旦再起動する(再起動のテストと設定の反映)
Route53設定(メールを送信するサーバの場合)
web2.refirio.jp でサーバにアクセスできるように、「Hosted zones → refirio.jp」でAレコードを登録する
SPFレコードとTXTレコードを登録する
コンテンツの配置
FTPアップロードだとすべてのサーバで同じ内容を維持するのが難しいため、デプロイでの配置を推奨
動作確認1
ドメイン経由でアクセスした場合の動作を単体で確認(正規のアクセスではないので、SSLの証明書は不正となるので注意。http経由で確認。)
C:/windows/System32/drivers/etc/hosts
(EC2のIPアドレス) refirio.jp
ロードバランサーに追加
「EC2」→「ロードバランサー」→ 作成済みのロードバランサーを選択 →「インスタンス」
→「インスタンスの編集」→ 作成したインスタンスを選択(削除したサーバがあれば監視対象から外す) → 「保存」
動作確認2
ブラウザからロードバランサー経由でアクセス(通常の手順)し、動作確認
Cron(必要なら)
実行の有無やタイミングなどを調整する
(バッチサーバでのみ実行すべきCronや、サーバによって実行タイミングをずらすべきものがあれば)
CloudWatch(必要なら)
削除したサーバがあれば監視対象から外す
追加したサーバを監視対象に加える
「refirio.net web2 CPU Utilization: CPUUtilization >= 80 for 5 minute」など
Zabbix(必要なら)
削除したサーバがあれば監視対象から外す
追加したサーバを監視対象に加える
■Auto Scaling
■オートスケーリングの作成
EC2 → AUTO SCALING → 起動設定 → Auto Scaling グループの作成 → 起動設定の作成
1. AMI の選択
Amazon Linux AMI を選択
2. インスタンスタイプの選択
t2.micro を選択
3. 詳細設定
名前: Sample
高度な設定 ユーザーデータ: 起動時に実行したい処理を指定できる
高度な設定 IPアドレスタイプ: 「パブリック IP アドレスを各インスタンスに割り当てます。」にするといい?
4. ストレージの追加
特に変更せず
5. セキュリティグループの設定
必要に応じて、あらかじめ設定しておいたセキュリティグループを選択
6. 確認
内容を確認して、問題なければ「起動設定の作成」
ダイアログが表示されるので、キーペアを作成or選択して「起動設定の作成」
1. Auto Scaling グループの詳細設定
グループ名: Sample Group
グループサイズ: 1
ネットワーク: VPCを選択or作成
サブネット: サブネットを選択or作成。マルチAZにしたい場合は複数AZを選択する?
高度な詳細 ロードバランシング: ELBを使う場合、チェックを入れてロードバランサーを選択する
2. スケーリングポリシーの設定
少し試す程度なら「このグループを初期のサイズに維持する」でいいが、この設定だとアクセス数が増えてもインスタンス数は増えない
実際はここでスケーリングの設定を行う
3. 通知の設定
少し試す程度なら設定不要だが、実際はここで通知の設定を行う?
4. タグを設定
必要に応じて設定する
5. 確認
内容を確認して、問題なければ「Auto Scaling グループの作成」
EC2 → AUTO SCALING → Auto Scaling グループ
でグループの状態を確認できる
EC2 → インスタンス
などでも、インスタンスが起動されていることを確認できる
■オートスケーリングの編集
ユーザーデータなどを編集したい場合、「起動設定」から設定をコピーして新たに起動設定を作成する
その後「Auto Scaling グループ」からグループを編集し、使用する起動設定を切り替える
起動設定を切り替えたからといって、以前の起動設定で作成されたインスタンスが削除されたりはしないみたい
新しい起動設定を適用させたい場合、以前作成されたインスタンスを終了させれば自動的に新しいインスタンスが作成される
ユーザーデータを直接編集したり…はできないみたい
■オートスケーリングの解除
「Auto Scaling グループ」でグループを削除、さらに「起動設定」で設定を削除
関連するインスタンスも自動で削除されるみたい
ロードバランサーなど他のサービスも使っている場合、それらも削除する
今からでも遅くない、AWS Auto Scaling入門
http://toach.click/hello-aws-auto-scaling/
スケールアウトを自動化する
http://www.atmarkit.co.jp/ait/articles/1407/15/news007.html
【AWS】AutoScalingを使う際の注意点についてまとめてみました
http://dev.classmethod.jp/cloud/aws/autoscaling_considerations-for-system-configuration/
【AWS】Auto Scalingまとめ
http://qiita.com/iron-breaker/items/2b55da35429da7b19e49
1台のサーバですら Auto Scaling でケチる
http://blog.hde.co.jp/entry/2015/02/12/175214
■ユーザーデータについて
例えば以下のように記述しておくと、EC2起動時に /root/test.txt が作成される
#!/bin/bash
touch /root/test.txt
作成されたファイルは以下のとおり。root権限で実行されている
# ll /root/
total 0
-rw-r--r-- 1 root root 0 Sep 5 05:16 test.txt
例えば以下のように記述しておくと、EC2起動時に /test.txt が作成される
(rootのホームディレクトリでは無いので注意)
#!/bin/bash
touch test.txt
例えば以下のようにシェルスクリプトを作成しておき、
# vi /root/startup.sh
#!/bin/bash
touch /root/test.txt
# chmod 700 /root/startup.sh
# /root/startup.sh
ユーザーデータで以下のように記述しておくと、EC2起動時に /root/startup.sh が実行される
(シェルスクリプト内でパスを省略すると、やはり / 直下が基準となるので注意)
#!/bin/bash
/root/startup.sh
/root/startup.sh の内容を作りこむことで、
EC2起動時に yum update や git pull などを行うことができる
■要調査メモ
台数が多いと基本的に固定IPを割り振らない?数十代台数百台になると、固定IPの割り振りは非現実的
台数が多いと一台一台を監視していてもあまり意味がない?トータルで監視する定番の方法はある?
ユーザーデータの作りこみが必要
Zabbixへの自動登録、デプロイ
ログの退避も必要。起動時ではなくインスタンス終了時の処理を作る?
CloudWatchLogで転送し続けていればいい?
Zabbix監視対象からの自動除外も必要
サーバ名はデフォルト名のままの方がいい?
インスタンスの異常検知 → 新規インスタンスの起動 → ロードバランサーへの割り当て
という過程があるため、デフォルトの検知設定(オートスケーリング・ロードバランサーとも300秒)だとタイムラグが大きすぎるかも
CloudWatchとの組み合わせで、適切な検知設定を作成する必要がありそう
インスタンスの数やEIPの数など、初期状態では制限があるので必要に応じて緩和申請が必要
RDSやElastiCacheのインスタンス数は増えない?はじめから高機能なインスタンスにしておく必要がある?
RDSのリードレプリカは手動で作成して、アプリケーション側も手動対応が必要?
接続先のサービスにIP制限がある場合、オートスケーリングでないNATサーバを立てる必要がある?
リポジトリの内容が更新された時点で、全サーバにおいて自動でデプロイを実行する必要がある?
クックパッドのデプロイとオートスケール、1日10回デプロイする大規模サイトの裏側(前編)。JAWS DAYS 2014
http://www.publickey1.jp/blog/14/110jaws_day_2014_1.html
クックパッドでは完全自動デプロイでは無いみたい?
マージしたらCIは走るが、その後改めてデプロイを行う?
CLIで稼働中のインスタンス一覧を表示して、そこに現在のバージョンを表示して、ポチポチと手動でデプロイするとか?
クックパッドにおけるサーバ監視と運用の工夫
http://techlife.cookpad.com/entry/2015/04/28/100000
AutoScalingも怖くない、Zabbix自動登録
http://blog.serverworks.co.jp/tech/2014/05/29/zabbix-auto-registration/
オートスケールするインスタンスをzabbix監視対象として自動登録(削除)する
http://qiita.com/kaojiri/items/c8d2061829b96b84d850
PHP 5分でわかる! Zabbix API の使い方(ホスト一覧の取得)
https://blog.apar.jp/zabbix/3055/
以下は後から見つけたので未検証だが、詳細にかかれているので良さそう
AWS Elastic Beanstalkで環境構築自動化
http://qiita.com/supertaihei02/items/b2373890b7e739ded318
以下も後から見つけて未検証だが、実際の運用フローも紹介されているので参考にできそう
AWS再入門2018 Amazon EC2 Auto Scaling編 | Developers.IO
https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-autoscaling/
■Elastic Beanstalk
※最低限の設定で、インフラを自動構築してくれる
結果的にVPC・EC2・RDSなどが作成される
※今新規に構築するなら、ECSやEKSなどコンテナを使うサービスを検討するといい
AWSでおてがる開発シリーズ!AWS Elastic Beanstalkでアプリデプロイ編 | MISO
https://www.tdi.co.jp/miso/aws-elastic-beanstalk
■プログラムの準備
まずはWordPressをzipでデプロイしてみる
あらかじめ以下からWordPressを入手しておく
https://ja.wordpress.org/download/
もしくは自分でプログラムを用意する場合、作成したプログラムをzip圧縮しておく
例えば以下のプログラムを作成した場合、
test/index.php
test/about.php
test/css/common.css
test/js/common.js
「test」フォルダを選択して圧縮すると http:// 〜デプロイ先〜 /test/index.php でアクセスすることになる
公開フォルダ直下に配置したければ、「test」フォルダ内のファイルをすべて選択して圧縮する
圧縮ファイルの名前は案件名で問題ないと思われる
バージョンごとにファイル名を変更したりしなくても、Elastic Beanstalk の画面でバージョンラベルを設定できる
■アプリケーションの作成
Elastic Beanstalk → 新しいアプリケーションの作成(画面右上)
※「今すぐ始める」からだと、設定を省略してすぐにアプリケーションが起動できる
「サンプルのアプリケーションを起動」と紹介されているので、これは基本的にはお試し用かも
「新しいアプリケーションの作成」画面が開くので、以下のように入力する
アプリケーション名はEC2のインスタンス名などに使われるので、案件の内容を直感的に把握できる英数字にしておく
アプリケーション名: EB-WordPress
説明: Elastic Beanstalk のテスト
「作成」をクリック
■環境の作成
はじめは「このアプリケーションの環境は現在存在しません。」と表示されている
「今すぐ作成しましょう。」をクリック
「ウェブサーバー環境」をクリックして「選択」をクリック
「ウェブサーバー環境の作成」画面になる
「環境情報」は変更せず
「基本設定」の「プラットフォーム」を「事前設定済みプラットフォーム」の「PHP」に変更し、
さらに「アプリケーションコード」を「コードのアップロード」にし、WordPress公式から入手した wordpress-5.2.2-ja.zip をアップロードする
自分でプログラムを作成した場合、そのzipファイルをアップロードする
「より多くの設定を行う」をクリック(「環境の作成」をクリックすると、ただちに作成される。はず)
※EIPを使わない設定にはできる?要確認
「EbWordpress-env の設定」画面が開く
それぞれ必要な箇所を設定して「保存」をクリックするとこの画面に戻ってくる
「ソフトウェア」でApacheやPHPに関する一部の設定を行える
「インスタンス」でインスタンプタイプやセキュリティグループを設定できる。デフォルトのセキュリティグループは、HTTP(80)とSSH(22)の全アクセスのみを許可するようになっている
「容量」で単一インスタンスで運用するのか、複数インスタンスで負荷分散するのか設定できる。オートスケーリングを使用する場合もこの画面から設定する
「ロードバランサー」は、複数インスタンスで負荷分散する場合に自動追加される
「セキュリティ」でキーペアを選択できる。SSHでアクセスするバイアは選択しておく
「通知」で重要イベントのメール受信アドレスを設定できる
「ネットワーク」で使用するVPCやサブネットを選択できる
「データベース」でRDSを追加できる
今回RDSのユーザー名とパスワードは以下のように設定した
ユーザー名: webmaster
パスワード: gV0+8k6BM#z7
必要な設定を行ったら「環境の作成」をクリック
画面が遷移して以下が表示された。しばらく待つ
「EbWordpress-env を作成しています
この操作には数分かかります。..」
10分ほどで完了し、「ヘルス OK」となった
ページ上部に
「環境 ID: e-fnegyzsjf9, URL: EbWordpress-env.cxbmzusags.ap-northeast-1.elasticbeanstalk.com」
のように表示されている
これをもとに、以下のURLでWordPressにアクセスできる
http://ebwordpress-env.cxbmzusags.ap-northeast-1.elasticbeanstalk.com/wordpress/
通常の手順でWordPressをセットアップしてみる
「さあ、始めましょう!」をクリック
データベース名: ebdb (自動でこの名前になるらしい)
ユーザー名: webmaster
パスワード: gV0+8k6BM#z7
データベースのホスト名: develop.xxxxx.ap-northeast-1.rds.amazonaws.com (「設定」画面でエンドポイントを確認)
上のように設定して「送信」をクリック
「インストール実行」をクリック
サイトのタイトル: EBテスト
ユーザー名: admin
パスワード: MdMme^4v)n@f(nzrP@ (自動作成されたもの)
メールアドレス: example@example.comm
上のように設定して「WordPressをインストール」をクリック
完了したら管理画面にログインし、投稿やメディアアップロードなどを試す
■SSHでの接続
SSHで接続したければ、22番ポートを開くためのセキュリティグループを設定しておく必要がある
構築時に設定しなかった場合は、あとから手動で設定する
キーペアも必要なので、構築時に選択しなかった場合は手動で紐付ける
設定 → セキュリティ → 変更
「EC2キーペア」が空欄なので、作成済みのキーに変更する
ただし後からキーペアを紐付けると
Changes to option EC2KeyName settings will not take effect immediately. Each of your existing EC2 instances will be replaced and your new settings will take effect then.
という警告が表示された
この設定は即時反映では無いとのこと
存在するEC2は新しいものに置き換えられるとのこと
■プログラムの更新
Elastic Beanstalk のダッシュボードで「アップロードとデプロイ」ボタンを押すと、新たなプログラムをアップロード&デプロイできる
また、
EB-WordPress(アプリケーション名) → アプリケーションバージョン
から過去にデプロイしたプログラムを一覧表示できる
ここから
任意のプログラムを選択 → アプション → デプロイ
とすれば、過去のプログラムに戻したりできる
■環境プロパティの利用
WordPressの設定ファイルの内容、メディアなどは消えてしまうので注意(データベースはRDSなので、投稿内容は残る)
「EC2は使い捨て」の思想で設計する必要がある
アップロードファイルはS3に保存すればいいが、アプリケーションの設定は「環境プロパティ」を使って管理できる
Elastic Beanstalk の画面に設定を切り出し、自由に書き換えることができる
設定 → ソフトウェア → 変更 → 環境プロパティ
で設定でき、例えば API_ENDPOINT という名前の値は、以下のようにすれば取得できる
$endpoint = $_SERVER['API_ENDPOINT'];
通常の $_SERVER の内容に加えて、他にもデフォルトで以下のような値を参照できる
Array
(
[PHP_MEMORY_LIMIT] => 256M
[PHP_MAX_EXECUTION_TIME] => 60
[PHP_DISPLAY_ERRORS] => Off
[PHP_COMPOSER_OPTIONS] =>
[PHP_ALLOW_URL_FOPEN] => On
[PHP_ZLIB_OUTPUT_COMPRESSION] => Off
[PHP_DOCUMENT_ROOT] => /
[PHP_DATE_TIMEZONE] => UTC
環境プロパティの名前は、半角英数字で設定する
設定したものは /etc/php.d/environment.ini 内に以下のような形式で記録される
よって「!」などアンダーバー以外の記号を名前に含めると環境が起動できなくなるので注意
また、値に日本語を使うと文字化けするので、半角英数字のみで設定する
API_ENDPOINT="xxxxx"
aws.api_endpoint="xxxxx"
PHP_MEMORY_LIMIT="256M"
aws.php_memory_limit="256M"
PHP_MAX_EXECUTION_TIME="60"
aws.php_max_execution_time="60"
PHP_DISPLAY_ERRORS="Off"
aws.php_display_errors="Off"
PHP_COMPOSER_OPTIONS=""
aws.php_composer_options=""
PHP_ALLOW_URL_FOPEN="On"
aws.php_allow_url_fopen="On"
PHP_ZLIB_OUTPUT_COMPRESSION="Off"
aws.php_zlib_output_compression="Off"
PHP_DOCUMENT_ROOT="/"
aws.php_document_root="/"
PHP_DATE_TIMEZONE="UTC"
aws.php_date_timezone="UTC"
aws.log_dir="/var/app/support/logs"
環境プロパティとその他のソフトウェアの設定 - AWS Elastic Beanstalk
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environments-cfg-softwaresettings.html
AWS Elastic Beanstalk PHP プラットフォームを使用する - AWS Elastic Beanstalk
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_PHP.container.html
RDSを使用している場合、RDSへの接続情報は以下の環境変数から取得できる
リポジトリ内のプログラムには、直接パスワードなどを書く必要は無さそう
$_SERVER['RDS_HOSTNAME']
$_SERVER['RDS_PORT']
$_SERVER['RDS_DB_NAME']
$_SERVER['RDS_USERNAME']
$_SERVER['RDS_PASSWORD']
PHP アプリケーション環境に Amazon RDS DB インスタンスを追加 - AWS Elastic Beanstalk
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_PHP.rds.html
Elastic Beanstalk の細かな設定は、.ebextensions ファイルから行うもの?
設定ファイル (.ebextensions) による高度な環境のカスタマイズ - AWS Elastic Beanstalk
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ebextensions.html
■プログラムの直接編集
Elastic Beanstalk で作成されるWebサーバは、基本的には通常のEC2と同じ
よって非推奨ではあるが、SSHからプログラムを直接書き換えることはできる(緊急対応や検証のとき用に)
例えばプラットフォームが「PHP」の場合、デフォルトでは /var/www/html が公開ディレクトリなので、この中のファイルを書き換えれば反映される
なお、/var/www/html は /var/app/current/ へのシンボルリンクになっている
■環境の削除
アクション → 環境の終了
確認のために表示される「環境の名前」には、今回は「EbWordpress-env」と入力する
EC2やRDSは削除され、EIPも開放される
■エラー例とその対応
以下のエラーになって止まった
2019-09-18 18:35:59 UTC+0900 INFO Launched environment: EbWordpress-env. However, there were issues during launch. See event log for details.
2019-09-18 18:35:58 UTC+0900 INFO Environment health has transitioned to Pending. Initialization in progress (running for 8 seconds). There are no instances.
2019-09-18 18:35:56 UTC+0900 ERROR Creating security group failed Reason: Resource creation cancelled
2019-09-18 18:35:56 UTC+0900 ERROR Creating EIP failed Reason: The maximum number of addresses has been reached. (Service: AmazonEC2; Status Code: 400; Error Code: AddressLimitExceeded; Request ID: c9a2a2d1-cbda-4477-8523-3659b776944d)
2019-09-18 18:35:56 UTC+0900 ERROR Stack named 'awseb-e-fnegyzsjf9-stack' aborted operation. Current state: 'CREATE_FAILED' Reason: The following resource(s) failed to create: [AWSEBEIP, AWSEBSecurityGroup].
EIPを上限まで使用しているので作成できないとある
不要なEIPを開放し、「アクション → 環境の再構築」を実行
「Elastic Beanstalk は 更新しています の環境です。」と表示された。これで再度しばらく待つと完了できた
■Spring Boot で作成したJavaプログラムのデプロイ
Spring Boot で作成したJARファイルをデプロイする場合、「事前設定済みプラットフォーム」では「Java」を選択する
(「Tomcat」ではないので注意。Spring Bootで作成したJARファイルにはTomcatが含まれているため)
「アプリケーションコード」を「コードのアップロード」にし、demo-0.0.1-SNAPSHOT.jar をアップロードする
(あらかじめ Spring Boot で作成したJARファイル)
「インスタンス」のデフォルトのセキュリティグループは、HTTP(80)とSSH(22)の全アクセスのみを許可するようになっている
EC2インスタンスに外部から直接アクセスする場合、8080番ポートも許可しておく
ロードバランサーを使用する場合、セキュリティグループはいじらずにロードバランサーからのアクセス先ポートを8080番にすればいいかもしれない
(要検証)
デプロイしたプログラムは /var/app/current/application.jar に配置されているみたい?
(要検証)
■参考
以下は参考になるかもしれないが難易度が高いかも
ゼロから始めるJavaでAWS Elastic Beanstalk #1〜 EB CLIを使ったJava Webアプリ環境構築 〜 - Qiita
https://qiita.com/riversun/items/9d53238fef611ce7d466
以下は古いが以前にメモしていたもの
AWS Elastic Beanstalkで環境構築自動化 - Qiita
https://qiita.com/supertaihei02/items/b2373890b7e739ded318
■DynamoDB
フルマネージドのNoSQL
S3のデータベース版のようなもの
要勉強
NoSQLについて勉強する。
http://qiita.com/t_nakayama0714/items/0ff7644666f0122cfba1
PayPayでのDynamoDB活用事例について - Speaker Deck
https://speakerdeck.com/paypay/paypaydefalsedynamodbhuo-yong-shi-li-nituite
■Lambda
※あらかじめ登録したコードを実行できる
※コードはイベントに応じて呼び出したり、API Gatewayから呼び出したりなどができる
Lambda → 今すぐ始める
設計図の選択
「hello-world」を選択(すぐに見つからなければ、フィルターで絞り込む)
トリガーの設定
何も変更せずに「次へ」をクリック
関数の設定
名前: hello-world
ランタイム: Node.js 6.10(必要に応じて変更する)
Lambda関数のコード: (必要に応じて変更する)
ロール: existing(必要に応じて新規に作成する)
既存のロール: lambda_basic_execution(必要に応じて新規に作成する)
「次へ」をクリック
確認
内容を確認して「関数の作成」をクリック
関数が作成されたら「テスト」をクリックしてテストする
「サンプルイベントテンプレート」は各サービスやイベントから呼び出された際の入力値となるサンプル
「Hello World」を選択し、「key1」の値を「Hello Lambda World!」に変更する
「保存してテスト」をクリック
実行結果として「成功」と「"Hello Lambda World!"」のログが表示されていれば成功
■S3にアップロードされたJpegとPNGのサムネイルを自動作成する例
チュートリアル: Amazon S3 での AWS Lambda の使用
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-s3-example.html
デプロイパッケージの作成
フォルダ名は CreateThumbnail とした
ファイル名は指定通り CreateThumbnail.js とした
ZIP圧縮は CreateThumbnail に対してではなく、CreateThumbnail.js と node_modules に対して行う
Lambda関数の作成(公式の解説はCLIだが、コンソールから作成)
設計図の選択: ブランク関数
トリガーの設定: S3 → 画像をアップロードするバケットを選択し、イベントタイプは「Put」にし、サフィックスはjpgにする
関数の名前: CreateThumbnail
コード エントリ タイプ: .ZIP ファイルをアップロード(CreateThumbnail.zip)
ハンドラ: CreateThumbnail.handler
ロール: 既存のロールを選択
既存のロール: lambda_basic_execution
詳細設定 メモリ(MB): 1024
タイムアウト: 10秒
※LambdaにS3の書き込み権限が無い場合、権限を与えておく
「トリガー」で関数を有効化する
S3の指定のバケットに画像がアップロードし、サムネイル用のバケットに縮小画像が作成されているか確認する
アップロード時、権限など特に変更せずにデフォルト設定のままアップロードして大丈夫だった
AWS LambdaでのS3画像アップロードをトリガーとしたリサイズ(サムネイル作成) (1/2) ローカルPC上の準備
http://aws-mobile-development.hatenablog.com/entry/2016/11/25/152052
試すと「Cannot find module '/var/task/index'」のエラーが表示された場合、圧縮対象を間違っている可能性がある
CreateThumbnailフォルダを圧縮せずに、node_modulesとindex.jsを選択して圧縮し、createThumbnail.zipにリネームする必要がある
AWS LambdaでのS3画像アップロードをトリガーとしたリサイズ(サムネイル作成) (2/2) AWSコンソールでの作業
http://aws-mobile-development.hatenablog.com/entry/2016/11/25/155625
AWSコンソールでの作業手順。この手順の通り進めて大丈夫だった(最初はタイムアウトを設定していなかたので、タイムアウトのエラーになった)
解説通りトリガーを設定し、ポリシーをアタッチし、タイムアウトを10秒に設定した
この仕組みなら
「アプリからSDKで直接ファイルアップロード + サムネイル作成」
まで完全にAWS任せでできそう。負荷の心配も無さそう
■ブラウザから実行
※未検証
[アップデート]LambdaがHTTPSエンドポイントから実行可能になる、AWS Lambda Function URLsの機能が追加されました! | DevelopersIO
https://dev.classmethod.jp/articles/aws-lambda-function-urls-built-in-https-endpoints/
■ローカルでの動作確認
※未検証
本格的に開発するなら、環境の構築をしておくと良さそう
AWSがサーバレスアプリケーションのローカル開発とテストのための'SAM Local'をリリース
https://www.infoq.com/jp/news/2017/09/sam-local-beta
AWS Lambdaの開発をローカルで行う - サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2017/01/31/lambda-local/
■API Gateway
※APIを作成できる
※Lambda関数を実行したり、EC2へアクセスしたりなど、自由に定義できる
APIのURLルールは以下のようになる。独自ドメインを割り当てることもできる
https://アプリID.execute-api.リージョン.amazonaws.com/ステージ/リソース
アプリID ... svai50xfmb など、ランダムな文字列が割り当てられる
リージョン ... ap-northeast-1 などのリージョン名
ステージ ... prod, stg, dev, 2, 2.0.1 など。好きなようにいくつでも作成できる
「開発環境用」「本番環境用」など用途に合わせて作成してもいいし、
本番環境でのバージョン管理として 2.0.1 や prod_2.0.1 などバージョンごとにAPIを作成してもいい
API Gateway API のホスト名としてカスタムドメイン名を使用する
http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-custom-domains.html
API Gateway → 今すぐ始める
■APIの作成
「APIの作成」ボタンを押す
新しいAPIの作成: 新しいAPI
API名: my-api-sample
「APIの作成」ボタンを押すと、メソッドの無いAPIが作成される
■メソッドの作成
「アクション」から「メソッドの作成」を選択する
表示されたセレクトボックスから「GET」を選択し、チェックマークをクリックして決定する
続いてレスポンスを決定する
「統合タイプ」で「Mock」を選択し、「保存」をクリックする
「統合レスポンス」をクリックする
表の中にある、右向きの三角をクリックする
「本文マッピングテンプレート」をクリックし、「application/json」をクリックする
エディタ部分に以下を入力し、下にある「保存」をクリックし、さらに上にある青ボタンの「保存」をクリックする
{
"message": "foo"
}
「←メソッドの実行」をクリックしてメソッドの画面に戻り、
「クライアント」にある「テスト」をクリックし、
さらに「メソッドテスト」画面にある「テスト」をクリックする
結果として「レスポンス本文」に、上で設定したJSONが表示されていることを確認する
■デプロイ
画面左上にある「アクション」から「APIのデプロイ」を選択する
表示されたダイアログで「デプロイされるステージ」で「新しいステージ」を選択し、
「ステージ名」に「test」と入力して「デプロイ」ボタンを押す
https://svai50xfmb.execute-api.ap-northeast-1.amazonaws.com/test
のようなURLが発行されるので、クリックしてJSONが表示されればOK
■HTTPのメソッドを作成
APIとして「my-api-sample」を作成し、メソッドとして「GET」を作成する
「統合タイプ」で「HTTP」を選択し、「エンドポイントURL」に実在するURLを入力して「保存」をクリックする
メソッドの実行画面で「テスト」を実行して、設定したURLからのレスポングが表示されていることを確認する
■さらに別のメソッドを作成
「アクション」から「リソースの作成」を選択する
「リソース名」に「sample」と入力する。自動的に「リソースパス」が「/sample」になる
「リソースの作成」をクリックする
以降は先と同様の手順で「test2」というステージ名でデプロイする
https://eqpif1vx08.execute-api.ap-northeast-1.amazonaws.com/test2
https://eqpif1vx08.execute-api.ap-northeast-1.amazonaws.com/test2/sample
ステージ名やURL設計をどうすべきかは要勉強
■Lambda関数のメソッドを作成
「統合タイプ」で「Lambda関数」を選択し、
「Lambdaリージョン」で「ap-northeast-1」を選択し、
「Lambda関数」で「hello-world」を入力する(既存の関数)
「Lambda関数に権限を追加する」ダイアログが表示されるので、「OK」をクリックする
Lambda関数に引数を渡す方法は要勉強
■キャッシュ
APIを選択 → ステージ → ステージを選択 → 設定 → APIキャッシュを有効化
でキャッシュを利用できるみたい。要検証
■Amazon Elastic Container Registry(Amazon ECR)
AWSを使うなら、イメージのリポジトリにはECRを利用するといい
DockerHubは徐々に制限が厳しくなっている
また、Dockerhubからイメージがなくなったときのことを考えて、ECSなら常にECRを使っておくと無難
(公式イメージが無くなることは無いと思われるが、Dockerhubのサーバダウンなど可用性には影響するため)
【ECR】リポジトリの作成からイメージのプッシュまで - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2020/01/23/ecr/
AWS CLIを使ってECRにDockerイメージを登録する | DevelopersIO
https://dev.classmethod.jp/articles/push-docker-image-to-ecr-with-cli/
Amazon ECRからローカル環境にコンテナイメージをPullする方法 メモ - Qiita
https://qiita.com/KWS_0901/items/95a6a386ec3eabd49afa
AWS CLIをインストールし、ECRへDockerイメージをpushする手順 | Enjoy IT Life
https://nishinatoshiharu.com/ecr-with-awscli/
■CLIの準備
ECRへのプッシュにはCLIが必要となる
最近起動したAmazonLinux2サーバだと、以下がプリインストールされていた
$ aws --version
aws-cli/1.18.147 Python/2.7.18 Linux/4.14.243-185.433.amzn2.x86_64 botocore/1.18.6
「WSL2 + Ubuntu 20.04」環境へインストールしたときのメモは、
このファイルの「AWS CLI(WSL2 + Ubuntu 20.04 で使用する場合)」を参照
■イメージを作成
※WSL2環境でイメージを作成
「php:7.4-apache」をもとに、追加でファイルを作成するだけのイメージを作成する
docker\ecr_test\Dockerfile
… Dockerfileを作成
FROM php:7.4-apache
RUN touch /root/test1.txt
$ docker image build -t php:ecr_test docker/ecr_test
… Dockerfileをもとに、新しいイメージをビルド
$ docker image ls
… 作成されたイメージを確認
docker\ecr_test\code\index.php
… 動作確認用にPHPプログラムを作成
<?php phpinfo() ?>
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d php:ecr_test
… 作成したイメージから起動
$ docker container exec -it ecr_test bash
… phpコンテナのターミナルに接続
# ls /root
… テストファイルを確認する
また
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
確認できたら、起動したコンテナは終了しておく
$ docker container ls
$ docker container rm -f a3fee9aba4b8
■リポジトリの作成
※AWSコンソールで作業
Elastic Container Registry → リポジトリを作成
※初めてアクセスした場合、まずは「使用方法」をクリックすると「リポジトリを作成」と同じ画面が表示される
以下の内容でリポジトリを作成(いったん、リポジトリ名を入力する以外は初期値で作成してみる)
なお、「可視性設定」と「リポジトリ名」は後から変更できない
可視性設定: プライベート
リポジトリ名: ecr_test
タグのイミュータビリティ: 無効(実際に案件用にリポジトリを作成する場合、「有効」にしておくといい。詳細は後述の「タグの上書き禁止設定」を参照)
「リポジトリを作成」ボタンを押すとリポジトリが作成される
■イメージのプッシュ
※タグは「latest」ではなく、「1.1」や「1.0.1」のようなバージョンを指定しておく方が無難そう
詳細は後述の「タグの上書き禁止設定」を参照
AWSコンソールで作成したリポジトリにチェックを入れ、「プッシュコマンドの表示」ボタンを押す
解説とともに、以下のコマンドが表示される
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
docker image build -t ecr_test .
docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
以下はWSL2環境で実際に実行した時のもの
※アクセスキーには、ECR操作のための最低限の権限だけを設定しておくといい
この場合、AWSへの接続確認は「$ aws ecr list-images --repository-name ecr_test --query "imageIds[*].imageTag" --output table」のようにしてタグ一覧を表示すると良さそう
(「ecr_test」部分は、接続したいリポジトリ名を指定する)
$ cd docker/ecr_test
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Your password will be stored unencrypted in /home/refirio/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
$ docker image build -t ecr_test .
Sending build context to Docker daemon 2.56kB
Step 1/2 : FROM php:7.4-apache
---> 93e55f680811
Step 2/2 : RUN touch /root/test1.txt
---> Using cache
---> 4229d38cf367
Successfully built 4229d38cf367
Successfully tagged ecr_test:latest
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test]
e91015d98cd4: Pushed
a8ada76173c3: Pushed
46a0f0111934: Pushed
d6da32e9bff2: Pushed
400f5ced50ab: Pushed
7485c1ee99c3: Pushed
b98c6acdec28: Pushed
86b5e34374f3: Pushed
c52f69d9a297: Pushed
c24f05541085: Pushed
82f581b09510: Pushed
3b7e206db54c: Pushed
575b147c7c31: Pushed
814bff734324: Pushed
1.0.0: digest: sha256:fd3cbc2c64dd2d4b0fcb57927e49a339fbb92527efd9dd96ad7293a05a7c0092 size: 3242
ECRでリポジトリ名 ecr_test をクリックし、イメージタグとして「1.0.0」が現れていることを確認する
■イメージを利用
ECRからの取得を確認できるようにするため、
「イメージを作成」でタグ付けしたイメージを以下で削除しておく
$ docker image ls
$ docker image rm 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
イメージを再取得
$ cd
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
… プッシュしたイメージから起動
$ docker container exec -it ecr_test bash
… phpコンテナのターミナルに接続
# ls /root
… テストファイルを確認する
確認できたら、起動したコンテナは終了しておく
$ docker container ls
$ docker container rm -f 2cbfa9da239c
■イメージの脆弱性スキャン
リポジトリ内のイメージ一覧で、任意のイメージにチェックを入れて「スキャン」を押すと、イメージの脆弱性スキャンを利用できる
上記イメージに対して実行すると、315件の警告が表示された。内訳は以下のとおり
Critical ... 1
High ... 10
Medium ... 47
Low ... 46
Informational ... 192
Undefined ... 19
Criticalの内容は以下のとおり
名前: CVE-2019-19814
パッケージ: linux:4.19.194-3
重要度: CRITICAL
説明: In the Linux kernel 5.0.21, mounting a crafted f2fs filesystem image can cause __remove_dirty_segment slab-out-of-bounds write access because an array is bounded by the number of dirty types (8) but the array index can exceed this.
【超待望アップデート】ECRに対する脆弱性スキャン機能が提供されました | DevelopersIO
https://dev.classmethod.jp/articles/ecr-repository-scan/
対応については、また確認しておきたい
「apt-get update」を行なったイメージでも同様の結果になった
update に続けて upgrade もすればいいかと思ったが、それは非推奨らしい
Linux Ubuntu - apt-get update / upgrade の違い - Qiita
https://qiita.com/YumaInaura/items/dd50ba59c245a0a5f3f1
Dockerfileで`apt-get upgrade`をつかってはいけない。注:古い日本語版だと誤訳されています。 - Qiita
https://qiita.com/aimof/items/8f08671c5ab356b01e2b
イメージを作る環境(WSLのUbuntu)をアップデートすればいいかと思ったが、スキャン結果には影響が無かった
$ sudo apt-get update
$ sudo apt-get upgrade
php:7.3.27-apache Critical Issue in ECR Scan - Issue #1143 - docker-library/php - GitHub
https://github.com/docker-library/php/issues/1143
以下は参考になるか
CVE-2019-19814 detected by AWS ECR scanner in a Docker image created by BentoML - Issue #2140 - bentoml/BentoML - GitHub
https://github.com/bentoml/BentoML/issues/2140
GitHub - docker-library/faq: Frequently Asked Questions
https://github.com/docker-library/faq#why-does-my-security-scanner-show-that-an-image-has-so-many-cv...
脆弱性スキャンについては、後述の「ベースイメージのセキュリティチェックについて考察」も参照
■latestタグについて
※タグは「latest」ではなく、「1.1」や「1.0.1」のようなバージョンを指定しておく方が無難そう
詳細は後述の「タグの上書き禁止設定」を参照
以下のように「ecr_test:latest」を付けてイメージをプッシュした場合、
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
以下のように「ecr_test」のみの指定で「latest」を取得できる
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test
Dockerfile を以下のように編集
docker\php_create_file\Dockerfile
FROM php:7.4-apache
RUN touch /root/test1.txt
RUN touch /root/test2.txt
イメージをビルド
$ cd docker/ecr_test
$ docker image build -t ecr_test .
latestタグを上書きしてプッシュ
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
イメージを再取得
$ docker image rm 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ cd
$ docker container run --name ecr_test -v $PWD/docker/ecr_test/code:/var/www/html -p 80:80 -d 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test
最新の内容を取得できていることが確認できる
■タグの上書き禁止設定
リポジトリの設定編集で「タグのイミュータビリティ」を「有効」にすると、
タグを上書きしてプッシュしようとすると以下のようなエラーになる
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test]
3d6ebb73c1c8: Pushed
682dac57ee22: Layer already exists
e91015d98cd4: Layer already exists
a8ada76173c3: Layer already exists
46a0f0111934: Layer already exists
d6da32e9bff2: Layer already exists
400f5ced50ab: Layer already exists
7485c1ee99c3: Layer already exists
b98c6acdec28: Layer already exists
86b5e34374f3: Layer already exists
c52f69d9a297: Layer already exists
c24f05541085: Layer already exists
82f581b09510: Layer already exists
3b7e206db54c: Layer already exists
575b147c7c31: Layer already exists
814bff734324: Layer already exists
tag invalid: The image tag 'latest' already exists in the 'ecr_test' repository and cannot be overwritten because the repository is immutable.
以下のように、別のタグ(ここでは「1.0.1」)を指定するとプッシュできる
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
これにより、常に「latest」タグを付けてプッシュする運用を禁止することができる
(プッシュのためには、明示的に「1.1」や「1.0.1」のようなバージョンを指定することになる)
「latest」タグを使うと常に最終バージョンを取得するため、意図しない修正が入ったイメージを取得してしまう可能性がある
よってタグを付けるとき&Dockerfileで指定するとき、どちらも明示的にバージョンを指定するといい
■プログラムをイメージに含める
トップページにアクセスすると、ボリューム同期なしで phpinfo() が表示されるようにしてみる
docker\ecr_test\code\html\index.php
<?php phpinfo() ?>
docker\ecr_test\Dockerfile
FROM php:7.4-apache
COPY code/html /var/www/html
$ docker image build -t php:ecr_test docker/ecr_test
$ docker image ls
以下で起動する
$ docker container run --name ecr_test -p 80:80 -d php:ecr_test
$ docker container exec -it ecr_test bash
# ls /var/www/html
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker container ls
$ docker container rm -f 6f986c913818
タグ「1.1.0」を付けてプッシュする
$ cd docker/ecr_test
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t ecr_test .
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
ECRでリポジトリ名 ecr_test をクリックし、イメージタグとして「1.1.0」が現れていることを確認する
Docker Composeでの起動も試す
docker\ecr_compose_test\docker-compose.yml
version: '3'
networks:
compose_network:
driver: bridge
services:
php:
container_name: ecr_test
ports:
- 80:80
networks:
- compose_network
image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.1.0
ファイルを用意できたら以下で起動する
$ cd docker/ecr_compose_test
$ docker-compose build
$ docker-compose up -d
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker-compose down
■パブリックレジストリの利用
※うまくいかず
ECRからDocker公式イメージが取得可能になったらしい
Amazon ECR PublicからDocker公式イメージが取得可能に。Docker Hubのプル制限を回避可能。AWS re:Invent 2021 − Publickey
https://www.publickey1.jp/blog/21/amazon_ecr_publicdockerdocker_hubaws_reinvent_2021.html
[速報]AWS、Docker Hubの代替を狙う「Amazon Elastic Container Registry Public」提供開始。AWS re:Invent 2020 − Publickey
https://www.publickey1.jp/blog/20/awsdocker_hubamazon_elastic_container_registry_publicaws_reinvent_...
ECRをパブリックレジストリとして利用可能になりました! #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/ecr-public-registry/
ECRにある「php:7.4-apache」を使ってみる
Elastic Container Registry → Public gallery
ページ上部の検索フォームから「php:7.4-apache」と入力して検索すると、以下のページにたどり着くことができる
「Mirror of dockerhub php:7.4-apache」と書かれているので、DockerHubにあるイメージのコピーだと思われる
https://gallery.ecr.aws/w8m1p4d9/php_7_4_apache
docker\ecr_test\Dockerfile
FROM public.ecr.aws/w8m1p4d9/php_7_4_apache:latest
COPY code/html /var/www/html
$ docker image build -t php:ecr_test docker/ecr_test
Sending build context to Docker daemon 5.12kB
Step 1/2 : FROM public.ecr.aws/w8m1p4d9/php_7_4_apache:latest
latest: Pulling from w8m1p4d9/php_7_4_apache
6f28985ad184: Pulling fs layer
db883aae18bc: Pulling fs layer
ffae70ea03a9: Pulling fs layer
1e8027612378: Waiting
3ec32e53dce5: Waiting
3bb74037bf77: Waiting
feda0fbd85b1: Waiting
b2244185b327: Waiting
8852ae668073: Waiting
985e21deb66e: Waiting
f262da4e7afa: Waiting
157f3d683e13: Waiting
990684a56233: Waiting
error pulling image configuration: Get "https://d2glxqk2uabbnd.cloudfront.net/ea2ac3-888802067332-72bc2017-5f4e-65a5-91f4-1bc1b7f291e8/441e156b-f02f-449d-9755-258c18f5ed29?Expires=1641552304&Signature=ipSg9QA9J0En6pUPT6IYwqLzAG8DFmaUcv7FGj3-YTVuPvv8MhT72RpRObzimwKt27OuPFMQcC3c8L-T717LgMHu03o4dXFF8DNv~yAjiTWCmOD8rxn1T7HuqsVeyG1W-dx8WwWW5KS2xlnbrdSI58uoc8gckWMzN4fEElqIA0UtpfkWxnO7IRzlnGYHO0T0ZMvZStu5N26FI2z2IDi2SW~YUwaItKyfJy0BhO0st8fi1RZZTGZblQovNv1c01EF1XzhyCf7uyyKQH0WY5JPgFmecljNpivgeo4OKDJbbsvsOAJAKZFnI06JCu2soFO2megUnBCnS5rfbo1zHnGZ4g__&Key-Pair-Id=KSPLJWGOARK62": dial tcp: lookup d2glxqk2uabbnd.cloudfront.net on 172.21.192.1:53: read udp 172.21.198.215:38077->172.21.192.1:53: i/o timeout
直接は取得できない?
Pull through cacheという仕組みを使う前提?
Amazon ECRのPull through cacheでECR PublicからDocker公式イメージをpullする - Qiita
https://qiita.com/hayao_k/items/78d3acd5b19af0cfa73b
Elastic Container Registry → Private registry → Pull through cache → ルールを追加
パブリックレジストリ: ECR Public
送信先: ecr-public (デフォルトのままとした)
「保存」ボタンをクリック
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/w8m1p4d9/php_7_4_apache:latest
latest: Pulling from ecr-public/w8m1p4d9/php_7_4_apache
6f28985ad184: Pulling fs layer
db883aae18bc: Pulling fs layer
ffae70ea03a9: Pulling fs layer
1e8027612378: Waiting
3ec32e53dce5: Waiting
3bb74037bf77: Waiting
feda0fbd85b1: Waiting
b2244185b327: Waiting
8852ae668073: Waiting
985e21deb66e: Waiting
f262da4e7afa: Waiting
157f3d683e13: Waiting
990684a56233: Waiting
error pulling image configuration: Get "https://d2glxqk2uabbnd.cloudfront.net/ea2ac3-888802067332-72bc2017-5f4e-65a5-91f4-1bc1b7f291e8/441e156b-f02f-449d-9755-258c18f5ed29?CallerAccountId=410618224259&Expires=1641553565&Signature=ZxqG3VRFp2gKq8enC5vyllnSMKBpSYNuvBddIpAYQQHEdg1~81Wgl37CortOA62aWQ-ddL2dkRFB5LawVdh6EasXrb-hlHy35sdVCQbplrfw1qzCv8i9Mp~wq72jD5rnokqJIdi~bUTIpIAN3VWW~n8gypQjf0TC9TD0XsErzHwar8t4~GcYalanEQ-RqcZ-exUMteduXh~MQLNIhtC~SH2CEZNaTbE6aon4Q9HjHo73PAbHi0CyJAf52PzV1hYaVywA3r5GYECgbsW65E1PNx9vMQyG1HLvHaizRp3BbE0jHSRMMX2EqfH0wG1J5WukkPzYAMpBkoL1qGwrF~slnw__&Key-Pair-Id=KSPLJWGOARK62": dial tcp: lookup d2glxqk2uabbnd.cloudfront.net on 172.21.192.1:53: read udp 172.21.198.215:43724->172.21.192.1:53: i/o timeout
それでも取得できない?
Amazon ECRに「プルスルーキャッシュリポジトリ」機能が追加されました #reinvent | DevelopersIO
https://dev.classmethod.jp/articles/ecr-pull-through-cache-repositories/
$ docker image pull 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr-public/amazonlinux/amazonlinux:latest
latest: Pulling from ecr-public/amazonlinux/amazonlinux
8b8a142162d2: Pulling fs layer
error pulling image configuration: Get "https://prod-ap-northeast-1-starport-layer-bucket.s3.ap-northeast-1.amazonaws.com/70714d-410618224259-b2beaaf0-1cbb-117e-eacb-91470817179b/725cefd4-a87c-42fa-b3ed-23488a697ef0?X-Amz-Security-Token=IQoJb3JpZ2luX2VjELH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLW5vcnRoZWFzdC0xIkcwRQIgRd4kBfF0JdGNO5z6siF1bRu7gknlu9KV26U2JSbDhb8CIQDShYYLQI7YfgFkJhu4rjRPmHdgxqf%2BlLJY2U7RzceF2CrRAwi7%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8BEAMaDDc1NTI1NTY5Mjg2NSIMNGsKlupyXWB01Mm6KqUDPyEIrYf92RxamIfJBOD%2FQa1I9afmnW9TIV%2FLnrIU6MyM9bJ6qQhw2aewaXynx9NR2qqaE53vmUgpOLIQj7%2Fv7yL%2BTuI5tI9HPEKtwRyPb9E5ovgtdOORa8kEg%2F5K7LGzPVlafYuDu%2FWme9f60P7dw7VRgqiRFQ7pnFM50DX9eNxmGkn%2F2GzCg7OKaY141XtyEz9NkEwm3vOASnGo3tPXRuuOe0bMcZOGAl5%2FnwEbAq5QCvs%2FodVeaE0sP0hDi44p1hMuOMh8X2skQTtv9xJCg5cdFBJsMo%2Fm0tiih%2FfZpmwokM2YtZ0AMQNzLNDjFrunt2F2WwejLBIjx0uj0oKyOCYQreYvQG4JPXxpOZZy57Wdvt38p%2BVMoJfvYkuArIaf0HWAlrPuIRcQTsx7BPGepNPW4ZK5PG34w835iofsfSHTAWt1fNxIYq0OuZzAef4TEIOg3Kcpbg8MGWLaIclML8ZQYQ2FGLu4fAN1Hoc4NJ70wcBBGezb%2BD2TrUR8hiNdDy7iZnSGIcJpERm5%2BNFMbVZrg9H%2FCoVt6aGkoWVfXWTqM2YiOjD1jeCOBjqhAfLEVya56lIu5ZCv6F2aMiTqIWaE%2FOH3yZ9R5ftHYoFTPMnuAAOX6cSIogwpeaFFMfWFEV2ATHBOkMUiUEcbRldYX%2FpkNY28iPZJC6GgeyA3Mi6Xm6GZLTN1ZykNHlMbSn%2BHDlo4ohixtbQnfd6g%2FEcnBu0JdiJhomkYAbXmqAZLnDUNH7VTM3ed8KcBLtuOALk%2FcI4XORnxpinurUJ7n8a6&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220107T101729Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=ASIA27WF7JZA4KABMSMU%2F20220107%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Signature=429064555b3bb4f68a7be6f36d22ec42bf8f565638c5467647ff96a3a23513a2": dial tcp: lookup prod-ap-northeast-1-starport-layer-bucket.s3.ap-northeast-1.amazonaws.com on 172.21.192.1:53: read udp 172.21.198.215:60628->172.21.192.1:53: i/o timeout
それでも取得できない?
何か勘違いしてそうなので、改めて勉強する
取得できたら、AWS.txt の「Amazon Elastic Container Registry(Amazon ECR)」の「プログラムをイメージに含める」を参考に、Dockerfileを調整してプッシュするか
■ECSとEKS・EC2とFargateの比較
■ECSとEKS
ECS ... コンテナ管理のマネージドサービス
他AWSサービスと組み合わせて使える
EKS ... Kubernetesのマネージドサービス
OSSエコシステム中心な運用ができる
■EC2とFargate
EC2 ... コンテナをEC2で管理
OS管理をする必要がある
Fargate ... コンテナをサーバレスで管理
OS管理をしなくていい
■参考
上記は以下「なんでAWS選んだんですか?」資料のP.31をもとにしている
「なんでAWS選んだんですか?」 - 社内AWSイベント資料の公開してみます - How elegant the tech world is...!
https://iselegant.hatenablog.com/entry/2021/07/09/014410
why-aws.pdf - Speaker Deck
https://speakerdeck.com/iselegant/why-aws
■Amazon Elastic Container Service(Amazon ECS)
AWS ECSでDockerコンテナ管理入門(基本的な使い方、Blue/Green Deployment、AutoScalingなどいろいろ試してみた) - Qiita
https://qiita.com/uzresk/items/6acc90e80b0a79b961ce
【Docker × ECS入門】docker compose upでECSデプロイ - Qiita
https://qiita.com/Rubyist_SOTA/items/1ead200bf602569804ea
ECSやEKSのメトリクスを一括取得するContainer Insightsが一般公開!既存ECSクラスタも追加設定可能に! | DevelopersIO
https://dev.classmethod.jp/articles/container-insights-ga/
ECSの概念を理解しよう - まーぽんって誰がつけたの?
http://www.mpon.me/entry/2017/11/19/200000
ECSでごっつ簡単に機密情報を環境変数に展開できるようになりました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/ecs-secrets/
Amazon ECSを安定運用するためにやっていること コンテナインスタンス、ログ、モニタリングにおける工夫 - ログミーTech
https://logmi.jp/tech/articles/320723
基礎から応用までじっくり学ぶECS Fargateを利用したコンテナ環境構築 #Fargate | Developers.IO
https://dev.classmethod.jp/articles/developers-io-2020-connect-kaji-ecs-fargate/
ECS×Fargateで実現する運用コストほぼ0なコンテナ運用の仕組み/ ecs fargate low cost operation - Speaker Deck
https://speakerdeck.com/shoichiron/ecs-fargate-low-cost-operation
Docker ComposeによるAmazon ECS対応がGAに!コンテナをローカル環境と同じノリでECS環境で起動できるぞ!! | Developers.IO
https://dev.classmethod.jp/articles/docker-compose-for-amazon-ecs-now-available/
ラズパイでもAmazon ECSを動かせる、「Amazon ECS Anywhere」が正式リリース。ラズパイやオンプレミスのコンテナ環境をAWSから集中管理可能 − Publickey
https://www.publickey1.jp/blog/21/amazon_ecsamazon_ecs_anywhereaws.html
Amazon ECS Anywhereを使ってAWS外でもコンテナが運用できるようになったので使ってみた | DevelopersIO
https://dev.classmethod.jp/articles/try-amazon-ecs-anywhere/
アプリケーション開発者は Amazon ECS あるいは Kubernetes をどこまで知るべきか #AWSDevDay / You build it, you run it - Speaker Deck
https://speakerdeck.com/toricls/you-build-it-you-run-it
AWS Black Belt コンテナシリーズのあるきかた 2021年10月版 | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/aws-black-belt-guide202110/
「コンテナ・サーバレスがもたらす世界と開発者がAWS上で取り組むべきこと」というタイトルで登壇しました - How elegant the tech world is...!
https://iselegant.hatenablog.com/entry/2022/03/08/071906
■作業の流れ
おおまかに、以下のような作業の流れとなる
削除する場合、逆順に作業する
1. VPCの作成 ... ネットワークを作成する(クラスターと一緒に作成できるが、あらかじめ作成しておく方が良さそう)
2. ロードバランサーの作成 ... クラスターの上位に配置するロードバランサーを作成する
3. タスクの定義 ... クラスター上で動かすコンテナの情報を定義する(イメージ、CPUやメモリの制限、アプリケーションの環境変数など)
4. クラスターの作成 ... クラスターを動かすためのEC2の設定を行う(インスタンスタイプ、インスタンス数、ネットワークなど)
5. サービスの作成 ... タスク、クラスター、ロードバランサーを結びつける(一つのクラスターに複数のサービスを登録することもできる)
■VPCの作成
クラスター作成時、VPCを作成する指定を行なえばCloudFormationで一緒に作成される
が、ここではCloudFormationであらかじめ作成しておく(管理しやすいそうなので)
VPCの名前は、ここでは「Container」とする
※VPCやセキュリティグループは、CloudFormationであらかじめ作成しておく方が良さそう
手順中に新規に作った場合、名前が無しで作られるようなので、名前の設定はしておくと良さそう
手順中に作ると、ECSクラスターと一緒に削除してくれるメリットはあるが、そうそう削除はしないか
■ロードバランサーの作成
EC2 → ターゲットグループ → ターゲットグループの作成
Choose a target type: Instance
Target group name: Container-Test-TargetGroup
VPC: Container(あらかじめ作成しておいたもの)
Protocol version: HTTP1
「Next」をクリック
「Register targets」の画面になる
特に何も変更せず「Create target group」をクリック
これでターゲットの無いターゲットグループができる
EC2 → ロードバランサー → ロードバランサーの作成
Select load balancer type: Application Load Balancer
Load balancer name: Container-Test-LoadBalancer
VPC: Container(あらかじめ作成しておいたもの)
Mappings: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの)
Security groups: default, Container-WebSecurityGroup(あらかじめ作成しておいたもの / 80番ポートを通すためのセキュリティグループを選択)
Listeners and routing
Protocol: HTTP
Port: 80
Default action: Container-Test-TargetGroup
「Create load balancer」をクリック
ロードバランサーが作成されるので、「View load balancer」で確認する
ターゲットタイプについては以下を参照
Blue/Greenデプロイを使うなら、「Instance」ではなく「IP addresses」にしておく必要がある
(古いプログラムと新しいプログラムを混在することが短時間でも許容できない場合、Blue/Greenデプロイを採用するといい)
今回は「Instance」でいい
[新機能] ALBのターゲットにIPアドレスを指定可能になりました | DevelopersIO
https://dev.classmethod.jp/articles/ip-target-for-alb/
ALBのターゲットにIPアドレスを指定できる機能は、2017年からの機能らしい
外部のサーバを指定したりではなく、ローカルのIPを指定する前提みたい
到達可能なIPアドレスであれば、VPCをまたいで指定できるメリットはあるみたい
■タスクの定義
※イメージは「Amazon Elastic Container Registry(Amazon ECR)」で作成したものを使用する
※本番運用するなら、「コンテナの追加」の際に「ストレージとログ」の「ログ設定」にチェックを入れておくか
再作成する場合、CloudWatchのロググループが作成済みなら、あらかじめ削除しておく必要があるか
Elastic Container Service → Amazon ECS → タスク定義 → 新しいタスク定義の作成
起動タイプの互換性の選択
「EC2」を選択して「次のステップ」をクリック
タスクとコンテナの定義の設定
タスク定義名: Container-Test-Task
タスクロール: なし
ネットワークモード: <default>
「コンテナの追加」をクリック
コンテナ名: ecr_test
イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0
プライベートレジストリの認証: (チェックしない / ECR以外でプライベートリポジトリを利用する場合に必要みたい)
メモリ制限 (MiB): ハード制限 128
ポートマッピング:
ホストポート: 80
コンテナポート: 80
プロトコル: tcp
環境
基本: (チェックを入れたままにする)
「追加」をクリック
「作成」をクリック
「タスク定義が正常に作成されました」と表示された
ネットワークモードについては以下を参考
Blue/Greenデプロイを使うなら、「<default>」ではなく「awsvpc」にする必要があるみたい
今回は「<default>」でいい
ECSでEC2インスタンスを利用する際のネットワークモードについて調べてみた | DevelopersIO
https://dev.classmethod.jp/articles/ecs-networking-mode/
ECSのバックエンドをEC2からFargateに変更するにあたり知っておくとよさそうな事 - コネヒト開発者ブログ
https://tech.connehito.com/entry/2018/09/05/164805
AWS ECSのネットワークモードの違いを調べてみた - 私の戦闘力は53万です
https://cloud-aws-gcp.hateblo.jp/entry/2019/10/30/023835
■クラスターの作成
Elastic Container Service → Amazon ECS → クラスター → クラスターの作成
クラスターテンプレートの選択
「EC2 Linux + ネットワーキング」を選択して「次のステップ」をクリック
クラスターの設定
クラスター名: Container-Test-Cluster
プロビジョニングモデル: オンデマンドインスタンス
EC2 インスタンスタイプ: t2.micro
インスタンス数: 2
EC2 AMI ID: Amazon Linux 2 AMI
ルート EBS ボリュームサイズ (GiB): 30
キーペア: (EC2に接続するためのキーを必要に応じて選択 / Fargateで構築する場合は不要?)
ネットワーキング
VPC: Container(あらかじめ作成しておいたもの)
サブネット: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの)
パブリック IP の自動割り当て: サブネット設定を使用
セキュリティグループ: Container-WebSecurityGroup(あらかじめ作成しておいたもの)
コンテナインスタンスの IAM ロール: ecsInstanceRole(初回は「新しいロールの作成」を選択する)
CloudWatch Container Insights: (チェックしない / 後から変更できないらしいので、本番環境用ならチェックを入れておくと良さそう)
「作成」をクリック
作成完了後、「クラスターの表示」をクリックすると、Container-Test-Clusterの詳細が表示される
※クラスター(EC2)の作成には1〜2分ほどかかる
完了時に以下のメッセージが表示され、CloudFromationには「EC2ContainerService-Container-Test-Cluster」が作成されていた(あらかじめ作成したVPCを選択した場合でも、作成された。オートスケーリングのための設定のみ?)
ECS クラスター: ECSクラスターContainer-Test-Clusterが正常に作成されました
ECS インスタンスの IAM ポリシー: ロールecsInstanceRoleの IAM ポリシーが正常にアタッチされました
CloudFormation スタック: CloudFormation スタックEC2ContainerService-Container-Test-Clusterとそのリソースが正常に作成されました
※はじめてクラスターを作成する際、「Unable to assume the service linked role. Please verify that the ECS service linked role exists.」と表示されて中断された
もう一度同じ操作をすると、「ECSクラスターContainer-Test-Clusterが正常に作成されました」と表示されて完了した
クラスター作成時に必要なロールが作成されるが、そのロールが使えるようになるには若干のタイムラグがあるため…らしい
ECS初回構築時に自動作成されるIAMロール「AWSServiceRoleForECS」とTerraformでの予期せぬ挙動 - 憂鬱な世界にネコパンチ!
https://nekopunch.hatenablog.com/entry/2018/09/01/122525
AWS Fargate - Qiita
https://qiita.com/propella/items/d261879e89774a06e2bb
■サービスの作成
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → 作成
サービスの設定
起動タイプ: EC2
タスク定義
ファミリー: Container-Test-Task
リビジョン: 1 (latest)
クラスター: Container-Test-Cluster
サービス名: Container-Test-Service
サービスタイプ: REPLICA ※可能性向上のためには、サービスタイプを「DAEMON」にしてタスクの数を「自動」にする方がいい?タスクの配置で「AZバランススプレッド」を選択しておけば十分?要検証
タスクの数: 2
タスクの配置
配置テンプレート: AZバランススプレッド
「次のステップ」をクリック
ネットワーク構成
ヘルスチェックの猶予期間: 120(下で「ロードバランサーの種類」を選択したあとに入力できる / 0だとコンテナサイズによってはうまく起動しないことがあるらしい / もっと小さい値でもいいかもしれない)
ロードバランサーの種類: Application Load Balancer
サービス用の IAM ロールの選択: AWSServiceRoleForECS
ロードバランサー名: Container-Test-LoadBalancer
ロードバランス用のコンテナ: 「ecr_test:80:80」を選択して「ロードバランサーに追加」
プロダクションリスナーポート: 80:HTTP
ターゲットグループ名: Container-Test-TargetGroup
サービスの検出の統合の有効化: (チェックしない / 本番環境用ならチェックしておくと良さそうだが要確認)
「次のステップ」をクリック
Auto Scaling (オプション)
Service Auto Scaling: サービスの必要数を直接調整しない
「次のステップ」をクリック
「サービスの作成」をクリック
「サービス 作成しました。タスクがすぐに開始されます。」と表示された
「サービスの表示」をクリック
タスク一覧に、「前回のステータス」が「PROVISIONING」になっているタスクが2つ表示される。10秒ほど待つと「PENDING」になり、さらに「RUNNNING」になる
「サービスタイプ」と「タスクの配置」については引き続き調査したい
上の手順ではサービスタイプは「REPLICA」で、配置テンプレートを「AZバランススプレッド」としているが、他の方法も検討すべきか
ECSをより便利に使うためのポイント解説 - UUUM攻殻機動隊(エンジニアブログ)
https://system.blog.uuum.jp/entry/aws-ecs-tips
Amazon ECS タスク配置戦略 - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-placement-strategies.html
■動作確認
ロードバランサーのDNS名にアクセスすると、ページが表示される
http://Container-Test-LoadBalancer-1234567890.ap-northeast-1.elb.amazonaws.com/
ターゲットグループを確認すると、以下2つのインスタンスがぶら下がっている
i-02e8ec2ab414b6c2d
i-0017fea28482d815b
各インスタンスの名前は、以下のようになっている(自動で付けられたもの)
ECS Instance - EC2ContainerService-Container-Test-Cluster
各インスタンスのIPアドレスで、直接アクセスすることもできる
http://203.0.113.1/
http://203.0.113.2/
また、インスタンスに紐づいているセキュリティグループで22番ポートへのアクセスを許可すると、SSHで直接アクセスできる
サーバ内の /etc/ecs/ecs.config に、ECSの設定ファイルらしきものがある
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → タスク
以下が表示されている
インスタンスは同じものが使われている?
タスク タスク定義 コンテナインスタンス EC2インスタンス
0715d017bb5f4764bed66b00836d899d Container-Test-Task:1 5b23968a45a74f6aa16bf9f0b019e19d i-02e8ec2ab414b6c2d
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
タスク 0715d017bb5f4764bed66b00836d899d を停止させてみる
すぐにタスクの一覧から削除された
10秒程度で、すぐに別のインスタンスが起動した
タスク タスク定義 コンテナインスタンス EC2インスタンス
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
7d346e49f4be45de9b53350378211f81 Container-Test-Task:1 5b23968a45a74f6aa16bf9f0b019e19d i-02e8ec2ab414b6c2d
今度はEC2のインスタンス一覧から、i-02e8ec2ab414b6c2d を直接停止させてみる
停止させる際
・このインスタンスはAuto Scalingグループにアタッチされている
・停止すると自動的に別のインスタンスが立ち上がる可能性がある
という注意が表示される
自動で別のEC2インスタンスが起動された
タスク タスク定義 コンテナインスタンス EC2インスタンス
2bd80034be4b4eb1bb91d5a732dff8cf Container-Test-Task:1 fd472723b89845549b13024396418ae2 i-0017fea28482d815b
374003de24e043dfa5b7ac309be69d4d Container-Test-Task:1 7ab06e6ff00747eb9b04a070a9cbe596 i-0b11a824305c8d37d
新しいインスタンスにも、HTTP&SSHとも直接アクセスできている
■イメージの変更準備(動的ポートマッピングの設定)
動的ポートマッピングを利用するため、
Container-WebSecurityGroup(Webサーバに設定しているセキュリティグループ)のインバウンドルールに以下を追加
タイプ: カスタムTCP
プロトコル: TCP
ポート範囲: 32768-61000
ソース: Container-WebSecurityGroup ※ロードバランサーからのアクセスを許可する(ロードバランサー専用にセキュリティグループを設定しているなら、それを指定する)
説明: Dynamic port mapping
【図解】ELB + ECSの動的ポートマッピング | DevelopersIO
https://dev.classmethod.jp/articles/dynamic-portmapping-elb-ecs/
ECSでタスク定義更新してデプロイしても古いタスク定義のままになる問題について - インターネットのスケッチ
https://khanamoto.hatenablog.com/entry/2021/05/18/222001
■イメージの変更準備(イメージの準備)
変更したイメージを作成し、ECRにプッシュする
$ cd docker/ecr_test
$ docker image build -t ecr_test .
$ docker image tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
■イメージの変更
タスク定義に新しいリビジョンを作成する
Elastic Container Service → Amazon ECS → タスク定義
「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック
(以下、前回タスクを作成した時の内容をベースに入力する)
タスク定義名: Container-Test-Task (変更せず)
タスクロール: なし
ネットワークモード: <default> (変更せず)
もともと追加されている「ecr_test」をクリックし、必要な箇所を調整
コンテナ名: ecr_test
イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1
プライベートレジストリの認証: (チェックしない)
メモリ制限 (MiB): ハード制限 128
ポートマッピング:
ホストポート: 0 ※通常は80だが、動的ポートマッピングを利用するため0に設定する
コンテナポート: 80
プロトコル: tcp
環境
基本: (チェックを入れたままにする)
「更新」をクリック
「作成」をクリック
「タスク定義 Container-Test-Task: 3 の新しいリビジョンを正常に作成しました」と表示された
次にサービスを更新して新しいリビジョンを選択する
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → 更新
サービスの設定
タスク定義
リビジョン: 2 (latest)
新しいデプロイの強制: チェックを付ける
タスクの配置
配置テンプレート: AZバランススプレッド
「次のステップ」をクリック
「次のステップ」をクリック
「次のステップ」をクリック
「サービスの更新」をクリック
「デプロイメント」タブ内の画面に移動し、デプロイ状況が表示される
「ロールアウトの状態」列の最下部が「完了」になれば完了(通常すぐに完了される)
ただしこの時点では、まだ前のバージョンのタスクが起動されたまま
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス
「Container-Test-Service」のタスク定義のバージョンが変わっていることを確認する
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → タスク
タスクが4つになっていることを確認する(タスクの起動までは2〜3分程度かかる)
タスク更新時に以下のように設定したので、最大で4タスク、最低で2タスク起動されることになる
タスクの数: 2
最小ヘルス率: 100
最大率: 200
2〜3分程度待つと、更新の反映が完了する
(不要になったタスクの終了も含めてだと、10分程度かかる)
■補足1
EC2の台数には変化がない
ロードバランサーには変化がない
ターゲットグループでは、以下のようにターゲットの切り替えを確認できる
(ターゲットが切り替わらない場合、動的ポートマッピングのためのセキュリティグループ設定がされているかを確認する)
Instance ID Name
Port Zone Health status Health status details
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1a healthy
↓
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1c draining Target deregistration is in progress
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1a healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 80 ap-northeast-1a draining Target deregistration is in progress
↓
i-02d84fe5687ee1ab1 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1c healthy
i-015079215549d5a87 ECS Instance - EC2ContainerService-Container-Test-Cluster 49159 ap-northeast-1a healthy
■補足2
「新しいデプロイの強制」にチェックを入れなかった場合、以下のようにしてタスクを入れ替えることができる
1. タスクを1つ選択し、「停止」ボタンで停止させる
2. サービスの設定に従って、「Container-Test-Task:1」ではなく「Container-Test-Task:2」が起動される
この場合、動的ポートマッピングの設定は不要だが、起動させるべきタスクの数が多いと単純に手間がかかる
また、どうしてもダウンタイムが発生してしまうと思われる
※タスクを停止した直後は、タスクが終了された方のインスタンスにアクセスされてエラーが表示されることがある
数秒で解消するようだが、本番運用するとなると気になる
CodePipelineでの自動デプロイなら、「新しいタスクが起動されてから、古いタスクへのアクセスが遮断される」となっているようなので問題無いか
■補足3
「新しいデプロイの強制」にチェックを入れると、自動でタスクが差し変わる…はずだが、最初はいつまで経っても変わらなかった(チェックをいれていないときでも、エラーになることがあった)
サービスの「イベント」タブを確認すると、以下のように表示されていた
service Container-Test-Service was unable to place a task because no container instance met all of its requirements.
The closest matching container-instance 2f7dd44c692b4a028183e6d9bb053659 is already using a port required by your task.
For more information, see the Troubleshooting section.
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/troubleshooting.html
以下によると、スペック不足の可能性はありそうだが、クラスターのインスタンスタイプをmicroからsmallにしても変わりなかった
ECS運用のノウハウ - Qiita
https://qiita.com/naomichi-y/items/d933867127f27524686a
[AWS] Amazon ECS(EC2タイプ)のちょっと長めのチュートリアル(第6回) - Qiita
https://qiita.com/VA_nakatsu/items/8e588c693a2f650c2af3
Amazon ECS コンテナインスタンスの要件エラーを解決する
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-container-instance-requirement-error/
今回の場合、動的ポートマッピングを使う必要があった
【図解】ELB + ECSの動的ポートマッピング | DevelopersIO
https://dev.classmethod.jp/articles/dynamic-portmapping-elb-ecs/
ALB + ECSの動的ポートマッピングでローリングアップデートをする - Qiita
https://qiita.com/mochizuki-pg/items/138de08e7a9ea03f241d
イメージ更新時は恐らく
1. Webサーバ用のコンテナを追加で起動する
2. 追加で起動した方のコンテナにトラフィックを移す
3. もともと起動していた方のコンテナを終了させる
という流れのはずだが、1でコンテナを起動しようにも、すでに80番ポートが使われていて起動できない…という現象
この対策に、新しいWebサーバ用のコンテナは 32768-61000 で起動し、ロードバランサーからのアクセスもこのポートに合わせる
これを動的ポートマッピングと呼ぶ
■クラスターのインスタンスタイプを変更する
クラスターを作成する際にEC2のインスタンスタイプを指定するが、ECSの画面内にこの指定を変更する箇所が無い
これはクラスター作成時に実行されるCloudFormationスタックで指定する必要がある
今回は「t2.micro」を「t2.small」に変更するものとする
CloudFormation → スタック → EC2ContainerService-Container-Test-Cluster → 更新
テンプレートの指定
テンプレートの準備: 「現在のテンプレートの使用」が選択されていることを確認する
「次へ」をクリック
スタックの詳細を指定
EcsInstanceType: 「t2.micro」を「t2.small」に変更する
「次へ」をクリック
スタックオプションの設定
「次へ」をクリック
レビュー
「スタックの更新」をクリック
スタックが更新され、数秒で処理が完了した
ただしこの時点では、まだEC2のインスタンスタイプは変更されていない
EC2 → インスタンス
クラスター用のEC2を停止させると、オートスケーリングによって自動的にEC2が起動される(停止させたEC2は自動的に終了される)
起動されたEC2はインスタンスタイプがt2.smallになっていることを確認する
(ただし、停止させてから自動起動が完了するまでは、5〜10分程度タイムラグがあるかもしれないので注意)
Amazon ECSでインスタンスタイプを変更する | DevelopersIO
https://dev.classmethod.jp/articles/ecs-change-instance-type/
ECS(EC2)のインスタンスタイプ変更は要注意 - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/2020/08/05/193842
■環境の削除
上の手順で作成した場合、以下の順番で削除できる
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス
から「Container-Test-Service」を削除
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster
で「クラスターの削除」をクリック
これで関連するCloudFormationとEC2インスタンスも削除される(少し時間がかかる)
Elastic Container Service → Amazon ECS → タスク定義 → Container-Test-Task
からすべてのリビジョンを登録解除(これでタスク定義の一覧からも Container-Test-Task が削除される)
EC2 → ロードバランサー
から「Container-Test-LoadBalancer」を削除
EC2 → ターゲットグループ
から「Container-Test-TargetGroup」を削除
CloudFormation → スタック
CloudFormationを別途手動で作成した場合、必要に応じて別途削除する
また、不要になったセキュリティ認証情報(ロールやポリシー)を削除しておく
■Amazon Elastic Kubernetes Service(Amazon EKS)
※未検証
Amazon EKS(AWS でマネージド Kubernetes を実行)| AWS
https://aws.amazon.com/jp/eks/
EKS入門者向けに「今こそ振り返るEKSの基礎」というタイトルで登壇しました #jawsug_ct | DevelopersIO
https://dev.classmethod.jp/articles/eks_basic/
AWS 、「Amazon EKS Anywhere」の一般提供開始を発表 - ZDNet Japan
https://japan.zdnet.com/article/35176427/
■AWS Fargate
※未検証
AWS Fargate - サーバーやクラスターの管理が不要なコンテナの実行
https://aws.amazon.com/jp/fargate/
AWS Fargateとは? - Qiita
https://qiita.com/riywo/items/1a5b50028542d9bb06cc
AWS FargateとECSの違いは? - Qiita
https://qiita.com/ABCompany1/items/5f3fcea04052415dc875
【全世界のFargateファンに朗報】Fargate利用料が35%〜50%値下げされました! | DevelopersIO
https://dev.classmethod.jp/cloud/aws/fargate-lower-price/
平成最後なのでEC2からECS+Fargateに 置き換えた話 - Speaker Deck
https://speakerdeck.com/marnie/ping-cheng-zui-hou-nafalseteec2karaecs-plus-fargateni-zhi-kihuan-etah...
AWS Fargateを本番運用した所感 - コネヒト開発者ブログ
http://tech.connehito.com/entry/2018/11/21/163534
AWS FargateではなくECS on EC2を選ぶメリット〜コスト編〜 - Uzabase for Engineers
https://tech.uzabase.com/entry/2022/12/01/175423
Fargateには「プラットフォームバージョン」というものがある
できるだけ最新を保つのが良さそう
AWS Fargate プラットフォームのバージョン - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/platform_versions.html
[アップデート] AWS Fargate (ECS)のプラットフォームバージョン “LATEST” が 1.4.0 になりました | DevelopersIO
https://dev.classmethod.jp/articles/fargate-updates-platform-version-1-4-0-to-be-the-latest-version/
Fargateプラットフォーム1.4.0の変更点 - Qiita
https://qiita.com/ryo0301/items/8929761f5df7e1e2e7a0
AWS Fargateのプラットフォームバージョンを1.3.0に固定したつもりが失敗したお話 - Qiita
https://qiita.com/imai_amazia/items/df139425df350be439a8
■CodeCommit
※未検証
AWSがホスティングしているGitリポジトリを利用できる
CodeDeployやCodePipelineなど、AWSの他サービスと連携して自動デプロイプロセスを実現することができる
ただし2017年6月時点では、PullRequest機能が無いなど他のGitサービスと比べると機能は少ない。移行する場合は注意
CodeCommit入門 - Code三兄弟を知る | DevelopersIO
https://dev.classmethod.jp/cloud/aws/codecommit-introduction/
■CodeBuild
イメージのビルドなどを行なえる
実例は「ECR+ECS+Codeシリーズで自動デプロイ」を参照
AWS CodeBuild(継続的スケーリングによるコードのビルドとテスト)| AWS
https://aws.amazon.com/jp/codebuild/
いますぐ使うCodeBuild - Qiita
https://qiita.com/sasasin/items/6e5f7001cba350851d49
■CodeDeploy
※未検証
CodeCommit、S3、GitHubなどに置いたコードを自動デプロイできる
デプロイ方式として「インプレース」「Blue/Green」を選択できる
インプレース ... サーバ内のアプリケーションを更新する
Blue/Green ... インスタンスを新規に立ち上げ、アプリケーションを配置し、ロードバランサーの向け先を変更する
単純なデプロイならCodeDeployで対応できるようだが、複雑なものはCodePipelineを使う必要があるみたい?
AWS CodeDeployとGitHubを連携してEC2に簡単自動デプロイ - Qiita
https://qiita.com/dq-nobuko-takatsuki/items/ba365966ae61e177a4da
AWS CodeDeployを使ってGitHubにあげているリポジトリをデプロイする - ひよっこエンジニアの雑多な日記
https://kimuraysp.hatenablog.com/entry/2017/08/25/001547
CodeDeploy + ALBでEC2に1台ずつデプロイする - Qiita
https://qiita.com/shonansurvivors/items/fb6e8f38008c1167c287
【DOP】CodeDeploy EC2のデプロイの設定について
https://zenn.dev/kenryo/scraps/683cf6fe08f789
AWS CodeDeploy 入門用 インプレースデプロイ | 優技録
https://www.yuulinux.tokyo/7573/
■CodePipeline
CodeCommit を使っても直接 CodeCommit → CodeDeploy でデプロイすることはできない
CodePipeline を使ってデプロイワークフローに沿ってデプロイする
単純なデプロイだけでなく、CodeBuildを使ってビルドを挟んだり, jenkinsと連動してデプロイ前にテストをしたりできる
実例は「ECR+ECS+Codeシリーズで自動デプロイ」を参照
CodePipeline, CodeCommit, CodeDeploy を使ったデプロイ - Qiita
https://qiita.com/ta_ta_ta_miya/items/3d2b13f0f8f6cee47fef
■ECR+ECS+Codeシリーズで自動デプロイ
Codeシリーズを使ってECRからECSに自動デプロイする
おおまかな方針は以下のとおり
・プログラムのリポジトリにはBitbucketを使用する
・イメージのリポジトリにはECRを使用する
・環境は ECS + EC2 を使用する
・プログラムが更新されたら、CodeBuildで自動的にイメージをビルドしてECRにプッシュする
・デプロイは Amazon ECS 標準デプロイを使用する
・更新の検知〜ビルド〜デプロイは、CodePipelineで処理する
手順が長いので、以下に分割して記載する
■ECR+ECS+Codeシリーズで自動デプロイ: ベースイメージを登録
Dockerhubの制限やサーバダウンに影響を受けないように、ベースイメージをAWSで管理する
■ベースイメージの作成
Elastic Container Registry → リポジトリを作成
以下の内容でリポジトリを作成
可視性設定: プライベート
リポジトリ名: base_php74_apache
タグのイミュータビリティ: 有効
「リポジトリを作成」ボタンを押すとリポジトリが作成される
引き続き、リポジトリにプッシュするイメージを作成する
docker\base_php74_apache\code\html\index.php
<h1>base_php74_apache</h1>
<p>php:7.4-apache</p>
docker\base_php74_apache\Dockerfile
FROM php:7.4-apache
COPY code/html /var/www/html
$ docker image build -t php:base_php74_apache docker/base_php74_apache
$ docker image ls
以下で起動する
$ docker container run --name base_php74_apache -p 80:80 -d php:base_php74_apache
$ docker container exec -it base_php74_apache bash
# ls /var/www/html
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker container ls
$ docker container rm -f 6f986c913818
タグ「1.0.0」を付けてプッシュする
$ cd docker/base_php74_apache
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t base_php74_apache .
$ docker image tag base_php74_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php74_apache:1.0.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php74_apache:1.0.0
ECRでリポジトリ名 base_php74_apache をクリックし、イメージタグとして「1.0.0」が現れていることを確認する
■ベースイメージの利用確認
Docker Composeでの起動を試す
docker\ecr_php74_apache\docker\docker-compose.yml
version: '3'
networks:
compose_network:
driver: bridge
services:
php:
container_name: php
volumes:
- ./php/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ..:/var/www:rw
environment:
TZ: Asia/Tokyo
ports:
- 80:80
networks:
- compose_network
build: ./php
docker\ecr_php74_apache\docker\php\Dockerfile
FROM 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php74_apache:1.0.0
RUN apt-get update
RUN apt-get install -y \
libicu-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libonig-dev \
libzip-dev
RUN docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/
RUN docker-php-ext-install gd mbstring intl zip
RUN a2enmod rewrite
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN usermod -u 1000 www-data && \
groupmod -g 1000 www-data
docker\ecr_php74_apache\docker\php\php.ini
date.timezone = Asia/Tokyo
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = pass
mbstring.http_output = pass
mbstring.encoding_translation = Off
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
mbstring.substitute_character = none
mbstring.func_overload = 0
mbstring.strict_detection = Off
docker\ecr_php74_apache\html\index.php
<h1>ecr_php74_apache</h1>
<p>123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php74_apache:1.0.0</p>
ファイルを用意できたら以下で起動する
$ cd docker/ecr_php74_apache/docker
$ docker-compose build
$ docker-compose up -d
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker-compose down
■ECR+ECS+Codeシリーズで自動デプロイ: デプロイ用イメージを登録
■プログラムをイメージに含める
※ビルド時間を短くするために、PHPのインストールなどを終えた状態のものをベースイメージとして管理する方がいいかもしれない
もしくは「ベースイメージ」「PHPのインストールなどを終えたイメージ」「プログラムも含めたイメージ」を作成し、
以降は原則「プログラムも含めたイメージ」のみを更新していくか
※Dockerfileの内容は、本当にこれでいいのかは、改めて確認したい
Dockerfileでコピーしたうえで、docker-compose.ymlでファイル同期する…という仕組みにしているが、二重に共有しているのは微妙な気がする
プログラムをイメージに含めるようにDockerfileを修正する
また、Dockerfile内から上階層のファイルを参照できるように、docker-compose.ymlでbuildの設定を調整する
ローカルでの開発に難が出ないように、ボリュームの同期は無くさずに置いておく
docker\ecr_php74_apache\docker\php\Dockerfile の最後に以下を追加
COPY docker/php/php.ini /usr/local/etc/php/conf.d/php.ini
COPY . /var/www
docker\ecr_php74_apache\docker\docker-compose.yml のbuild部分を調整
build: ./php
↓
build:
context: ../
dockerfile: ./docker/php/Dockerfile
起動を確認しておく
$ cd docker/ecr_php74_apache/docker
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
■イメージをプッシュ
※AWSコンソールで作業
Elastic Container Registry → リポジトリを作成
※初めてアクセスした場合、まずは「使用方法」をクリックすると「リポジトリを作成」と同じ画面が表示される
以下の内容でリポジトリを作成(いったん、リポジトリ名を入力する以外は初期値で作成してみる)
なお、「可視性設定」と「リポジトリ名」は後から変更できない
可視性設定: プライベート
リポジトリ名: ecr_php74_apache
タグのイミュータビリティ: 有効
「リポジトリを作成」ボタンを押すとリポジトリが作成される
作成したリポジトリに、タグ「1.0.0」を付けてプッシュする
$ cd docker/ecr_php74_apache
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t ecr_php74_apache -f docker/php/Dockerfile .
$ docker image tag ecr_php74_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:1.0.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:1.0.0
ECRでリポジトリ名 ecr_php74_apache をクリックし、イメージタグとして「1.0.0」が現れていることを確認する
Docker Composeでの起動も試しておく
docker\ecr_compose_test\docker-compose.yml
version: '3'
networks:
compose_network:
driver: bridge
services:
php:
container_name: ecr_php74_apache
ports:
- 80:80
networks:
- compose_network
image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:1.0.0
ファイルを用意できたら以下で起動する
$ cd docker/ecr_compose_test
$ docker-compose build
$ docker-compose up -d
http://localhost/ にアクセスし、phpinfo() の内容が表示されることを確認する
$ docker-compose down
■ECSで手動構築
「Amazon Elastic Container Service(Amazon ECS)」の内容をもとに、以下の指定でECS環境を作ることはできた
コンテナ名: ecr_php74_apache
イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:1.0.0
なお今回、参照するコンテナ名が ecr_test から ecr_php74_apache に変わるので、サービス自体を作り直した
サービスを作り直すとき、すべてのタスクを止めてからでないと以下のエラーになるようなので注意
サービスの作成: Container-Test-Service
サービスの作成に失敗しました
サービス 作成に失敗: Unable to Start a service that is still Draining.
■ECR+ECS+Codeシリーズで自動デプロイ: CodeBuildでデプロイ用イメージを自動ビルド
上にある「ECR+ECS+Codeシリーズで自動デプロイ: ベースイメージを登録」からの続き
主に以下の書籍を参考に検証中
CodeシリーズはP.335から(ただし以降の手順では、FargateではなくEC2を使用している)
AWSコンテナ設計・構築[本格]入門 | SBクリエイティブ
https://www.sbcr.jp/product/4815607654/
GitHub - uma-arai/sbcntr-resources: 書籍用の各種リソースのダウンロードリポジトリ
https://github.com/uma-arai/sbcntr-resources
■前提
ベースイメージは、先の手順で作成した以下を使うものとする
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php74_apache:1.0.0
そのイメージをもとに、先の手順でプログラムも含めたApache+PHPの環境を作成した
ecr_php74_apache
以下で起動&終了でき、
http://localhost/ にアクセスできることを確認した
$ cd docker/ecr_php74_apache/docker
$ docker-compose build
$ docker-compose up -d
$ docker-compose down
■準備: Bitbucketアプリパスワードの作成
今回はBitbucketからデプロイするので、以下を参考にアプリパスワードを発行しておく
アプリ パスワード | Bitbucket Cloud | アトラシアン サポート
https://support.atlassian.com/ja/bitbucket-cloud/docs/app-passwords/
個人設定 → アクセス管理 → アプリパスワード
Label: ECS
権限: 「リポジトリ 読み取り」のみ
「作成」をクリックするとアプリパスワードが表示されるので控えておく
■準備: IAMポリシーの作成
セキュリティ認証情報 → ポリシー → ポリシーの作成
「JSON」タブに以下を入力する
AWSアカウントID(123456789012)とイメージ名(base_php74_apache と ecr_php74_apache)は、環境に合わせて調整する
イメージ名は、
ベースイメージを参照するためのリポジトリ(base_php74_apache)と、
ビルド済みイメージを保存するためのリポジトリ(ecr_php74_apache)を、
それぞれ2箇所で指定する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListImagesInRepository",
"Effect": "Allow",
"Action": [
"ecr:ListImages"
],
"Resource": [
"arn:aws:ecr:ap-northeast-1:123456789012:repository/base_php74_apache",
"arn:aws:ecr:ap-northeast-1:123456789012:repository/ecr_php74_apache"
]
},
{
"Sid": "GetAuthorizationToken",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Sid": "ManageRepositoryContents",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": [
"arn:aws:ecr:ap-northeast-1:123456789012:repository/base_php74_apache",
"arn:aws:ecr:ap-northeast-1:123456789012:repository/ecr_php74_apache"
]
}
]
}
「次のステップ:タグ」をクリック
そのまま「次のステップ:確認」をクリック
ポリシーの作成画面になるので以下を入力
名前: Container-Test-AccessingECRRepositoryPolicy
説明: Policy to access ECR repo
「ポリシーの作成」をクリック
なお、上記のコードは書籍のサポートページ掲載されている
sbcntr-resources/cloud9_ecr_policy.json at main - uma-arai/sbcntr-resources
https://github.com/uma-arai/sbcntr-resources/blob/main/iam/cloud9_ecr_policy.json
AWS公式サイトにも掲載されている(「Accessing One Amazon ECR Repository」の部分)
Amazon Elastic Container Registry Identity-Based Policy Examples - Amazon ECR
https://docs.aws.amazon.com/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html
■CodeBuild用ファイル作成
アプリケーションリポジトリのルートディレクトリに、以下をもとに作成したファイルを、コミット&プッシュしておく
https://github.com/uma-arai/sbcntr-resources/blob/main/cicd/buildspec.yml
…のが一般的な配置のようだが、今回は以下に配置してみる(Dockerに関するファイルは docker フォルダにまとめる)
このファイルはコミット&プッシュし、アプリケーションのリポジトリに含めておく
docker\ecr_php74_apache\docker\buildspec.yml
version: 0.2
env:
variables:
AWS_REGION_NAME: ap-northeast-1
ECR_REPOSITORY_NAME: ecr_php74_apache
DOCKER_BUILDKIT: "1"
phases:
install:
runtime-versions:
docker: 19
pre_build:
commands:
- AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
- aws ecr get-login-password --region ${AWS_REGION_NAME} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION_NAME}.amazonaws.com
- REPOSITORY_URI=${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION_NAME}.amazonaws.com/${ECR_REPOSITORY_NAME}
- IMAGE_TAG=$(echo ${CODEBUILD_RESOLVED_SOURCE_VERSION} | cut -c 1-7)
build:
commands:
- docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} -f docker/php/Dockerfile .
post_build:
commands:
- docker image push ${REPOSITORY_URI}:${IMAGE_TAG}
- printf '[{"name":"%s","imageUri":"%s"}]' $ECR_REPOSITORY_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files:
- imagedefinitions.json
imagedefinitions.json というファイル名が2箇所あるが、これはビルド結果をCodeDeployに渡すためのもの
ファイル名は
・Amazon ECS 標準デプロイには imagedefinitions.json がデフォルト
・Amazon ECS Blue/Green デプロイでは imageDetail.json がデフォルト
となっているので、原則これに合わせておくといい
また imageDetail.json の場合、printf 内の「[{"name":"%s","imageUri":"%s"}]」は「{"name":"%s","ImageURI":"%s"}」となるので注意
イメージ定義ファイルのリファレンス - AWS CodePipeline
https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/file-reference.html
また、一例だが post_build 部分を以下のようにすると、イメージをプッシュする直前の諸々の情報が、CodeBuildのコンソールに出力されるようになる
デバッグの一手段として
post_build:
commands:
- echo Build completed on `date`
- echo ${AWS_REGION_NAME}
- echo ${ECR_REPOSITORY_NAME}
- echo ${DOCKER_BUILDKIT}
- echo ${AWS_ACCOUNT_ID}
- echo ${REPOSITORY_URI}
- echo ${IMAGE_TAG}
- echo '[{"name":"%s","imageUri":"%s"}]' $ECR_REPOSITORY_NAME $REPOSITORY_URI:$IMAGE_TAG
- docker image push ${REPOSITORY_URI}:${IMAGE_TAG}
- printf '[{"name":"%s","imageUri":"%s"}]' $ECR_REPOSITORY_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
■CodeBuild設定
※今回はCodeCommitではなく、Bitbucketからデプロイする
※「Container-Test」というパイプライン名は、実際は案件名と環境をもとに付けると良さそう
CodeBuild → ビルドプロジェクトを作成する
プロジェクトの設定
プロジェクト名: Container-Test
ビルドバッジ: (「ビルドバッジを有効にする」にチェックを入れる)
ソース
ソースプロバイダ: Bitbucket
リポジトリ: Bitbucketアプリパスワードで接続する
Bitbucketユーザー名: refirio
Bitbucketのアプリパスワード: 9jzJ4nHrLp395xTzjgdX ※入力したら「Bitbucket認証情報の保存」ボタンをクリックし、Bitbucketに接続できることを確認する
リポジトリのURL:
https://bitbucket.org/refirio/ecr_php74_apache.git(Bitbucketに接続すると入力欄が表示される)
ソースバージョン: master
環境
環境イメージ: マネージド型イメージ
オペレーティングシステム: Amazon Linux 2
ランタイム: Standard
イメージ: aws/codebuild/amazonlinux2-x86_64-standard:3.0
イメージのバージョン: このランタイムバージョンには常に最新のイメージを使用してください
特権付与: (「Docker イメージを構築するか、ビルドで昇格されたアクセス権限を取得するには、このフラグを有効にします。」にチェックを入れる)
サービスロール: 新しいサービスロール
ロール名: Container-Test-CodeBuild-Role
Buildspec
ビルド仕様: buildspecファイルを使用する
Buildspec名: docker/buildspec.yml
アーティファクト
タイプ: アーティファクトなし
キャッシュタイプ: ローカル
少なくとも 1 つのオプションを選択してください。:(「DockerLayerCache」のみにチェックを入れる)
ログ
CloudWatch:(「CloudWatch Logs」にチェックを入れる)
「ビルドプロジェクトを作成する」ボタンをクリック
■ロールにアクセス権限を付与
CodeBuild → ビルドプロジェクト
作成したプロジェクトをクリックし、「ビルド開始」をクリック
…としても、現時点では以下のエラーになる
CodeBuildを設定する際に Container-Test-CodeBuild-Role というロールを作ったが、このロールにアクセス権限を与えていないため
[Container] 2022/01/19 11:37:34 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache. Reason: exit status 1
「準備: IAMポリシーの作成」で作成したポリシーを紐づける
セキュリティ認証情報 → ロール
先の手順中で作成した Container-Test-CodeBuild-Role を選択
「アクセス許可を追加 → ポリシーをアタッチ」をクリック
上の手順中で作成した Container-Test-AccessingECRRepositoryPolicy にチェックを入れ、「ポリシーのアタッチ」ボタンをクリック
■CodeBuild実行
CodeBuild → ビルドプロジェクト → Container-Test
画面上部にある「ビルド開始」ボタンをクリック
しばらく待つと最後に以下のようなログが表示され、ビルドが完了した
[Container] 2022/01/21 03:18:23 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2022/01/21 03:18:23 Phase context status code: Message:
[Container] 2022/01/21 03:18:23 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2022/01/21 03:18:23 Phase context status code: Message:
ビルドする内容によると思われるが、今回は2〜3分程度で完了した
ECRのリポジトリ ecr_php74_apache を確認すると、660918c というタグが指定されたイメージを確認できる
(buildspec.yml の内容に従って、Bitbucketのコミットしたときに発行されたハッシュの下7桁がタグ名に使われる)
作成された以下のイメージを使用して、新しいタスクとしてECSに反映できることを確認する
123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:660918c
※タグの上書き禁止設定(タグのイミュータビリティ)を有効にしている場合、
後の手順でエラーにならないように、この時点でリポジトリに何かしらの変更を加えておくといい
■ビルドエラー
以下などが参考になりそう
CodeBuildでECRビルドエラーから得た4つの知見 - Qiita
https://qiita.com/icck/items/bcf118a38c2a691a837d
AWS CodeBuildを使ってDockerイメージをビルドし、Amazon EC2 Container Registry(ECR)へpushする | DevelopersIO
https://dev.classmethod.jp/articles/20170225-codebuild-docker/
AWS CodeBuildでDockerビルドしてECRへプッシュする - け日記
https://ohke.hateblo.jp/entry/2020/09/26/230000
■ビルドエラー: 具体例1
「ビルド開始」をクリックする
しばらく待つと、以下のエラーで止まった
[Container] 2022/01/20 06:31:27 Running command docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} .
failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial unix /var/run/docker.sock: connect: no such file or directory
エラーメッセージで調べると、特権を有効にする必要があるらしい
CodeBuildでDocker in Dockerする - Qiita
https://qiita.com/reireias/items/c02e5e7b2f099f2dab9e
プロジェクトを選択し、「編集 → 環境 → イメージの上書き」として「特権付与」の項目を確認すると、チェックを入れ忘れていた
チェックを入れて「環境を更新」ボタンを押す
■ビルドエラー: 具体例2
「ビルド開始」をクリックする
しばらく待つと、以下のエラーで止まった
[Container] 2022/01/20 07:26:20 Entering phase BUILD
[Container] 2022/01/20 07:26:20 Running command docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} .
#1 [internal] load build definition from Dockerfile
#1 sha256:25a25a7aeafc92304eb63ea0db9f200c3253075e86ba57c7dac9663fd44d2194
#1 transferring dockerfile: 2B done
#1 DONE 0.1s
#2 [internal] load .dockerignore
#2 sha256:f9f7891f650ee769119b4b75aaaa3c7e5037b200eb42f86391868e95a0a17f8a
#2 transferring context: 2B done
#2 DONE 0.1s
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount854683111/Dockerfile: no such file or directory
[Container] 2022/01/20 07:26:20 Command did not exit successfully docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} . exit status 1
[Container] 2022/01/20 07:26:20 Phase complete: BUILD State: FAILED
[Container] 2022/01/20 07:26:20 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} .. Reason: exit status 1
Dockerfileを読み込めないとなっている
以下のようにパスを調整
docker\ecr_php74_apache\docker\buildspec.yml
- docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} .
↓
- docker image build -t ${REPOSITORY_URI}:${IMAGE_TAG} -f docker/php/Dockerfile .
■ビルドエラー: 具体例3
「ビルド開始」をクリックする
しばらく待つと、以下のエラーで止まった
[Container] 2022/01/20 07:57:40 Entering phase POST_BUILD
[Container] 2022/01/20 07:57:40 Running command docker image push ${REPOSITORY_URI}:${IMAGE_TAG}
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache]
4906f6f3890c: Preparing
2fee96bd8066: Preparing
280952099e51: Preparing
〜中略〜
4906f6f3890c: Retrying in 1 second
7173e6f39ae9: Retrying in 1 second
280952099e51: Retrying in 1 second
2fee96bd8066: Retrying in 1 second
EOF
[Container] 2022/01/20 07:58:30 Command did not exit successfully docker image push ${REPOSITORY_URI}:${IMAGE_TAG} exit status 1
[Container] 2022/01/20 07:58:30 Phase complete: POST_BUILD State: FAILED
[Container] 2022/01/20 07:58:30 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker image push ${REPOSITORY_URI}:${IMAGE_TAG}. Reason: exit status 1
IAMポリシーで指定するリポジトリの名前が間違っていたので修正
■ビルドエラー: 具体例4
「ビルド開始」をクリックする
しばらく待つと、以下のエラーで止まった
tag invalid: The image tag '6abc7d3' already exists in the 'ecr_php74_apache' repository and cannot be overwritten because the repository is immutable.
[Container] 2022/02/08 02:32:30 Command did not exit successfully docker image push ${REPOSITORY_URI}:${IMAGE_TAG} exit status 1
[Container] 2022/02/08 02:32:30 Phase complete: POST_BUILD State: FAILED
[Container] 2022/02/08 02:32:30 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker image push ${REPOSITORY_URI}:${IMAGE_TAG}. Reason: exit status 1
[Container] 2022/02/08 02:32:30 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2022/02/08 02:32:30 Phase context status code: Message:
タグの上書き禁止設定(タグのイミュータビリティ)を有効にしていて、すでにビルド済みのイメージが存在するためだった
リポジトリに変更を加えてから再度ビルドするか、ビルド済みのイメージを削除してから再度ビルドする
■ECR+ECS+Codeシリーズで自動デプロイ: CodePipelineでイメージを自動デプロイ
■タスク定義ファイル作成
Elastic Container Service → Amazon ECS → タスク定義 → Container-Test-Task
最新のリビジョンのページ内で「JSON」タブに表示される内容をもとに作る
その際、イメージの指定部分を「"image": "<IMAGE1_NAME>",」に調整し、さらに以下の項目を削除する
・taskDefinitionArn
・revision
・status
・requiresAttributes
・compatibilities
また動的ポートマッピングのために、hostPortは「0」にしておく(もとからそうなっているなら問題無い)
"portMappings": [
{
"hostPort": 80,
↓
"hostPort": 0,
describe で出力した ECS タスク定義をさくっと登録可能な形に整形する | Stuck inside
https://blog.msysh.me/posts/2020/12/transform_task_definition_by_describe_to_be_able_to_register.htm...
describe-task-definitionで取得したJSONはそのままではregister-task-definitionで登録できないお話 | DevelopersIO
https://dev.classmethod.jp/articles/describe-task-definition-to-register-task-definition/
内容は異なるが、以下は参考までにファイル内容の具体例
sbcntr-resources/taskdef.json at main - uma-arai/sbcntr-resources
https://github.com/uma-arai/sbcntr-resources/blob/main/cicd/taskdef.json
このファイルはコミット&プッシュし、アプリケーションのリポジトリに含めておく
リポジトリ直下に配置するのが一般的かもしれないが、今回は以下に配置してみる(Dockerに関するファイルは docker フォルダにまとめる)
値がnullの項目は削除できるかもしれないが、そのままでも支障はないはず
参考までに、以下は実際に登録した内容
docker\ecr_php74_apache\docker\taskdef.json
{
"ipcMode": null,
"executionRoleArn": null,
"containerDefinitions": [
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": null,
"entryPoint": null,
"portMappings": [
{
"hostPort": 0,
"protocol": "tcp",
"containerPort": 80
}
],
"command": null,
"linuxParameters": null,
"cpu": 0,
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": null,
"dockerSecurityOptions": null,
"memory": 128,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "<IMAGE1_NAME>",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "ecr_php74_apache"
}
],
"placementConstraints": [],
"memory": null,
"taskRoleArn": null,
"family": "Container-Test-Task",
"pidMode": null,
"requiresCompatibilities": [
"EC2"
],
"networkMode": null,
"runtimePlatform": null,
"cpu": null,
"inferenceAccelerators": null,
"proxyConfiguration": null,
"volumes": []
}
■CodePipelineを作成
※「Container-Test」というパイプライン名は、実際は案件名と環境をもとに付けると良さそう
CodePipeline → パイプライン → パイプラインを作成する
パイプラインの設定を選択する
パイプライン名: Container-Test
サービスロール: 新しいサービスロール
ロール名: AWSCodePipelineServiceRole-ap-northeast-1-Container-Test(パイプライン名を入力すると、自動で入力された / パイプラインを再作成する場合、以前作成したものを選択した)
「次に」ボタンをクリック
ソースステージを追加する
ソースプロバイダー: Bitbucket
接続: Bitbucketに接続(パイプラインを再作成する場合、以前作成したものを選択した)
接続名: Container-Test ※この接続名は、本番・検収・開発で共通して使う想定で良さそう
「Bitbucketに接続」ボタンをクリック
Bitbucketへのログインを求められるのでログイン
以下の許可を求められるので許可する
AWS CodeStar is requesting access to the following:
・アカウント情報の読み取り
・あなたの所属するチーム情報を読み取る
「接続」ボタンをクリック
Bitbucketアプリ: 「新しいアプリをインストールする」ボタンをクリック
アクセスの許可を求められるので許可
以下の許可を求められるので許可する
AWS CodeStar requests access
・アカウント情報の読み取り
・リポジトリとそのプルリクエストを確認する
・自分のリポジトリの管理
・リポジトリを確認し修正する
Authorize for workspace: refirio(対象のリポジトリがあるプロジェクトを選択する)
「アクセスを許可する」ボタンをクリック
「接続」ボタンをクリック
もとの画面に戻って「接続する準備が完了しました」と表示されることを確認する
リポジトリ名: refirio/ecr_php74_apache
ブランチ名: master
検出オプションを変更する: 「ソースコードの変更時にパイプラインを開始する」にチェックを入れる
出力アーティファクト形式: CodePipeline のデフォルト
「次に」ボタンをクリック
ビルドステージを追加する
プロバイダーを構築する: AWSCodeBuild
リージョン: アジアパシフィック(東京)
プロジェクト名: Container-Test(選択対象に表示されるので選択する)
ビルドタイプ: 単一ビルド
「次に」ボタンをクリック
デプロイステージを追加する
デプロイプロバイダー: Amazon ECS
リージョン: アジアパシフィック(東京)
クラスター名: Container-Test-Cluster
サービス名: Container-Test-Service
イメージ定義ファイル: imagedefinitions.json
「次に」ボタンをクリック
レビュー
「パイプラインを作成する」ボタンをクリック
「成功」と表示されるのを確認する
引き続き、各処理がそれぞれ実行されていくのを確認する
「Source」はすぐに「成功しました」となった
その2〜3分後くらいに、「Build」が「成功しました」となった
その7〜8分後くらいに、「Deploy」が「成功しました」となった
合計10分ほどでデプロイが完了したが、本番反映自体は3〜4分ほどでされていた(以降は不要なタスクやターゲットグループの削除)
どんなにイメージのビルド時間を短くしても、デプロイ完了までは5〜6分程度かかるかもしれない(デプロイ時間については、後述の「デプロイ時間の短縮」も参照)
以降は、プログラムの修正をmasterブランチにコミット&プッシュするだけで、処理が開始されデプロイされる
(developブランチの内容をmasterにマージ&プッシュとしても、同様に処理される)
なお、本番反映時に30秒程度、新旧が混在する状態が続く
これは恐らく標準デプロイ(ローリングアップデート)の仕様で、避けるためにはBlue/Greenデプロイにする必要があると思われる
taskdef.json の内容はリポジトリに含めているので、ローカルで編集してコミット&プッシュすることで、タスク定義の内容を変更できる
…かと思いきや、その流れでは変更が反映されなかった(AWSコンソールで値を変更してはじめて反映される)
そういうものかもしれないが、釈然としないのでまた調査しておきたい
■問題の修正1
「Build」で「失敗しました」となった
詳細から「実行の詳細へのリンク」を表示すると、以下が表示される
[Container] 2022/02/02 10:37:42 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: docker image push ${REPOSITORY_URI}:${IMAGE_TAG}. Reason: exit status 1
イメージのプッシュができなかったみたい
すでに指定のタグ名でイメージがビルド&プッシュ済みになっているからだった
(タグの上書きを禁止している)
リポジトリでプログラムを微調整してコミット&プッシュしてみる
パイプラインが「進行中」になった
CodeBuildの画面でも「進行中」になっているので、詳細を見つつ見守る
今度はビルドが成功した
■問題の修正3
「Deploy」で「失敗しました」となった
詳細を表示すると、以下が表示される
無効なアクション設定
The image definition file imagedefinitions.json contains invalid JSON format
docker/buildspec.yml に記述ミスがあったので修正して再実行したところ、デプロイも進むようになった
「詳細」をクリックすると Container-Test-Service に遷移した
「デプロイメント」を確認すると、すぐに完了していた
「イベント」を確認すると「service Container-Test-Service was unable to place a task because no container instance met all of its requirements. The closest matching container-instance 653f223309c54e67b32b21e6ea8e8408 is already using a port required by your task. For more information, see the Troubleshooting section.」と表示されていた
しばらくして「タスク定義」と「サービス」を確認すると、更新されていた
ただし、いつまで待っても「タスク」が置き換わらなかった
■問題の修正4
15分以上待っても「タスク」が置き換わらなかったので「停止して中止」にした
CodePipelineなしでも発生していたものと同じ現象だったので、動的ポートマッピングを設定すると完了できた
動的ポートマッピングに対応した taskdef.json をコミットしてもデプロイできない場合、
あらかじめAWSコンソール上で動的ポートマッピングに対応させてデプロイを行っておいてから再度試す
(デプロイ前の時点で動的ポートマッピングに対応している必要があるかもしれない)
■ECR+ECS+Codeシリーズで自動デプロイ: 環境変数を渡す
■機密情報以外の環境変数を渡す
Elastic Container Service → Amazon ECS → タスク定義
「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック
(以下、前回タスクを作成した時の内容をベースに入力する)
もともと追加されている「ecr_php74_apache」をクリックし、必要な箇所を調整
環境
基本: (チェックを入れたままにする)
環境変数
Key Value/ValueFrom 値
TEST_VALUE1 Value TEST
TEST_VALUE2 Value テストメッセージ!
TEST_VALUE3 Value This is a test message!
上記で更新すると、各値がコンテナに渡される
各値は環境変数に格納されるので、例えばPHPの場合は以下のようにすると参照できる
echo $_ENV['TEST_VALUE1'];
■機密情報を渡す
RDSへの接続情報などを渡したい場合、Secrets Managerを使用する
AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 - Qiita
https://qiita.com/tomoya_oka/items/a3dd44879eea0d1e3ef5
■ECR+ECS+Codeシリーズで自動デプロイ: RDSに接続する
■RDSパラメータグループの作成
パラメータグループファミリー: mariadb10.5
グループ名: container-test-parameter
説明: for Container-Test
■RDSパラメータグループの設定
character_set_client: utf8mb4
character_set_connection: utf8mb4
character_set_database: utf8mb4
character_set_results: utf8mb4
character_set_server: utf8mb4
init_connect: SET SESSION time_zone = CASE WHEN POSITION('rdsadmin@' IN CURRENT_USER()) = 1 THEN 'UTC' ELSE 'Asia/Tokyo' END;
■RDSの作成
データベース作成方法を選択: 標準作成
エンジンのオプション: MariaDB
バージョン: MariaDB 10.5.13
テンプレート: 開発/テスト
DBインスタンス識別子: container-test
マスターユーザー名: admin
マスターパスワード: qazwsxedc
DBインスタンスクラス: バースト可能クラス(t クラスを含む)
db.t3.micro
ストレージタイプ: 汎用(SSD)
ストレージ割り当て: 20GiB
マルチAZ配置: なし
Virtual Private Cloud: Container
既存のVPCセキュリティグループ: Container-DBSecurityGroup
最初のデータベース名: container
DBパラメータグループ: container-test-parameter
オプショングループ: default:mariadb-10-5
■Cloud9を作成
RDSにユーザやテーブルを作成するため、Cloud9を作成する
(運用はコンテナなので、作業用にEC2を作成する…が、一時的に必要になるだけなのでCloud9を使う)
Name: Test
Description: (空欄のまま)
Environment type: Create a new EC2 instance for environment (direct access)
Instance type: t2.micro (1 GiB RAM + 1 vCPU)
Platform: Amazon Linux 2 (recommended)
Cost-saving setting: After 30 minutes (default)
IAM role: AWSServiceRoleForAWSCloud9
Network (VPC): Container ※コンテナ用のVPCを選択
Subnet: Container-Public-A ※外部からアクセスできる(Publicな)サブネットを選択
■RDSへの接続を許可
Cloud9のEC2には、以下のセキュリティグループが自動で割り当てられていた
sg-04b8e304c2064b14d
RDSに割り当てられたセキュリティグループのインバウンドルールで、
このセキュリティグループからのアクセスを許可する
Cloud9からは、以下のようにして接続できる(mysqlはデフォルトでインストール済みだった)
パスワードを入力しても、いつまで経っても結果が返ってこない場合、セキュリティグループの設定が正しいか確認する
$ mysql --version
mysql Ver 15.1 Distrib 10.2.38-MariaDB, for Linux (x86_64) using EditLine wrapper
$ mysql -h container-test.c40sfbd72bsp.ap-northeast-1.rds.amazonaws.com -u admin -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 16
Server version: 10.5.13-MariaDB managed by
https://aws.amazon.com/rds/
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 10.5.13-MariaDB |
+-----------------+
1 row in set (0.00 sec)
AWS Cloud9 環境を作成してAmazon Aurora Serverless MySQL データベースに接続する | DevelopersIO
https://dev.classmethod.jp/articles/amazon-aurora-serverlessmysql-cloud9/
■RDSに作業ユーザを作成
> CREATE USER webmaster IDENTIFIED BY 'qazwsxedc';
> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, EVENT ON container.* TO webmaster;
> FLUSH PRIVILEGES;
> QUIT;
■RDSへの作業ユーザでの接続を確認&テーブルを作成
$ mysql -h container-test.c40sfbd72bsp.ap-northeast-1.rds.amazonaws.com -u webmaster -p
Enter password:
> CREATE TABLE table_test(
> id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
> text VARCHAR(255) NOT NULL COMMENT 'テキスト',
> PRIMARY KEY(id)
> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'テスト';
> INSERT INTO table_test(text) VALUES('Test1');
> INSERT INTO table_test(text) VALUES('Test2');
> SELECT * FROM table_test;
+----+-------+
| id | text |
+----+-------+
| 1 | Test1 |
| 2 | Test2 |
+----+-------+
2 rows in set (0.00 sec)
■Secrets ManagerにRDSへの接続情報を登録
※taskdef.json 内に(つまりアプリケーションのリポジトリ内に)機密情報を記載しなくていいようにする
Secrets Manager → 新しいシークレットを保存する
シークレットのタイプを選択
シークレットのタイプ: Amazon RDS データベースの認証情報
ユーザー名: (RDS上に作成したユーザー)
パスワード: (RDS上に作成したパスワード)
暗号化キー: aws/secretmanager (初回は「DefaultEncryptionKey」を選択するといい)
データベース: container-test (作成したRDS)
「次」ボタンをクリック
シークレットを設定
シークレットの名前: dev/container-test/Mysql
「次」ボタンをクリック
ローテーションを設定 - オプション
自動ローテーション: OFF
「次」ボタンをクリック
レビュー
「保存」ボタンをクリック
■ポリシーの作成
※ECSからSecrets Managerの情報を取得するためのポリシーを作成する
セキュリティ認証情報 → ポリシー → ポリシーの作成
「JSON」タブに以下を入力する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetSecretForECS",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": ["*"]
}
]
}
「次のステップ:タグ」をクリック
そのまま「次のステップ:確認」をクリック
ポリシーの作成画面になるので以下を入力
名前: Container-Test-GettingSecretForECS
説明: Policy to get Secret for ECS
「ポリシーの作成」をクリック
なお、上記のコードは書籍のサポートページ掲載されている
sbcntr-resources/secrets_policy.json at main - uma-arai/sbcntr-resources - GitHub
https://github.com/uma-arai/sbcntr-resources/blob/main/iam/secrets_policy.json
■タスク実行ロールの作成
※ECSがタスクを実行するときのロールを作成する
セキュリティ認証情報 → ロール → ロールを作成
信頼されたエンティティを選択
信頼されたエンティティタイプ: AWS のサービス
ユースケース
他の AWS のサービスのユースケース:
Elastic Container Service → Elastic Container Service Task を選択
「次へ」ボタンをクリック
許可を追加
「AmazonECSTaskExecutionRolePolicy」を検索してチェックを入れる
「次へ」ボタンをクリック
名前、確認、および作成
ロール名: ecsTaskExecutionRole
「ロールを作成」ボタンをクリック
Amazon ECS タスク実行IAM ロール - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_execution_IAM_role.html#creat...
ECSのタスクロールとタスク実行ロールの違い - karakaram-blog
https://www.karakaram.com/difference-between-ecs-task-role-and-task-execution-role/
■タスク実行ロールにアクセス権限を付与
※ECSがタスクを実行するとき、Secrets Managerの情報を取得できるように権限を付与する
セキュリティ認証情報 → ロール
先の手順中で作成した ecsTaskExecutionRole を選択
「アクセス許可を追加 → ポリシーをアタッチ」をクリック
上の手順中で作成した Container-Test-GettingSecretForECS にチェックを入れ、「ポリシーのアタッチ」ボタンをクリック
■Secrets Managerの情報を読み込ませるためにタスクを更新
Elastic Container Service → Amazon ECS → タスク定義
「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック
(以下、前回タスクを作成した時の内容をベースに入力する)
タスク定義名: Container-Test-Task
タスクロール: なし
ネットワークモード: <default>
タスク実行ロール: ecsTaskExecutionRole
もともと追加されている「ecr_php74_apache」をクリックし、必要な箇所を調整
コンテナ名: ecr_php74_apache
イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php74_apache:82559d5
プライベートレジストリの認証: (チェックしない)
メモリ制限 (MiB): ハード制限 128
ポートマッピング:
ホストポート: 0 ※通常は80だが、動的ポートマッピングを利用するため0に設定する
コンテナポート: 80
プロトコル: tcp
環境
基本: (チェックを入れたままにする)
環境変数
Key Value/ValueFrom 値
DB_HOST ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:host::
DB_NAME ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:dbname::
DB_USERNAME ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:username::
DB_PASSWORD ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:password::
「更新」をクリック
「作成」をクリック
「タスク定義 Container-Test-Task: 3 の新しいリビジョンを正常に作成しました」と表示された
次にサービスを更新して新しいリビジョンを選択する
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → 更新
サービスの設定
タスク定義
リビジョン: 3 (latest)
新しいデプロイの強制: チェックを付ける
タスクの配置
配置テンプレート: AZバランススプレッド
「次のステップ」をクリック
「次のステップ」をクリック
「次のステップ」をクリック
「サービスの更新」をクリック
以下に反映されるのを待つ
http://container-test-loadbalancer-2142067120.ap-northeast-1.elb.amazonaws.com/
問題無ければ、最新のタスク定義をもとに taskdef.json を更新する
(executionRoleArn と secrets の内容が追加されることになる)
参考までに、以下は taskdef.json の内容
{
"ipcMode": null,
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"dnsSearchDomains": null,
"environmentFiles": null,
"logConfiguration": null,
"entryPoint": null,
"portMappings": [
{
"hostPort": 0,
"protocol": "tcp",
"containerPort": 80
}
],
"command": null,
"linuxParameters": null,
"cpu": 0,
"environment": [],
"resourceRequirements": null,
"ulimits": null,
"dnsServers": null,
"mountPoints": [],
"workingDirectory": null,
"secrets": [
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:host::",
"name": "DB_HOST"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:dbname::",
"name": "DB_NAME"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:username::",
"name": "DB_USERNAME"
},
{
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:password::",
"name": "DB_PASSWORD"
}
],
"dockerSecurityOptions": null,
"memory": 128,
"memoryReservation": null,
"volumesFrom": [],
"stopTimeout": null,
"image": "<IMAGE1_NAME>",
"startTimeout": null,
"firelensConfiguration": null,
"dependsOn": null,
"disableNetworking": null,
"interactive": null,
"healthCheck": null,
"essential": true,
"links": null,
"hostname": null,
"extraHosts": null,
"pseudoTerminal": null,
"user": null,
"readonlyRootFilesystem": null,
"dockerLabels": null,
"systemControls": null,
"privileged": null,
"name": "ecr_php74_apache"
}
],
"placementConstraints": [],
"memory": null,
"taskRoleArn": null,
"family": "Container-Test-Task",
"pidMode": null,
"requiresCompatibilities": [
"EC2"
],
"networkMode": null,
"runtimePlatform": null,
"cpu": null,
"inferenceAccelerators": null,
"proxyConfiguration": null,
"volumes": []
}
デプロイすると、phpinfo() の「Environment」に以下が現れた
DB_HOST: container-test.c40sfbd72bsp.ap-northeast-1.rds.amazonaws.com
DB_NAME: container
DB_USERNAME: (RDS上に作成したユーザー)
DB_PASSWORD: (RDS上に作成したパスワード)
環境変数にはarnの値が表示されて、実際のパスワードを得るにはSDKなどで独自に処理が必要なのかと思いきや、普通に環境変数へ展開された
これだと環境変数に普通に接続情報を書くのと変わらないような
…と思ったが、taskdef.json に直接接続情報を書くと「リポジトリ内に機密情報を含めている」状態になるので、それを避けるための措置なのだと思われる
phpinfo() の内容は絶対に流出させてはならない(もともと流出させるべきでは無い内容だが)
以下などを参考に、本番環境では phpinfo() を使用できないようにするなどしておくべきか
php.iniで危険な関数を無効化する | 晴耕雨読
https://tex2e.github.io/blog/php/set-disable-functions
■PHPプログラムからの接続確認
Dockerfileを調整し、PHPからMySQLへ接続するための命令を追加インストール
デプロイして、PHPからMySQLへ接続する命令を書いたページへアクセスすると、データベースに接続できた
具体的なコードは以下のとおり
<?php
try {
$pdo = new PDO(
'mysql:dbname=' . $_ENV['DB_NAME'] . ';host=' . $_ENV['DB_HOST'],
$_ENV['DB_USERNAME'],
$_ENV['DB_PASSWORD']
);
$stmt = $pdo->query('SELECT NOW() AS now;');
$data = $stmt->fetch(PDO::FETCH_ASSOC);
echo "<p>" . $data['now'] . "</p>\n";
$pdo = null;
} catch (PDOException $e) {
exit($e->getMessage());
}
■トラブル: PHPプログラムのページからRDSへアクセスしようとすると「504 Gateway Time-out」と表示された
WebサーバのコンテナからRDSにアクセスできるように、
RDSに割り当てているセキュリティグループの設定を調整する
■ECR+ECS+Codeシリーズで自動デプロイ: 環境を削除
Secrets Manager → dev/Container-Test-RDS/Mysql → アクション → シークレットを削除する
からシークレットを削除(即座に削除は完了しない。最低7日間は情報が残されている)
RDS → データベース
から「container-test」を削除
RDS → パラメータグループ
から「container-test-parameter」を削除
CloudWatch → ログ → ロググループ
から「/ecs/Container-Test-Task」を削除
CodePipeline → パイプライン → パイプライン
から「Container-Test」を削除
CodeBuild → ビルドプロジェクト → ビルドプロジェクト
から「Container-Test」を削除
Elastic Container Registry → リポジトリ
から、不要になったリポジトリがあれば削除しておく
Cloud9 → Your environments
から、不要になったCloud9を削除
以降は「Amazon Elastic Container Service(Amazon ECS)」の「環境の削除」の手順で削除
(ターゲットグループはいくつも作成しているので、ECS用に作ったものはすべて削除する)
■ECR+ECS+Codeシリーズで自動デプロイ: ベースイメージのセキュリティチェックについて考察
Criticalの「CVE-2019-19814」が気になるので、何とかしようとして何とかならなかったときのメモ
■調査
軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog
https://blog.inductor.me/entry/alpine-not-recommended
Docker image(イメージ)の違い:alpine,bullseye, buster, slim, stretch, jessie, slim-buster, windowsservercore, latestどれを選ぶべきか?
https://prograshi.com/platform/docker/docker-image-tags-difference/
Dockerの公式PHPのDockerfileを頑張って読んで理解しようとしてみた | Unskilled?
https://unskilled.site/docker%E3%81%AE%E5%85%AC%E5%BC%8Fphp%E3%81%AEdockerfile%E3%82%92%E9%A0%91%E5%...
Debian - Wikipedia
https://ja.wikipedia.org/wiki/Debian#%E6%AD%B4%E5%8F%B2
Dockerイメージ alpine,slim,stretch,buster,jessie等の違いと使い分け - 行けたら行く
https://www.ted027.com/post/docker-debian-difference/
DockerでRUNをまとめた方が良いとは限らない | フューチャー技術ブログ
https://future-architect.github.io/articles/20210121/
PHPの公式Dockerfileを読み解く - Qiita
https://qiita.com/hareku/items/d44c5c08ef586e0efa43
php/Dockerfile at 1eb2c0ab518d874ab8c114c514e16aa09394de14 - docker-library/php - GitHub
https://github.com/docker-library/php/blob/1eb2c0ab518d874ab8c114c514e16aa09394de14/7.3/stretch/apac...
Dockerの公式PHPのDockerfileを頑張って読んで理解しようとしてみた | Unskilled?
https://unskilled.site/docker%E3%81%AE%E5%85%AC%E5%BC%8Fphp%E3%81%AEdockerfile%E3%82%92%E9%A0%91%E5%...
php/Dockerfile at 0d23b3d08770889c6cb31e8e5374334879103f92 - docker-library/php - GitHub
https://github.com/docker-library/php/blob/0d23b3d08770889c6cb31e8e5374334879103f92/7.0/apache/Docke...
Debianは「Debian 11.0(bullseye)」が新しいみたい?
それなら以下をスタートにするか
FROM debian:bullseye
■リポジトリ作成
Elastic Container Registry → リポジトリを作成
以下の内容でリポジトリを作成
可視性設定: プライベート
リポジトリ名: debian_php74_apache
タグのイミュータビリティ: 有効
「リポジトリを作成」ボタンを押すとリポジトリが作成される
引き続き、リポジトリにプッシュするイメージを作成する
■イメージ作成1
docker\debian_php74_apache\Dockerfile
FROM debian:bullseye
$ docker image build -t php:debian_php74_apache docker/debian_php74_apache
$ docker image ls
タグ「1.0.0」を付けてプッシュする
$ cd docker/debian_php74_apache
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t debian_php74_apache .
$ docker image tag debian_php74_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.0.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.0.0
ECRでリポジトリ名 debian_php74_apache をクリックし、イメージタグとして「1.0.0」が現れていることを確認する
上記イメージに対してスキャンを実行すると、44件の警告が表示された。内訳は以下のとおり
Critical ... 0
High ... 3
Medium ... 3
Low ... 5
Informational ... 30
Undefined ... 3
Highの内容は以下のとおり
名前: CVE-2021-33574
パッケージ: glibc:2.31-13+deb11u2
重要度: HIGH
説明: The mq_notify function in the GNU C Library (aka glibc) versions 2.32 and 2.33 has a use-after-free. It may use the notification thread attributes object (passed through its struct sigevent parameter) after it has been freed by the caller, leading to a denial of service (application crash) or possibly unspecified other impact.
名前: CVE-2022-23218
パッケージ: glibc:2.31-13+deb11u2
重要度: HIGH
説明: The deprecated compatibility function svcunix_create in the sunrpc module of the GNU C Library (aka glibc) through 2.34 copies its path argument on the stack without validating its length, which may result in a buffer overflow, potentially resulting in a denial of service or (if an application is not built with a stack protector enabled) arbitrary code execution.
名前: CVE-2022-23219
パッケージ: glibc:2.31-13+deb11u2
重要度: HIGH
説明: The deprecated compatibility function clnt_create in the sunrpc module of the GNU C Library (aka glibc) through 2.34 copies its hostname argument on the stack without validating its length, which may result in a buffer overflow, potentially resulting in a denial of service or (if an application is not built with a stack protector enabled) arbitrary code execution.
■イメージ作成2
docker\debian_php74_apache\Dockerfile
FROM debian:bullseye-slim
$ docker image build -t php:debian_php74_apache docker/debian_php74_apache
$ docker image ls
タグ「1.1.0」を付けてプッシュする
$ cd docker/debian_php74_apache
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t debian_php74_apache .
$ docker image tag debian_php74_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.1.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.1.0
ECRでリポジトリ名 debian_php74_apache をクリックし、イメージタグとして「1.1.0」が現れていることを確認する
上記イメージに対してスキャンを実行すると、44件の警告が表示された
つまり変化せず
■イメージ作成3
以下をもとに Dockerfile とその関連ファイルを調整
https://github.com/docker-library/php/tree/master/7.4/bullseye/apache
$ docker image build -t php:debian_php74_apache docker/debian_php74_apache
$ docker image ls
タグ「1.2.0」を付けてプッシュする
$ cd docker/debian_php74_apache
$ chmod +x apache2-foreground
$ chmod +x docker-php-entrypoint
$ chmod +x docker-php-ext-configure
$ chmod +x docker-php-ext-enable
$ chmod +x docker-php-ext-install
$ chmod +x docker-php-source
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
$ docker image build -t debian_php74_apache .
$ docker image tag debian_php74_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.2.0
$ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php74_apache:1.2.0
ECRでリポジトリ名 debian_php74_apache をクリックし、イメージタグとして「1.2.0」が現れていることを確認する
上記イメージに対してスキャンを実行すると、Criticalの「CVE-2019-19814」が現れた
つまり変化なしなので、解決せず
補足:
ビルド中に以下で止まったので、
+ export CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 LDFLAGS=-Wl,-O1 -pie
+ docker-php-source extract
/bin/sh: 1: docker-php-source: Permission denied
7.1.8-fpm-alpine does not build - Issue #490 - docker-library/php - GitHub
https://github.com/docker-library/php/issues/490
をもとに「chmod +x」を実行している
■2022年10月に追加で調査したメモ
dockerの脆弱性スキャンの結果を分析する
https://zenn.dev/starnishi/scraps/f1578f26951399
「CVE-2019-19814」についての見解が記載されている
どうやら
・CVE-2019-19814 の問題は存在している
・Debian/bullseye ではこの問題に対応はされていない
・対応しない理由としては
「no-dsa(直接悪用されにくい問題。インフラに介入されないと起きない問題)なのでマイナー問題と判断」となっている
ということらしい
インターネットに面していない脆弱性で、直接悪用されることはなく、攻撃者が被害者のインフラに片足を踏み入れたときに大きな問題となるもの
…だから対応しないとのこと
つまりは基本的には対応不要な脆弱性がリストに挙がっているだけのようだが、それはそれで
「対応不要な脆弱性警告が毎回挙げられる」ことになる
「以降はこの脆弱性を無視する」のような機能が無いと、実質脆弱性チェックは使い物にならないのでは
AWS CDKでECS on FargateのCI/CDを実現する際の理想と現実 / ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aws-cdk - Speaker Deck
https://speakerdeck.com/tomoki10/ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aw...
AWS CDKでECS on FargateのCI/CDを実現する際の理想と現実 / ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aws-cdk - Speaker Deck
https://speakerdeck.com/tomoki10/ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aw...
「パッケージによる脆弱性や脆弱性対応の負担を最小化するため、最低限のパッケージのみが含まれるalpineやslim、distrolessなどのイメージを選択することが良いとされている」
とあるが、実際のところデバッグの手間は増えて大変らしい
現状明確な対処方法は無いようなので、
・定期的に手動で実行し、毎回結果は控えておく
・前回と異なる警告があれば、都度調査して対応を考える
とするくらいだと思われる
■ECR+ECS+Codeシリーズで自動デプロイ: 引き続きの検証
■デプロイ時間の短縮
Amazon ECS でのコンテナデプロイの高速化 | トリの部屋
https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments/
ALBのヘルスチェック時間を短くすることで、デプロイ時間を短縮することは可能みたい
■ログ管理など
AWS CDKでECS on FargateのCI/CDを実現する際の理想と現実 / ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aws-cdk - Speaker Deck
https://speakerdeck.com/tomoki10/ideal-and-reality-when-implementing-cicd-for-ecs-on-fargate-with-aw...
あんどぅさんはTwitterを使っています: 「本番運用するといずれ誰もがたどり着く、公式ドキュメントには書かれてないログ管理の現実解が資料化されていてすばらしい」 / Twitter
https://twitter.com/integrated1453/status/1590341343821565953
ログ管理以外にも、セキュリティ対策やデプロイなど全般的に参考になりそう
■定期的に処理を行う
※未検証
Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → タスクのスケジューリング
からCronのように定期処理を定義することができるみたい
AWS ECSを使ったバッチサーバ環境を試してみる - Qiita
https://qiita.com/pokotyan/items/36ab249db0e8aeb16e76
Amazon ECS でタスクをスケジューリングして定期的に実行する | Ritolabo
https://www.ritolab.com/posts/222
■脆弱性対策
OpenSSL Security Advisories - November 2022
https://aws.amazon.com/jp/security/security-bulletins/AWS-2022-008/
・上記のようなopenssl脆弱性の対策などはどうするのか
今回は対応不要だったが、対応が必要なものだったらどういう作業が必要になるか
・EC2を使っている場合、インスタンスを終了させると勝手に対応済みのものが立ち上がるのか
EC2はあくまでも普通のEC2なので、SSHで接続してアップデートが必要か。さらに、元となるAMIのことも考慮が必要そう
・Fargateを使っている場合、一切何もしなくてもいいのか。もしくは再起動的な何かが必要か
・もしくはどちらの場合も、dockerfile側で何とかするものか
ケースバイケースかもしれないが
■追加検証用メモ
・どこで何を設定しているか、整理して考える
・ECS、nginx と php-fpm のような複数イメージの組み合わせも試す
・RDSのパスワード変更は試しておきたい
Secrets Manager側の情報も別途変更が必要だと思われる
アプリケーションのリポジトリ側は何も変更する必要が無いと思われる
・テストの自動実行も試す
・プログラムを更新した数だけタスクが作成されることになりそうだが、定期的に削除すべきか
Laravelを動作させる想定で、複数イメージ(nginxとphpなど)のビルド、マイグレーション、キャッシュの削除なども考えておきたい
以下などが参考になりそう
LaravelアプリケーションをCodePipeline/CodeBuildでECSに自動デプロイする - Qiita
https://qiita.com/imunew/items/687221e02d977564d610
LaravelアプリケーションをローカルでもAWSでもDockerで動かす - Qiita
https://qiita.com/imunew/items/1e4826030d725beb4710
LaravelをECS上で運用するTips - ROXX開発者ブログ
https://techblog.roxx.co.jp/entry/2020/06/16/102406
LaravelアプリをDockerfile, ECR, ECS, RDSを使用してデプロイする。 - Qiita
https://qiita.com/ken-s/items/3548568eaff4e60c2cb9
Laravel の ECS への Deploy
https://info.drobe.co.jp/blog/engineering/laravel-ecs-deploy
Laravel 9 を ECS on Fargateで構築 - Qiita
https://qiita.com/hirai-11/items/241df305a90af3ccf973
■SES・SNS・SQS の比較
SES ... Simple Email Service
SMTPサーバの代替サービス
メールの大量送信や、顧客へのメール送信、メールの受信を行う
信頼されたメールへ送ることを前提としているので、「メールアドレスで仮登録」のような仕組みとは相性が良くない(後述の「SES メール送信 > メール送信のベストプラクティス」を参照)
設定や運用に不備があると、サービスを停止される可能性があるので注意しつつ使用する
SNS ... Simple Notification Service
メッセージをプッシュ通知する
HTTP、メール、SMS、SQS、Push(Apple、Google、Windowsなど)に送ることができる
メールに通知する場合、
「トピック作成 → AWSにメールアドレス登録 → AWSから送信される英語メールでURLをクリックして送信承認」
という承認が必要なフローとなるので注意
SQS ... Simple Queue Service
メッセージキューの管理
キューに対して任意のメッセージを送り、ポーリング(プル)によって別のアプリケーションからそのキューのメッセージを取得する
例えば動画変換など非常に時間がかかる処理があった場合、1リクエストで完結させようとするとタイムアウトやネットワークの専有が発生する
これを「動画変換の受け付け → 動画変換完了の通知」という仕組みにすることにより、バックグラウンドで処理を行わせることができる
その際のキューの管理を行う
「仮登録のためにメールアドレスを入力してもらい、本登録用のURLを送信する」
「問い合わせフォームの自動返信メールを送信する」
のような用途にはどれも向かないかもしれない(不特定多数のアドレスに送ることになるため)
SESやSNSでメールを送信するとしても、EC2からのメール送信が不要になるわけでは無さそう
ただしバウンスの処理をきちんと行うなら、SESでのメール送受信でひととおり対応できるかもしれない
■SES メール送信
■メールの送信
Amazon EC2 Eメール送信ベストプラクティス
http://dev.classmethod.jp/cloud/aws/ec2-send-email-best-practice/
Amazon SESによるメール送信環境の構築と実践
http://dev.classmethod.jp/cloud/aws/amazon-ses-build-and-practice/
AWS SDK を使用して Amazon SES から E メールを送信する
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-an-email-using-sdk.html
以下は未検証だが比較的最近の記事
AWS再入門ブログリレー Amazon SES編 | Developers.IO
https://dev.classmethod.jp/cloud/aws/re-introduction-2019-amazon-ses/
Amazon SES ベストプラクティス&アンチパターン - 後ろを向いて後退します
http://micpsm.hatenablog.com/entry/2019/12/06/120000
【Amazon SES】SESでメール送信する時に知っておきたい事 - websandbag ブログ
https://blog.websandbag.com/entry/2019/07/31/160557
Amazon SES でメール送信するときのベストプラクティスまとめ(2020年10月) | Developers.IO
https://dev.classmethod.jp/articles/ses-send-mail-best-practices-summary/
SESが不正利用された!?その調査と対応 | Developers.IO
https://dev.classmethod.jp/articles/ses_compromised_check/
さらにその後、以下の記事もあった
参考にできそう
大規模Email配信システムのクラウドジャーニー - DeNA Engineers' Blog
https://engineer.dena.com/posts/2021.05/email-cloud-migration/
そのメール、本当に届いてる?Amazon SESの運用で得た監視プラクティス - Cybozu Inside Out | サイボウズエンジニアのブログ
https://blog.cybozu.io/entry/2021/11/26/075846
AWS SESで信頼性の高いメール送信(SPF, DKIM, DMARC) with Terraform - 電気ひつじ牧場
https://cha-shu00.hatenablog.com/entry/2022/03/06/175823
2020年7月から東京リージョンが利用できるようになったので、東京リージョンで使用する
Amazon SES 東京リージョン対応のお知らせ | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/amazon-ses-tokyo/
■メール送信のベストプラクティス
SESはバウンスや苦情を抑えることが重要になる
対策例が以下に紹介されているので参考にする
Amazon SES を使用した E メール送信のベストプラクティス - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/best-practices.html
Amazon SES 送信レビュープロセスに関するよくある質問 - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/faqs-enforcement.html
特に「Q11. バウンスを最小限に抑えるにはどうすればよいですか?」の項目が参考になりそう
例えばメールでの仮登録機能などは「友だちにメールを送る」機能の対策が参考になりそう
以下、実際に試した内容のメモ
■ドメインの登録
Amazon Simple Email Service → 設定 → 検証済みID → IDの作成
「IDの詳細」で以下のように入力する
IDタイプ: ドメイン
ドメイン: refirio.net
「デフォルト設定セットの割り当て」と「カスタムMAIL FROMドメインの使用」にはチェックを入れない
続いて「ドメインの検証」の「DKIM の詳細設定」で以下のように入力する
IDタイプ: Easy DKIM
DKIM署名キーの長さ: RSA_2048_BIT
「DNSレコードのRoute53への発行」と「DKIM署名」にチェックを入れる
これで「IDの作成」ボタンをクリック
完了画面に
必要なアクション
この ID の所有権を確認するには、指定された CNAME レコードを使用してドメインの DNS 設定で DKIM を設定する必要があります。
と表示された
画面上部の「ID ステータス」で「検証保留中」となっている
また画面下部の「DomainKeys Identified Mail (DKIM)」で「DKIM の設定」が「保留中」となっている
また「DNSレコードの発行」部分にCNAMEレコードが表示されている
このレコードを登録する必要がある…かと思ったが、数分待つと「DKIM setup SUCCESS for refirio.net in Asia Pacific (Tokyo) region」というメールが届いた
画面を再読み込みすると、どちらも「検証済み」になっていた
また、Route53を確認すると対象のCNAMEが登録されていた
(サブドメインの権限を移譲した先のAWSアカウントでも問題無かった)
■SMTPアカウントの発行
Amazon Simple Email Service → SMTP設定 → SMTP認証情報の作成
IAMユーザの作成画面になる
「IAM User Name」はそのままで「作成」ボタンをクリック
ボタンが「認証情報のダウンロード」に変わり、クリックするとアカウント情報が記載されたCSVファイルをダウンロードできる
今回は以下の情報を取得できた
IAM User Name: ses-smtp-user.12345678-901234
Smtp Username: XXXXXXXXXX
Smtp Password: YYYYYYYYYY
それ以外の情報は、「SMTP設定」の画面に表示されている
今回は以下のように表示されていた
SMTPエンドポイント: email-smtp.ap-northeast-1.amazonaws.com
Transport Layer Security (TLS): 必須
STARTTLS ポート: 25、587 または 2587
カスタム SSL クライアントのサポート: -
TLS ラッパーポート: 465 または 2465
この情報をもとに、いったんPHPMailerからメール送信テストを行なってみる(送信プログラムの詳細は、後述の「PHPMailerからSMTPでメールを送信」を参照)
…が。以下のエラーになった
接続はできているようだが、送信制限に引っかかっているのだと思われる
この時点では、送信元も送信先も refirio.net である必要がある…はず
CLIENT: 554 Message rejected: Email address is not verified. The following identities failed the check in region AP-NORTHEAST-1: refirio.work@gmail.com
■送信制限の解除
Amazon SES サンドボックス外への移動 - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/request-production-access.html
Amazon Simple Email Service → アカウントダッシュボード
準備ができたら本稼働アクセスのリクエストをするように案内が表示されている
現時点では以下のように送信制限が表示されている
日次送信クォータ: 200(24時間あたりのEメール数)
最大送信レート: 1(1秒あたりのEメール数)
「本稼働アクセスのリクエスト」ボタンをクリック
リクエストするための画面に遷移するので、以下のように入力
メールタイプ: トランザクション
ウェブサイトのURL:
https://refirio.net/
ユースケースの説明: お客様宛に通知メールを送信します。メール受信者のアドレスはシステムで管理されており、送信できないメールアドレスは登録されておりません。
その他の連絡先: (空欄)
連絡する際の希望言語: Japanese
「私はAWSサービス条件と適正利用規約(AUP)に同意します」にチェックを入れ、「リクエストの送信」ボタンをクリック
以下のように表示された
本稼働アクセスのリクエストが正常に送信されました。リクエストの詳細を確認するまでに最大で 24 時間かかることがあります。
翌日に以下のメールが届き、送信制限は解除された
再度PHPMailerからメール送信テストを行うと、無事にメールが送信できた
またGmailからメールのヘッダを確認すると、以下のとおりSPF&DKIMともに「PASS」になっていた
SPF: PASS(IP: 23.251.234.10)
DKIM: 'PASS'(ドメイン: refirio.net)詳細
■送信制限の解除(昔の手順)
Amazon SES サンドボックスの外への移動
http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html
「Sending Statistics」画面に表示されている「Request a Sending Limit Increase」をクリックする
名前: refirio-user
アカウント: 123456789012
内容: サービス制限の増加
制限タイプ: SES送信制限
リージョン: 米国東部 (バージニア北部)
制限: 希望する最大送信レート
新しい制限値: 3
メールの種類: システム通知
ウェブサイトのURL: (空欄)
私は AWS サービス利用規約と AUP に準拠してメールを送信します: はい
私は明確にリクエストされた受信者にのみメールを送信します: はい
バウンスや苦情を処理するプロセスがあります: はい
申請理由の説明: お客様宛にニュースを定期配信します。メール受信者のアドレスはシステムで管理されており、送信できないメールアドレスは登録されておりません。
お問い合わせ言語: 日本語
連絡方法: Web
※最大送信レート
Amazon SES が 1 秒あたりにアカウントから受け付ける E メールの最大数。
この制限を瞬間的に超えることはできますが、制限を超えた状態が長時間続くことは許可されません。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/manage-sending-limits.html
申請後、3時間ほどで返信が来て制限が解除された
■送信制限の解除(昔の手順でのトラブル事例)
申請後、3時間ほどで返信が来て制限が解除された…と思ったが、
相変わらず「Sending Statistics」画面に「Request a Sending Limit Increase」と表示されてことがあった
未承認アドレスへのメール送信テストもエラーになった
2日経っても変化がないのでクローズされたケースを再開し、以下の問い合わせをした
一応日本語と英語を併記した
半日程度で以下の返信があり、制限は解除された
AWS側で正しく手続きできていなかったみたい?
Thank you very much for bringing this to our attention.
After investigating, we have discovered that the problem was on our end
and we have increased your sending quota to 50,000 messages per day
and your maximum send rate to 14 messages per second in AWS Region US East (N. Virginia).
Your account has also been moved out of the sandbox, so you no longer need to verify recipient addresses.
■PHPMailerからSMTPでメールを送信
<?php
require_once 'PHPMailer/class.phpmailer.php';
require_once 'PHPMailer/class.smtp.php';
// SMTPサーバ: ホスト
define('SMTP_HOST', 'email-smtp.ap-northeast-1.amazonaws.com');
// SMTPサーバ: メールアカウント
define('SMTP_USERNAME', 'XXXXXXXXXX');
// SMTPサーバ: メールパスワード
define('SMTP_PASSWORD', 'YYYYYYYYYY');
// SMTPサーバ: プロトコル (ssl または tls)
define('SMTP_SECURE', 'tls');
// SMTPサーバ: 送信ポート (ssl:465, tls:587)
define('SMTP_PORT', '587');
// メール送信準備
$mail = new PHPMailer();
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->Host = SMTP_HOST;
$mail->Username = SMTP_USERNAME;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = SMTP_SECURE;
$mail->Port = SMTP_PORT;
// メール内容定義
$mail->CharSet = 'UTF-8';
$mail->Encoding = 'base64';
$mail->setFrom('from@example.com', 'メール送信者');
$mail->addAddress('to@example.com', 'メール受信者');
$mail->Subject = 'SESからの送信テスト';
$mail->Body = "テスト。\nこれはテストです。";
// メール送信
if (!$mail->send()) {
exit('Error: ' . $mail->ErrorInfo);
}
exit('complete');
tls と 587 は、ssl と 465 にしても送信できたが、tls(587)の方が推奨されるらしい
ポートの違いについては以下を参照
ポート465と587の違いとは? | SendGridブログ
https://sendgrid.kke.co.jp/blog/?p=12945
■PostfixからSMTPでメールを送信
後述の「SES PostfixからSMTPでメールを送信」を参照
■メーラーからSMTPでメールを送信
SMTPを使ってAmazonSESのメールをGmailで送信できるようにする | Hodalog
https://hodalog.com/sending-email-with-ses-using-smtp-and-gmail/
Amazon SESでメールクライアントからSMTP送信を行う | DevelopersIO
https://dev.classmethod.jp/articles/amazon-ses-smtp/
■Return-Pathの設定
現状未検証
何もしなければ、以下のようなReturn-Pathになっていた
Return-Path: <012345678901cee8-57b4ef59-99a0-4548-b220-f14c687d28f2-000000@ap-northeast-1.amazonses.com>
以下は参考になるかもしれない
AWS SES で検証済のドメインとメールアドレスが競合しているときのカスタム MAIL FROM での書き換え - Qiita
https://qiita.com/ngyuki/items/63e0e57cab2cba266eef
到達率に影響すると思われるので、それとは関係なく設定しておくべきか…と思うが、設定するとバウンスメールの受け取りに悪影響があるか
そもそも、後述の「バウンスメールの設定」を行うなら不要か
以下の公式解説では「Amazon SES を使用する場合は、常に「Return-Path」パラメータを設定して、バウンスを常時把握し、バウンスの発生時に適切なアクションを実行できるようにすることをお勧めします。」となっている
が、「バウンスメールの設定」によってAmazonのアドレスが入っているのなら、変更すべきでは無いか
Amazon SESのE メール形式 - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-concepts-email-format.html
■メール送信ログの設定
後述の「SES メール送信ログの設定」を参照
■通知先の作成
Amazon SNS → トピック → トピックの作成
タイプ: スタンダード
名前: refirio
「トピックの作成」ボタンをクリック
トピックが作成されたことを確認する
Amazon SNS → サブスクリプション → サブスクリプションの作成
トピックARN: (上で作成したトピックを選択)
プロトコル: Eメール
エンドポイント: server@refirio.net
「サブスクリプションの作成」ボタンをクリック
サブスクリプションが作成されたことを確認する
また、上で設定したメールアドレスに「AWS Notification - Subscription Confirmation」というメールが送信される
これはメールアドレスの存在確認なので、本文のURLをクリックする
■バウンスメールの設定
Amazon SES → 検証済みID → refirio.net → 通知
フィードバック通知として3つ表示されており、それぞれ
Bounce: SNSトピックなし
Complaint: SNSトピックなし
Delivery: SNSトピックなし
となっている
「編集」ボタンをクリック
SNSトピックの設定が表示される
「バウンスフィードバック」と「苦情のフィードバック」に上で作成した通知先を設定し、
それぞれ「元のEメールヘッダーを含める」にチェックを入れ、「変更の保存」ボタンをクリックする
SESのバウンス情報をメールで受け取る方法 - Qiita
https://qiita.com/K5K/items/2ab9c82fd7b139384ea0
SESでバウンスメールを確認する方法をいくつか試してみた | DevelopersIO
https://dev.classmethod.jp/articles/ses-bounce-check/
AWS SESでハードバウンスのようなメールがソフトバウンス扱いで届いた場合のしくみと対処について - コネヒト開発者ブログ
https://tech.connehito.com/entry/2022/09/22/180521
【こんなときどうする?】Amazon SESのバウンスレートが高くて、メールの送信ができない | SunnyCloud
https://www.sunnycloud.jp/column/20210923-01/
■バウンスメールのテスト
Amazon SES → 検証済みID → refirio.net → テストEメールの送信
Eメール形式: フォーマット済み
From-address: info@refirio.net
シナリオ: バウンス
件名: 送信テスト
本文: これは送信テストです。(バウンス)
設定セット: refirio-ses-log
「テストEメールの送信」ボタンをクリック
「通知先の作成」で指定したメールアドレスに、実際に「AWS Notification Message」という件名のメールが届けば成功
送信元は no-reply@sns.amazonaws.com で、送信先は server@refirio.net となっていた
本文は以下のとおり(冒頭のJSONは、実際は改行なしで記載されていた)
{
"notificationType":"Bounce",
"bounce":{
"feedbackId":"01060180bcc4a2c6-12345678-d33a-40e9-9db7-896a09ad3459-000000",
"bounceType":"Permanent",
"bounceSubType":"General",
"bouncedRecipients":[
{
"emailAddress":"bounce@simulator.amazonses.com",
"action":"failed",
"status":"5.1.1",
"diagnosticCode":"smtp; 550 5.1.1 user unknown"
}
],
"timestamp":"2022-05-13T09:34:05.000Z",
"remoteMtaIp":"203.0.113.2",
"reportingMTA":"dns; e234-3.smtp-out.ap-northeast-1.amazonses.com"
},
"mail":{
"timestamp":"2022-05-13T09:34:04.020Z",
"source":"test@refirio.net",
"sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net",
"sourceIp":"203.0.113.1",
"callerIdentity":"refirio-user",
"sendingAccountId":"123456789012",
"messageId":"01060180bcc49ef4-12345678-3bb4-4a9c-ad17-4ff037d8e4cc-000000",
"destination":[
"bounce@simulator.amazonses.com"
]
}
}
--
If you wish to stop receiving notifications from this topic, please click or visit the link below to unsubscribe:
https://sns.ap-northeast-1.amazonaws.com/unsubscribe.html?SubscriptionArn=arn:aws:sns:ap-northeast-1...
Please do not reply directly to this email. If you have any questions or comments regarding this email, please contact us at
https://aws.amazon.com/support
■バウンスレートと苦情率の監視
※未検証
SESのバウンスレートと苦情率は監視対象にしておきたい
以下などが参考になりそう
AWS SESでハードバウンスのようなメールがソフトバウンス扱いで届いた場合のしくみと対処について - コネヒト開発者ブログ
https://tech.connehito.com/entry/2022/09/22/180521
【こんなときどうする?】Amazon SESのバウンスレートが高くて、メールの送信ができない | SunnyCloud
https://www.sunnycloud.jp/column/20210923-01/
■専用IPアドレスの取得
※未検証
月額$25でSESに固定IPアドレスを割り当てることができる
共有IPアドレスの場合、他人が同じIPアドレスから大量にメールを送信することで、スパム報告に巻き込まれる可能性がある
また、同一IPアドレスからの受信を制限しているところもあるが、固定IPアドレスを複数取得することで対応できる
専用 IP アドレスのリクエストと解放 - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/dedicated-ip-case.html
Amazon SESでSPFとDKIMを設定してみた|梨_茶|note
https://note.com/li_oche1021/n/ne0357eacbabf
メール送信で固定IPアドレスを利用すると何がうれしいのか - Qiita
https://qiita.com/nakansuke/items/e26f44103e9a1dda366f
■メモ
キャリアメールに届かないという記事を見かけるが、DNSにSPFを設定すれば大丈夫みたい?
WordPresでSESを使う方法もあるみたいなので、WordPressで使えないことも無いみたい?
要調査
Amazon SES でメール送信するときのベストプラクティスまとめ(2020年10月) | Developers.IO
https://dev.classmethod.jp/articles/ses-send-mail-best-practices-summary/
Amazon SESによるメール送信環境の構築と実践 | DevelopersIO
https://dev.classmethod.jp/articles/amazon-ses-build-and-practice/
Amazon SES と SendGrid のバウンスの取り扱いについてまとめてみた | DevelopersIO
https://dev.classmethod.jp/articles/amazon-ses-sendgrid-bouce-reaction/
AWSのSESでバウンスメール(bouncemail)対策。3つの方法とメリット・デメリット | ブログ|ベトナムでのオフショア開発とスマートフォンアプリ開発のバイタリフィ
https://vitalify.jp/blog/2018/03/aws-ses-bouncemail.html
SESのバウンス率 - Amazon SES(AWS)のバウンスされたメールアドレス
https://www.usebouncer.com/ja/%E7%B0%A1%E5%8D%98%E3%81%8B%E3%81%A4%E5%8A%B9%E6%9E%9C%E7%9A%84%E3%81%...
[AWS]SESを利用したキャリアメール送信について考える | Developers.IO
https://dev.classmethod.jp/articles/20170824-ses-send-to-carrier/
【Amazon SES】SESでメール送信する時に知っておきたい事 - websandbag ブログ
https://blog.websandbag.com/entry/2019/07/31/160557
AmazonSESから携帯キャリアメールに届く確率を上げる - Qiita
https://qiita.com/shouta-dev/items/a33c55e0df154012c557
wordpress・SES経由でメールを送信できるようにする - Qiita
https://qiita.com/gozuqi/items/099d064e8657f51f2b3e
バウンスメールと AWS SES - コネヒト開発者ブログ
https://tech.connehito.com/entry/2020/09/17/152126
おさえておきたいメールの基礎用語 | SendGridブログ
https://sendgrid.kke.co.jp/blog/?p=658
SESが利用停止されたときの内容は以下が参考になる
バウンスしすぎて Amazon SES から追放された俺たちは Mailgun と SendGrid に国を作ることにした - ANDPAD Tech Blog
https://tech.andpad.co.jp/entry/2021/10/27/100000
以下は上記ページについての気になるはてブコメント
https://b.hatena.ne.jp/entry/s/tech.andpad.co.jp/entry/2021/10/27/100000
・SESはちょっと前にアカウントレベルのサプレッションリストが設定できるようになってて、ハードバウンスは自動で送信停止できるよ
警告来たのはバウンス率じゃなくて苦情率か。何やってるの?
・オプトアウト実装や宛先リストのクリーニング含めバウンス対応をちゃんとやらないと結局同じことになりそうな気はする(共有 IP アドレスみたいだし
・SendGrid は機械学習のスパム検知機能があり、それに引っかかると容赦なくアカウント単位で配信停止される。
問い合わせると誤検知で発動してしまったごめんね。というのが過去2回あって、メインで使うのはやめた。
・面倒くさいのは同意するけど、SESからSendgrid/Mailgunに逃げても本質的な対応はいずれしないといけないんじゃないのかなという気がする。
うちはSendGrid高くてSESに来たクチだけど何も困ってない。
・苦情レートが高いのをスルーしてるのはどうなんだろう。自分だったらスパマー扱いされてるのでは?と考えてレートを下げる施策を考えるかも
■昔のメモ
解除後も送信制限は、徐々に緩和されていくみたい
制限が解除されると任意の送信先を指定できるみたいだが、送信元は常にアドレスの認証が必要みたい
以下に同意する必要があるため、仮登録時のメール送信やフォームメールでの自動リプライなどに使うことはできないかもしれない
あくまでも、ニュースの一斉配信を用途としているかもしれない
(2021年5月追記:AWSのアーキテクチャレビューにて、「仮登録のためにドコモのアドレスにメールを送ったり、という使用例は実際にある」とのこと)
その場合でも、常にバウンスや苦情については気にかける必要がある
バウンスは5%以下に、苦情は0.1%以下に保ち、悪意あるコンテンツ(ウイルスなど)も送らないようにする
・私は AWS サービス利用規約と AUP に準拠してメールを送信します
・私は明確にリクエストされた受信者にのみメールを送信します
・バウンスや苦情を処理するプロセスがあります
仮登録時のメール送信やフォームメールでの自動リプライなどは、ごく普通にPHPから送信すれば良さそう
でもSPFなどを考えるなら、固定IPを持ったバッチサーバから送信する必要がありそう
そうなると、SESを使うか否かに関係なく、バッチサーバからのメール送信の仕組みは構築する必要がありそう
SESはキャリアメールへの送信問題もある
独自ドメインでのメール受信という用途としては使えそう
仮登録のためにメールを送信してもらって自動返信、バウンスメールの受信、など
■SES PostfixからSMTPでメールを送信
サーバ内でmailコマンドを実行したり、PHPでmail関数を実行することにより、自動でSESが使用されるようにする
Amazon SES と Postfix の統合 - Amazon Simple Email Service
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/postfix.html
[AWS] Amazon SES と Postfix を連携しメールを送付する | MSeeeeN
https://mseeeen.msen.jp/send-emails-by-linking-amazon-ses-and-postfix/
【AWS】EC2インスタンスからPostfix + SESで外部へシステムメールを送信 | 電算星組
https://densan-hoshigumi.com/aws/aws-postfix-ses-send-email
Amazon SESとPostfixの連携でハマったポイント - Qiita
https://qiita.com/ushirog/items/bd0e890e22b01c474352
Amazon SESとpostfixの連携 - kazu22002の技術覚書
https://kazu22002.hatenablog.com/entry/2021/02/06/055536
Amazon SESのSMTPエンドポイントを試してみた | DevelopersIO
https://dev.classmethod.jp/articles/sendmail-from-ses-smtpendpoint/
[AWS] Amazon SES と Postfix を連携しメールを送付する | MSeeeeN | 大阪発 IT メディア by MSEN
https://mseeeen.msen.jp/send-emails-by-linking-amazon-ses-and-postfix/
Amazon SES にSPF、DKIM、DMARC設定と、サンドボックスを解除してメール送信してみた | DevelopersIO
https://dev.classmethod.jp/articles/amazon-ses-set-up-spf-dkim-dmarc-and-unlocked-sandbox/
AWSからメールを送信するには?見落としがちなメール送信時の課題について解説 - ベアメールブログ
https://baremail.jp/blog/2022/01/24/1891/
■EC2の起動と設定
EC2の t2.micro を起動する
ElasticIP でIPアドレスを固定しておく
Route53で以下のDNSを設定しておく
refirio.net A 固定IPアドレス
言語とタイムゾーンを設定
# localectl set-locale LANG=ja_JP.UTF-8
# timedatectl set-timezone Asia/Tokyo
メールログの時差を調整
# cd /var/spool/postfix
# mkdir etc
# cd etc
# cp /etc/localtime .
# systemctl restart rsyslog
# systemctl restart postfix
認証情報ファイルを作成
# vi /etc/postfix/sasl_passwd
… 認証情報ファイルを新規作成
[email-smtp.ap-northeast-1.amazonaws.com]:587 AK**********JES342R7:BP**********1AlS39hD6OfyaQdm6gUzfJ3QuG6LB2Ko
# postmap hash:/etc/postfix/sasl_passwd
… postmapで認証情報ファイルをハッシュ化(sasl_passwd と同じ階層に sasl_passwd.db が作成される)
# chown root. /etc/postfix/sasl_passwd
# chown root. /etc/postfix/sasl_passwd.db
# chmod 0600 /etc/postfix/sasl_passwd
# chmod 0600 /etc/postfix/sasl_passwd.db
Postfixの設定ファイルを調整
# vi /etc/postfix/main.cf
#relayhost = $mydomain
#relayhost = [gateway.my.domain]
#relayhost = [mailserver.isp.tld]
#relayhost = uucphost
#relayhost = [an.ip.add.ress]
relayhost = [email-smtp.ap-northeast-1.amazonaws.com]:587 … 転送先のメールサーバ
# 以下、最終行へ追記
smtp_sasl_auth_enable = yes … Postfix SMTPクライアントのSASL認証を有効にする
smtp_sasl_security_options = noanonymous … Postfix SMTPクライアントで使うことが許される認証方法(今回は「匿名ログインを許可しない認証」としている)
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd … 認証情報ファイル
smtp_use_tls = yes
smtp_tls_security_level = encrypt … STARTTLS ESMTP機能をサポートしていれば暗号化、そうでなければ平文で送る
smtp_tls_note_starttls_offer = yes
smtp_tls_loglevel = 1 … TLSに関する追加ログ設定(TLSハンドシェイクと証明書の情報をログに記録する)
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt … Postfix SMTPクライアント証明書を発行した認証局(CA)の証明書を持つファイル
# systemctl restart postfix
… Postfixを再起動
これで、サーバ内部からメールを送信できるようになっている
一例だが、以下のようにすることで example@gmail.com にメールが送信される
(SES利用開始時に「検証済みID」で登録した送信元を指定する必要があるので注意)
# yum -y install mailx
# echo "本文" | mail -s "タイトル" -r info@refirio.net example@gmail.com
届いたメールのヘッダに
Received: from e234-2.smtp-out.ap-northeast-1.amazonses.com (e234-2.smtp-out.ap-northeast-1.amazonses.com. [23.251.234.2])
by mx.google.com with ESMTPS id z18-20020a170903019200b001892e5980a7si23632554plg.405.2023.01.19.19.22.20
for <example@gmail.com>
(version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
Thu, 19 Jan 2023 19:22:20 -0800 (PST)
Received-SPF: pass (google.com: domain of 01060185cd32d7e7-95598bec-cc0a-464f-bf7c-6e119af0e8a3-000000@ap-northeast-1.amazonses.com designates 23.251.234.2 as permitted sender) client-ip=23.251.234.2;
などと書かれているので、SES経由で送信できていることが確認できる
また、/var/log/maillog に以下のログが記録された
Jan 20 12:22:19 ip-10-1-0-69 postfix/pickup[3733]: 3F77D458CE7: uid=0 from=<info@refirio.net>
Jan 20 12:22:19 ip-10-1-0-69 postfix/cleanup[3785]: 3F77D458CE7: message-id=<63ca08eb.4XiwGj2j9Ku+rgpP%info@refirio.net>
Jan 20 12:22:19 ip-10-1-0-69 postfix/qmgr[3734]: 3F77D458CE7: from=<info@refirio.net>, size=468, nrcpt=1 (queue active)
Jan 20 12:22:19 ip-10-1-0-69 postfix/smtp[3787]: Trusted TLS connection established to email-smtp.ap-northeast-1.amazonaws.com[54.64.137.154]:587: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Jan 20 12:22:19 ip-10-1-0-69 postfix/smtp[3787]: 3F77D458CE7: to=<example@gmail.com>, relay=email-smtp.ap-northeast-1.amazonaws.com[54.64.137.154]:587, delay=0.44, delays=0.04/0.04/0.14/0.21, dsn=2.0.0, status=sent (250 Ok 01060185cd32d7e7-95598bec-cc0a-464f-bf7c-6e119af0e8a3-000000)
Jan 20 12:22:19 ip-10-1-0-69 postfix/qmgr[3734]: 3F77D458CE7: removed
■外部からメールサーバのSMTPを経由して送信
ポート587を空ける
今回は実際の送信をSESに任せるので、ポート25を空ける必要は無い
正しいSMTPポートの選び方(ポート番号25、587、465、2525)
https://kinsta.com/jp/blog/smtp-port/
サブミッションポートを設定する
# vi /etc/postfix/master.cf
… サブミッションポートを設定(OP25Bの対応)
#submission inet n - n - - smtpd
submission inet n - n - - smtpd … サブミッションポートを有効にする
# -o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_auth_enable=yes … サブミッションポートで、SASL認証を実施(先頭のスペースの数は2つ必要みたい)
# vi /etc/sasl2/smtpd.conf
#pwcheck_method: saslauthd
pwcheck_method: auxprop … SASL独自のパスワードDBを使用する
SASLの設定 - Qiita
https://qiita.com/nkiw/items/cbddeaba18f8c010fb5e
Postfixの設定ファイルを調整
# vi /etc/postfix/main.cf
#myhostname = virtual.domain.tld
myhostname = web1.refirio.net … ホスト名(FQDN)を設定
#mydomain = domain.tld
mydomain = refirio.net … ドメインを設定
#myorigin = $mydomain
myorigin = $mydomain
#inet_interfaces = localhost
inet_interfaces = all
#mydestination = $myhostname, localhost.$mydomain, localhost
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# systemctl restart postfix
… Postfixを再起動
SMTP送信ユーザの作成
# echo "パスワード" | saslpasswd2 -p -u refirio.net -c info
/etc/sasldb2 というバイナリファイルが生成されるため、所有者を調整する
# chgrp postfix /etc/sasldb2
反映されたか確認
# sasldblistusers2
info@refirio.net: userPassword
… 反映されていれば、メールアドレスが表示される
これで info@refirio.net ユーザが作成されたことになる
PHPMailderなどから送信テストする
一例だが、以下のようにして接続できる
// SMTPサーバ: ホスト
define('SMTP_HOST', 'refirio.net');
// SMTPサーバ: メールアカウント
define('SMTP_USERNAME', 'info@refirio.net');
// SMTPサーバ: メールパスワード
define('SMTP_PASSWORD', 'パスワード');
// SMTPサーバ: プロトコル (ssl または tls)
define('SMTP_SECURE', 'CRAM-MD5');
// SMTPサーバ: 送信ポート (ssl:465, tls:587)
define('SMTP_PORT', '587');
■トラブルとその対応
外部からSMTPで接続できなかった
結論から書くと、サブミッションポートを設定し忘れていたからだった
(設定しないと587番ポートに接続できないみたい)
PHPMailerでメールをSTMP送信する - Qiita
https://qiita.com/e__ri/items/857b12e73080019e00b5
PHPMailerで以下を指定すると、送信時の詳細なログを確認できる
$mail->SMTPDebug = 3;
$mail->Debugoutput = function($str, $level) { echo "debug level $level; message: $str<br>"; };
送信完了した場合は以下のようになる
debug level 3; message: Connection: opening to refirio.net:587, timeout=300, options=array ( )
debug level 3; message: Connection: opened
debug level 2; message: SERVER -> CLIENT: 220 refirio.net ESMTP unknown
debug level 1; message: CLIENT -> SERVER: EHLO localhost
debug level 2; message: SERVER -> CLIENT: 250-refirio.net 250-PIPELINING 250-SIZE 10485760 250-VRFY 250-ETRN 250-AUTH PLAIN LOGIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN
debug level 1; message: CLIENT -> SERVER: AUTH LOGIN
debug level 2; message: SERVER -> CLIENT: 334 VXNlcm5hbWU6
debug level 1; message: CLIENT -> SERVER: aW5mb0BjcmUudGVycmFwb3J0LWRldi5jb20=
debug level 2; message: SERVER -> CLIENT: 334 UGFzc3dvcmQ6
debug level 1; message: CLIENT -> SERVER: SldqeE1xcll4OXM4
debug level 2; message: SERVER -> CLIENT: 235 2.7.0 Authentication successful
debug level 1; message: CLIENT -> SERVER: MAIL FROM:
debug level 2; message: SERVER -> CLIENT: 250 2.1.0 Ok
debug level 1; message: CLIENT -> SERVER: RCPT TO:
debug level 2; message: SERVER -> CLIENT: 250 2.1.5 Ok
debug level 1; message: CLIENT -> SERVER: DATA
debug level 2; message: SERVER -> CLIENT: 354 End data with .
debug level 1; message: CLIENT -> SERVER: Date: Fri, 20 Jan 2023 13:38:55 +0900
debug level 1; message: CLIENT -> SERVER: To: =?UTF-8?B?44Oh44O844Or5Y+X5L+h6ICF?=
debug level 1; message: CLIENT -> SERVER: From: =?UTF-8?B?44Oh44O844Or6YCB5L+h6ICF?=
debug level 1; message: CLIENT -> SERVER: Subject: =?UTF-8?B?5aSW6YOoU01UUOOBi+OCieOBrumAgeS/oeODhuOCueODiA==?=
debug level 1; message: CLIENT -> SERVER: Message-ID: <878c32f7524c55c24bbfa598be314438@localhost>
debug level 1; message: CLIENT -> SERVER: X-Mailer: PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)
debug level 1; message: CLIENT -> SERVER: MIME-Version: 1.0
debug level 1; message: CLIENT -> SERVER: Content-Type: text/plain; charset=UTF-8
debug level 1; message: CLIENT -> SERVER: Content-Transfer-Encoding: base64
debug level 1; message: CLIENT -> SERVER:
debug level 1; message: CLIENT -> SERVER: 44OG44K544OI44Oh44O844Or44CCDQrjgZPjgozjga/lpJbpg6hTTVRQ44GL44KJ44Gu6YCB5L+h
debug level 1; message: CLIENT -> SERVER: 44OG44K544OI44Gn44GZ44CC
debug level 1; message: CLIENT -> SERVER:
debug level 1; message: CLIENT -> SERVER: .
debug level 2; message: SERVER -> CLIENT: 250 2.0.0 Ok: queued as 0C21C456ABB
debug level 1; message: CLIENT -> SERVER: QUIT
debug level 2; message: SERVER -> CLIENT: 221 2.0.0 Bye
debug level 3; message: Connection: closed
接続先を間違えた場合は以下のような内容が表示される
debug level 3; message: Connection: Failed to connect to server. Error number 2. "Error notice: stream_socket_client(): php_network_getaddresses: getaddrinfo failed: 〇〇〇〇〇〇〇〇〇〇
debug level 3; message: Connection: Failed to connect to server. Error number 2. "Error notice: stream_socket_client(): unable to connect to refirio.net:587 (php_network_getaddresses: getaddrinfo failed: 〇〇〇〇〇〇〇〇〇〇 )
debug level 1; message: SMTP ERROR: Failed to connect to server: php_network_getaddresses: getaddrinfo failed: 〇〇〇〇〇〇〇〇〇〇 (0)
debug level 3; message: SMTP connect() failed.
https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
接続ポートを間違えた場合、サブミッションポートの設定がされていない場合は以下のような内容が表示される
debug level 3; message: Connection: Failed to connect to server. Error number 2. "Error notice: stream_socket_client(): unable to connect to refirio.net:24 (〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇 )
debug level 1; message: SMTP ERROR: Failed to connect to server: 〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇 (10060)
debug level 3; message: SMTP connect() failed.
https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
存在しないメールアドレスを指定した場合、間違ったパスワードを指定した場合は以下のような内容が表示される
debug level 2; message: SERVER -> CLIENT: 535 5.7.8 Error: authentication failed: authentication failure
debug level 1; message: SMTP ERROR: Password command failed: 535 5.7.8 Error: authentication failed: authentication failure
debug level 3; message: SMTP Error: Could not authenticate.
プロトコルを「define('SMTP_SECURE', 'CRAM-MD5');」ではなく「define('SMTP_SECURE', 'tls');」と設定した場合は以下のような内容が表示される
debug level 1; message: CLIENT -> SERVER: STARTTLS
debug level 2; message: SERVER -> CLIENT: 502 5.5.1 Error: command not implemented
debug level 1; message: SMTP ERROR: STARTTLS command failed: 502 5.5.1 Error: command not implemented
debug level 3; message: SMTP Error: Could not connect to SMTP host.
debug level 1; message: CLIENT -> SERVER: QUIT
debug level 2; message: SERVER -> CLIENT: 221 2.0.0 Bye
debug level 3; message: Connection: closed
■サーバからの通知メールについて補足
サーバを運用していると、Cron実行時エラーなどがメールで送られてきたりする
ただしSES+Postfixだと、送信元の問題でこういったメールが送られなくなる可能性がある
(SES利用開始時に「検証済みID」で登録した送信元を指定する必要があるが、サーバがデフォルトで通知する内容を完璧に把握して送信元を調整するのは難しい)
対処方法としては
「何とかしてEC2からメールを送る」
ではなく
「ログを記録して、CloudWatchに転送して、必要に応じて警告する」
という流れにするといいみたい
(EC2はデフォルトでポートが制限されているくらいなので、こういったメールを受け取れないからと言って致命的だということは無い…はず)
ECSなどでオートスケーリング構成を取る場合でも同じ
Webサーバは使い捨てにできる前提で構築することが好ましい
サーバからの通知メールに関しては、ひとまず
・Cronの通知は無効にしない(エラーなど重大な通知を含むことがあるので)
・Cronの通知は転送設定をしなければrootのメールボックスに届くので、定期的にメールボックスの内容を確認する
・ただし定期的に手動でチェックするのは大変なので、「毎週月曜日に確認して新着メールがあれば通知」というシェルスクリプトを作る
・Anacronの通知は無効にする(原則完了報告だけなので)
という方針にするか
■SES メール送信ログの設定
Amazon SESには、メール送信ログを確認する方法が提供されていない
Amazon OpenSearch Service や Amazon Elasticsearch Service に記録することはできるらしい
Amazon SES の E メール送信履歴の保存と表示
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ses-email-sending-history/
Amazon SES でのメール送信ログを表示する - DENET 技術ブログ
https://blog.denet.co.jp/amazon-ses-log/
Amazon SESのメール送信ログを記録する - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/2020/12/04/190000
Amazon OpenSearch Service は高額らしいので、S3に保存している例もある
ただしこの場合、S3に保存されたログを確認する手段を自分で用意する必要がある
SESの送信履歴を確認したい
https://zenn.dev/isseeeeey55/articles/61b350c27e1040
SES のログを S3 に出力してバウンスメールを確認してみる - Qiita
https://qiita.com/sugimount-a/items/f9202c676514dcd3d182
Kinesis Data Firehose をゼロからざっくり理解する | DevelopersIO
https://dev.classmethod.jp/articles/amazon-kinesis-data-firehose-for-beginner/
以下は発展形としていつか参考になるかも…くらい
そのメール、本当に届いてる?Amazon SESの運用で得た監視プラクティス - Cybozu Inside Out | サイボウズエンジニアのブログ
https://blog.cybozu.io/entry/2021/11/26/075846
以下を参考に、実際にS3へのログ転送を試してみる
【AWS】AWS SESのログをKinesis Data Firehose経由でS3へ転送してみました - Qiita
https://qiita.com/hyj624117615/items/6bf44f2f86c252e3e00b
s3のライフサイクルルールを設定してみる - Qiita
https://qiita.com/miyuki_samitani/items/cbea495fb116b5bf5db6
以下はS3への保存では無いが、部分的には参考になる
SESのメール送信履歴をOpenSearch Serviceで表示してみた | DevelopersIO
https://dev.classmethod.jp/articles/ses-visualisation-email-sending-history-with-opensearch-service/
【AWS】AWS SESのログをKinesis Data Firehose経由でS3へ転送してみました - Qiita
https://qiita.com/hyj624117615/items/6bf44f2f86c252e3e00b
■S3にバケットを作成
S3 → バケットを作成
バケット名: refirio-ses-log
AWSリージョン: アジアパシフィック(東京)
このバケットのブロックパブリックアクセス設定: パブリックアクセスをすべて ブロック
※「バケットのバージョニング」はデフォルトのまま(無効)とした
「デフォルトの暗号化」はデフォルトのまま(SSE-S3 / 有効にする)とした
■Kinesis Data Firehoseに配信ストリームを作成
Kinesis Data Firehose → 配信ストリームを作成
ソース: Direct PUT
送信先: Amazon S3
配信ストリーム名: refirio-ses-kinesis
S3バケット: s3://refirio-ses-log
S3バケットプレフィックス: ses-log-
S3バケットエラー出力プレフィックス: ses-log-error-
バッファ間隔: 60
※「S3バケット」は上で作成したものを選択
「バッファ間隔」は検証のために60にした。本番運用なら、300のままでいいかもしれない
※「許可」はデフォルトのまま「IAM ロール KinesisFirehoseServiceRole-refirio-ap-northeast-1-1234567890123 を作成または更新」を選択したが、
すでに作成したものがあるならそれを使えば良さそう(2回目以降に作成する場合など)
作成すると「refirio-ses-kinesis の作成中。ステータスが更新されるまでに最大5分かかる場合があります。」と表示されるので待つ
「配信ストリームを作成」ボタン押して以下のエラーが作成された場合、作業しているユーザの権限を確認する
配信ストリームは作成されませんでした
配信ストリーム refirio-ses-kinesis の作成に必要な許可がありません。IAM 許可を確認して変更し、このユーザーに必要な許可が付与されているようにしてください。
アクション: iamadmin:CreateServiceRole/CreatePolicyForServiceRole/UpdateServiceRolePolicy
ユーザー: arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_PowerUserAccess_1db0a2445f639f21/refirio
APIレスポンス: User: arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_PowerUserAccess_1db0a2445f639f21/refirio is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::123456789012:role/service-role/KinesisFirehoseServiceRole-refirio-ap-northeast-1-1674707361061 because no identity-based policy allows the iam:CreateRole action
■SESを設定
Amazon Simple Email Service → 設定セット → セットの作成
設定セット名: refirio-ses-log
※設定セットは引き続きの設定が必要だが、このタイミングでいったんIAMポリシーとIAMロールを作成する
■IAMポリシーを作成
Identity and Access Management (IAM) → ポリシー → ポリシーを作成
「JSON」タブで以下を入力する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "0",
"Effect": "Allow",
"Action": "firehose:ListDeliveryStreams",
"Resource": "*"
},
{
"Sid": "1",
"Effect": "Allow",
"Action": "firehose:*",
"Resource": "arn:aws:firehose:*:123456789012:deliverystream/*"
}
]
}
※「123456789012」部分にはAWSのIDを入力する
名前: ses-log-policy
これでポリシーを作成する
■IAMロールを作成
Identity and Access Management (IAM) → ロール → ロールを作成
「信頼されたエンティティタイプ」で「カスタム信頼ポリシー」を選択し、表示される「カスタム信頼ポリシー」欄に以下を入力する
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ses.amazonaws.com"
]
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "123456789012",
"AWS:SourceArn": "arn:aws:ses:ap-northeast-1:123456789012:configuration-set/refirio-ses-log"
}
}
}
]
}
※「123456789012」部分にはAWSのIDを、「refirio-ses-log」部分には設定セット名をそれぞれ入力する
「許可を追加」で「IAMポリシーを作成」の手順で作成したポリシー(ses-log-policy)を選択
名前: ses-log-role
これでロールを作成する
■SESを設定(続き)
Amazon Simple Email Service → 設定セット → refirio-ses-log → イベント送信先 → 送信先の追加
※「refirio-ses-log」は上の手順で作成した設定セット
今回はイベントタイプの選択で
「送信」「拒否」「配信」「ハードバウンス」「苦情数」「配信の遅延」「サブスクリプション」
にチェックを入れてみる
※イベントタイプの内容を絞ることでコストを最適化できるみたい
送信先の指定は
送信先タイプ: Amazon Kinesis Data Firehose
名前: refirio-ses-log
配信ストリーム: refirio-ses-kinesis
Identity and Access Management (IAM) ロール: ses-log-role
※「配信ストリーム」は上で作成したものを選択
※「Identity and Access Management (IAM) ロール」は上で作成したものを選択
■メール送信テスト
Amazon Simple Email Service → 検証済みID → refirio.net → テストEメールの送信
Eメール形式: フォーマット済み
From-address: info@refirio.net
シナリオ: 配信の成功
件名: 送信テスト
本文: これは送信テストです。
設定セット: refirio-ses-log
※「設定セット」は上で作成したものを選択
「テストEメールの送信」ボタンをクリック(実際にメールは送信されない)
2〜3分ほど待つと、refirio-ses-log バケット内にフォルダが作成された
refirio-ses-log/ses-log-2023/01/26/06/refirio-ses-kinesis-1-2023-01-26-06-32-55-4459a487-45e3-41ad-80ca-d53999eeddc2
{"eventType":"Delivery","mail":{"timestamp":"2023-01-26T06:32:14.171Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185ecc6de5b-7376664e-c6e8-4a33-9d11-a8f8be738b5e-000000","destination":["success@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"info@refirio.net"},{"name":"To","value":"success@simulator.amazonses.com"},{"name":"Subject","value":"送信テスト"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\"----=_Part_80348_1716894568.1674714734175\""}],"commonHeaders":{"from":["info@refirio.net"],"to":["success@simulator.amazonses.com"],"messageId":"01060185ecc6de5b-7376664e-c6e8-4a33-9d11-a8f8be738b5e-000000","subject":"送信テスト"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["refirio-user"],"ses:outgoing-ip":["23.251.234.1"]}},"delivery":{"timestamp":"2023-01-26T06:32:15.224Z","processingTimeMillis":1053,"recipients":["success@simulator.amazonses.com"],"smtpResponse":"250 2.6.0 Message received","reportingMTA":"e234-1.smtp-out.ap-northeast-1.amazonses.com"}}
{"eventType":"Send","mail":{"timestamp":"2023-01-26T06:32:14.171Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185ecc6de5b-7376664e-c6e8-4a33-9d11-a8f8be738b5e-000000","destination":["success@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"info@refirio.net"},{"name":"To","value":"success@simulator.amazonses.com"},{"name":"Subject","value":"送信テスト"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\"----=_Part_80348_1716894568.1674714734175\""}],"commonHeaders":{"from":["info@refirio.net"],"to":["success@simulator.amazonses.com"],"messageId":"01060185ecc6de5b-7376664e-c6e8-4a33-9d11-a8f8be738b5e-000000","subject":"送信テスト"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["refirio-user"]}},"send":{}}
それらしいものが格納されている
再度テストEメールを送信してみる。今回はシナリオで「バウンス」を選択して送信してみる
2〜3分ほど待つと、新たにファイルが作成された
refirio-ses-log/ses-log-2023/01/26/06/refirio-ses-kinesis-1-2023-01-26-06-38-14-c5d40628-51e3-4636-88e9-681b3e08ac53
{"eventType":"Send","mail":{"timestamp":"2023-01-26T06:37:30.930Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185eccbb3b2-7b3a8bc1-aebd-4f35-b385-369eb6fd1691-000000","destination":["bounce@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"info@refirio.net"},{"name":"To","value":"bounce@simulator.amazonses.com"},{"name":"Subject","value":"送信テスト(バウンス)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\"----=_Part_3104396_282462092.1674715050933\""}],"commonHeaders":{"from":["info@refirio.net"],"to":["bounce@simulator.amazonses.com"],"messageId":"01060185eccbb3b2-7b3a8bc1-aebd-4f35-b385-369eb6fd1691-000000","subject":"送信テスト(バウンス)"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["refirio-user"]}},"send":{}}
{"eventType":"Bounce","bounce":{"feedbackId":"01060185eccbb630-c60c6634-7090-4b79-aabc-b6e2b08d9af2-000000","bounceType":"Permanent","bounceSubType":"General","bouncedRecipients":[{"emailAddress":"bounce@simulator.amazonses.com","action":"failed","status":"5.1.1","diagnosticCode":"smtp; 550 5.1.1 user unknown"}],"timestamp":"2023-01-26T06:37:31.687Z","reportingMTA":"dns; e234-2.smtp-out.ap-northeast-1.amazonses.com"},"mail":{"timestamp":"2023-01-26T06:37:30.930Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185eccbb3b2-7b3a8bc1-aebd-4f35-b385-369eb6fd1691-000000","destination":["bounce@simulator.amazonses.com"],"headersTruncated":false,"headers":[{"name":"From","value":"info@refirio.net"},{"name":"To","value":"bounce@simulator.amazonses.com"},{"name":"Subject","value":"送信テスト(バウンス)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"multipart/alternative; boundary=\"----=_Part_3104396_282462092.1674715050933\""}],"commonHeaders":{"from":["info@refirio.net"],"to":["bounce@simulator.amazonses.com"],"messageId":"01060185eccbb3b2-7b3a8bc1-aebd-4f35-b385-369eb6fd1691-000000","subject":"送信テスト(バウンス)"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["refirio-user"]}}}
「メール1送信=1ファイル」でログが作成されている
■デフォルト設定セットの割り当て
Amazon Simple Email Service → 検証済みID → refirio.net → 設定セット → 編集
デフォルト設定セットの割り当て: (チェックを入れる)
デフォルト設定セット: refirio-ses-log
※「デフォルト設定セット」は上で作成したものを選択
これでメール送信時に「設定セット」を指定しなくても、自動的に設定セットが割り当てられる
SMTPからのメール送信なども、自動的に設定セットが使用される
■古いログの自動削除
S3 → refirio-ses-log → 管理 → ライフサイクルルールを作成する
ライフサイクルルール名: refirio-ses-log-delete
ルールスコープを選択: バケット内のすべてのオブジェクトに適用
バケット内のすべてのオブジェクトに適用: (チェックを入れる)
ライフサイクルルールのアクション: オブジェクトの現行バージョンを有効期限切れにする
オブジェクト作成後の日数: 3
※アクションは「有効期限切れ=S3から削除される」ということらしい
「オブジェクト作成後の日数」は検証のために3にした。本番運用なら、90(=3ヶ月)など適宜設定する
※本当に削除されるか確認したところ、
・2023/01/26 03:30 のファイル(12:30 のファイル)で確認
・2023/01/30 時点で削除されずに残っていた
・2023/01/31 時点で削除されていた
となっていた。ピッタリ3日では無いようだが、自動的に削除されていることは確認できた
■Postfix経由での送信
「SES PostfixからSMTPでメールを送信」の手順をもとに、Postfixを経由してSESからメール送信できるようにする
また、外部からPostfixのアカウントを経由してSESからメール送信できるようにもする
この状態で送信テストし、どのようにログが記録されるか確認
外部のPHPからSMTPを直接叩いてメール送信した場合、S3には以下のログが記録された
{"eventType":"Delivery","mail":{"timestamp":"2023-01-27T02:36:17.921Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f1153881-050e347e-1c63-4627-a941-b146682babf0-000000","destination":["example@gmail.com"],"headersTruncated":false,"headers":[{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-EQ3QJVK0M) id MAvuw8Xe28pKGsVJ1b6I for example@gmail.com; Fri, 27 Jan 2023 02:36:17 +0000 (UTC)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:36:17 +0900"},{"name":"To","value":"メール受信者 <example@gmail.com>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからの送信テスト"},{"name":"Message-ID","value":"<0b123d8412043e673ccc717b26354311@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:36:17 +0900","to":["\"メール受信者\" <example@gmail.com>"],"messageId":"01060185f1153881-050e347e-1c63-4627-a941-b146682babf0-000000","subject":"外部SMTPからの送信テスト"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"],"ses:outgoing-ip":["23.251.234.3"]}},"delivery":{"timestamp":"2023-01-27T02:36:19.434Z","processingTimeMillis":1513,"recipients":["example@gmail.com"],"smtpResponse":"250 2.0.0 OK 1674786979 m3-20020a17090a730300b002297f945cf0si3008883pjk.57 - gsmtp","reportingMTA":"e234-3.smtp-out.ap-northeast-1.amazonses.com"}}
{"eventType":"Send","mail":{"timestamp":"2023-01-27T02:36:17.921Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f1153881-050e347e-1c63-4627-a941-b146682babf0-000000","destination":["example@gmail.com"],"headersTruncated":false,"headers":[{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-EQ3QJVK0M) id MAvuw8Xe28pKGsVJ1b6I for example@gmail.com; Fri, 27 Jan 2023 02:36:17 +0000 (UTC)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:36:17 +0900"},{"name":"To","value":"メール受信者 <example@gmail.com>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからの送信テスト"},{"name":"Message-ID","value":"<0b123d8412043e673ccc717b26354311@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:36:17 +0900","to":["\"メール受信者\" <example@gmail.com>"],"messageId":"01060185f1153881-050e347e-1c63-4627-a941-b146682babf0-000000","subject":"外部SMTPからの送信テスト"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["203.0.113.1"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"]}},"send":{}}
EC2を経由していないので、EC2の /var/log/maillog には何も記録されていない
外部のPHPからEC2経由でメール送信した場合、S3には以下のログが記録された
{"eventType":"Delivery","mail":{"timestamp":"2023-01-27T02:36:51.061Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f115b9f5-0a7e240a-54ef-49e9-9725-b77a002bd950-000000","destination":["example@gmail.com"],"headersTruncated":false,"headers":[{"name":"Received","value":"from refirio.net (ec2-3-113-235-47.ap-northeast-1.compute.amazonaws.com [3.113.235.47]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-1B60FHL0M) id BqzsiwDa4Rkwhg0fCpCS for example@gmail.com; Fri, 27 Jan 2023 02:36:51 +0000 (UTC)"},{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by refirio.net (Postfix) with ESMTPA id BAF64CAF15C for <example@gmail.com>; Fri, 27 Jan 2023 11:36:50 +0900 (JST)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:36:50 +0900"},{"name":"To","value":"メール受信者 <example@gmail.com>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからの送信テスト2"},{"name":"Message-ID","value":"<5e0f33a5a5e0e2bed18ad4a102047b1e@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:36:50 +0900","to":["\"メール受信者\" <example@gmail.com>"],"messageId":"01060185f115b9f5-0a7e240a-54ef-49e9-9725-b77a002bd950-000000","subject":"外部SMTPからの送信テスト2"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["3.113.235.47"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"],"ses:outgoing-ip":["23.251.234.5"]}},"delivery":{"timestamp":"2023-01-27T02:36:52.514Z","processingTimeMillis":1453,"recipients":["example@gmail.com"],"smtpResponse":"250 2.0.0 OK 1674787012 12-20020a17090a034c00b002264d5dfc15si6926883pjf.113 - gsmtp","reportingMTA":"e234-5.smtp-out.ap-northeast-1.amazonses.com"}}
{"eventType":"Send","mail":{"timestamp":"2023-01-27T02:36:51.061Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f115b9f5-0a7e240a-54ef-49e9-9725-b77a002bd950-000000","destination":["example@gmail.com"],"headersTruncated":false,"headers":[{"name":"Received","value":"from refirio.net (ec2-3-113-235-47.ap-northeast-1.compute.amazonaws.com [3.113.235.47]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-1B60FHL0M) id BqzsiwDa4Rkwhg0fCpCS for example@gmail.com; Fri, 27 Jan 2023 02:36:51 +0000 (UTC)"},{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by refirio.net (Postfix) with ESMTPA id BAF64CAF15C for <example@gmail.com>; Fri, 27 Jan 2023 11:36:50 +0900 (JST)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:36:50 +0900"},{"name":"To","value":"メール受信者 <example@gmail.com>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからの送信テスト2"},{"name":"Message-ID","value":"<5e0f33a5a5e0e2bed18ad4a102047b1e@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:36:50 +0900","to":["\"メール受信者\" <example@gmail.com>"],"messageId":"01060185f115b9f5-0a7e240a-54ef-49e9-9725-b77a002bd950-000000","subject":"外部SMTPからの送信テスト2"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["3.113.235.47"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"]}},"send":{}}
EC2の /var/log/maillog には以下のとおり送信成功が記録されている
Jan 27 11:36:50 ip-10-1-0-47 postfix/smtpd[3863]: connect from example.com[203.0.113.1]
Jan 27 11:36:50 ip-10-1-0-47 postfix/smtpd[3863]: BAF64CAF15C: client=example.com[203.0.113.1], sasl_method=LOGIN, sasl_username=info@refirio.net
Jan 27 11:36:50 ip-10-1-0-47 postfix/cleanup[3867]: BAF64CAF15C: message-id=<5e0f33a5a5e0e2bed18ad4a102047b1e@localhost>
Jan 27 11:36:50 ip-10-1-0-47 postfix/qmgr[3857]: BAF64CAF15C: from=<info@refirio.net>, size=795, nrcpt=1 (queue active)
Jan 27 11:36:50 ip-10-1-0-47 postfix/smtpd[3863]: disconnect from example.com[203.0.113.1]
Jan 27 11:36:50 ip-10-1-0-47 postfix/smtp[3868]: Trusted TLS connection established to email-smtp.ap-northeast-1.amazonaws.com[203.0.113.2]:587: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Jan 27 11:36:51 ip-10-1-0-47 postfix/smtp[3868]: BAF64CAF15C: to=<example@gmail.com>, relay=email-smtp.ap-northeast-1.amazonaws.com[203.0.113.2]:587, delay=0.52, delays=0.11/0.02/0.14/0.25, dsn=2.0.0, status=sent (250 Ok 01060185f115b9f5-0a7e240a-54ef-49e9-9725-b77a002bd950-000000)
Jan 27 11:36:51 ip-10-1-0-47 postfix/qmgr[3857]: BAF64CAF15C: removed
存在しないメールアドレスに対して、外部のPHPからEC2経由でメール送信した場合、S3には以下のログが記録された
{"eventType":"Bounce","bounce":{"feedbackId":"01060185f11ae6a9-8857de58-a91b-4e05-95d0-91f01b7e91c6-000000","bounceType":"Permanent","bounceSubType":"General","bouncedRecipients":[{"emailAddress":"abcdxxx@refirio.net","action":"failed","status":"5.1.1","diagnosticCode":"smtp; 550 5.1.1 <abcdxxx@refirio.net>: Recipient address rejected: User unknown in relay recipient table"}],"timestamp":"2023-01-27T02:42:30.322Z","reportingMTA":"dns; e234-2.smtp-out.ap-northeast-1.amazonses.com"},"mail":{"timestamp":"2023-01-27T02:42:29.554Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f11ae432-60aab4e8-b3a4-4f40-9b8b-886d027b3c50-000000","destination":["abcdxxx@refirio.net"],"headersTruncated":false,"headers":[{"name":"Received","value":"from refirio.net (ec2-3-113-235-47.ap-northeast-1.compute.amazonaws.com [3.113.235.47]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-XLR0CNL0M) id jWkq9bUZroC04PmhwDve for abcdxxx@refirio.net; Fri, 27 Jan 2023 02:42:29 +0000 (UTC)"},{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by refirio.net (Postfix) with ESMTPA id 47471CAF15C for <abcdxxx@refirio.net>; Fri, 27 Jan 2023 11:42:29 +0900 (JST)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:42:29 +0900"},{"name":"To","value":"メール受信者 <abcdxxx@refirio.net>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからのバウンスメールテスト"},{"name":"Message-ID","value":"<44c8337f6dbf9e4d37ce2fb7eedc0a41@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:42:29 +0900","to":["\"メール受信者\" <abcdxxx@refirio.net>"],"messageId":"01060185f11ae432-60aab4e8-b3a4-4f40-9b8b-886d027b3c50-000000","subject":"外部SMTPからのバウンスメールテスト"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["3.113.235.47"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"]}}}
{"eventType":"Send","mail":{"timestamp":"2023-01-27T02:42:29.554Z","source":"info@refirio.net","sourceArn":"arn:aws:ses:ap-northeast-1:123456789012:identity/refirio.net","sendingAccountId":"123456789012","messageId":"01060185f11ae432-60aab4e8-b3a4-4f40-9b8b-886d027b3c50-000000","destination":["abcdxxx@refirio.net"],"headersTruncated":false,"headers":[{"name":"Received","value":"from refirio.net (ec2-3-113-235-47.ap-northeast-1.compute.amazonaws.com [3.113.235.47]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-XLR0CNL0M) id jWkq9bUZroC04PmhwDve for abcdxxx@refirio.net; Fri, 27 Jan 2023 02:42:29 +0000 (UTC)"},{"name":"Received","value":"from localhost (example.com [203.0.113.1]) by refirio.net (Postfix) with ESMTPA id 47471CAF15C for <abcdxxx@refirio.net>; Fri, 27 Jan 2023 11:42:29 +0900 (JST)"},{"name":"Date","value":"Fri, 27 Jan 2023 11:42:29 +0900"},{"name":"To","value":"メール受信者 <abcdxxx@refirio.net>"},{"name":"From","value":"メール送信者 <info@refirio.net>"},{"name":"Subject","value":"外部SMTPからのバウンスメールテスト"},{"name":"Message-ID","value":"<44c8337f6dbf9e4d37ce2fb7eedc0a41@localhost>"},{"name":"X-Mailer","value":"PHPMailer 5.2.19 (https://github.com/PHPMailer/PHPMailer)"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"base64"}],"commonHeaders":{"from":["\"メール送信者\" <info@refirio.net>"],"date":"Fri, 27 Jan 2023 11:42:29 +0900","to":["\"メール受信者\" <abcdxxx@refirio.net>"],"messageId":"01060185f11ae432-60aab4e8-b3a4-4f40-9b8b-886d027b3c50-000000","subject":"外部SMTPからのバウンスメールテスト"},"tags":{"ses:operation":["SendSmtpEmail"],"ses:configuration-set":["refirio-ses-log"],"ses:source-ip":["3.113.235.47"],"ses:from-domain":["refirio.net"],"ses:caller-identity":["cre-test-smtp-user.20220726"]}},"send":{}}
EC2の /var/log/maillog には以下のとおり送信成功が記録されている
SESへのリレー自体は成功しているから…だと思われる
つまり送信ログからエラーを検知したければ、/var/log/maillog ではなくS3の方を調べる必要がある
Jan 27 11:42:29 ip-10-1-0-47 postfix/smtpd[3884]: connect from example.com[203.0.113.1]
Jan 27 11:42:29 ip-10-1-0-47 postfix/smtpd[3884]: 47471CAF15C: client=example.com[203.0.113.1], sasl_method=LOGIN, sasl_username=info@refirio.net
Jan 27 11:42:29 ip-10-1-0-47 postfix/cleanup[3888]: 47471CAF15C: message-id=<44c8337f6dbf9e4d37ce2fb7eedc0a41@localhost>
Jan 27 11:42:29 ip-10-1-0-47 postfix/qmgr[3857]: 47471CAF15C: from=<info@refirio.net>, size=846, nrcpt=1 (queue active)
Jan 27 11:42:29 ip-10-1-0-47 postfix/smtpd[3884]: disconnect from example.com[203.0.113.1]
Jan 27 11:42:29 ip-10-1-0-47 postfix/smtp[3889]: Trusted TLS connection established to email-smtp.ap-northeast-1.amazonaws.com[203.0.113.2]:587: TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
Jan 27 11:42:29 ip-10-1-0-47 postfix/smtp[3889]: 47471CAF15C: to=<abcdxxx@refirio.net>, relay=email-smtp.ap-northeast-1.amazonaws.com[203.0.113.2]:587, delay=0.52, delays=0.12/0.01/0.13/0.27, dsn=2.0.0, status=sent (250 Ok 01060185f11ae432-60aab4e8-b3a4-4f40-9b8b-886d027b3c50-000000)
Jan 27 11:42:29 ip-10-1-0-47 postfix/qmgr[3857]: 47471CAF15C: removed
なお、S3に格納される際のファイル名は、先に記載したとおり refirio-ses-log/ses-log-2023/01/26/06/refirio-ses-kinesis-1-2023-01-26-06-32-55-4459a487-45e3-41ad-80ca-d53999eeddc2 のような場所と名前になる
日付や時間が含まれているが、これはUTCの日時となっている(テストメールでなければ、ファイル内に日本時間が記録される)
特定の日付のメールを丸ごと取得するような場合、時差を考慮してデータを取得する必要があるので注意
■プログラムからのメール送信ログ確認
一例だが、以下のようなPHPプログラムでログを表示できる
SDKの導入については「AWS SDK(バージョン3)」を参照
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
define('AWS_KEY', 'XXXXX');
define('AWS_SECRET', 'YYYYY');
define('AWS_REGION', 'ap-northeast-1');
define('AWS_S3_BUCKET', 'refirio-ses-log');
define('AWS_S3_SES_PREFIX', 'ses-log-');
define('AWS_S3_SES_DATE', '2023/01/27');
$logs = [];
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$client = new S3Client([
'credentials' => [
'key' => AWS_KEY,
'secret' => AWS_SECRET,
],
'region' => AWS_REGION,
'version' => 'latest',
]);
// ディレクトリの一覧を取得
$result = $client->listObjects([
'Bucket' => AWS_S3_BUCKET,
'Prefix' => AWS_S3_SES_PREFIX . AWS_S3_SES_DATE . '/',
'Delimiter' => '/',
]);
$directories = [];
foreach ($result['CommonPrefixes'] as $prefix) {
$directories[] = $prefix['Prefix'];
}
// ファイルの一覧を取得
$files = [];
foreach ($directories as $directory) {
$result = $client->listObjects([
'Bucket' => AWS_S3_BUCKET,
'Prefix' => $directory,
'Delimiter' => '/',
]);
foreach ($result['Contents'] as $content) {
$files[] = $content['Key'];
}
}
// ログの内容を取得
foreach ($files as $file) {
$result = $client->getObject([
'Bucket' => AWS_S3_BUCKET,
'Key' => $file,
]);
$lines = explode("\n", $result['Body']);
foreach ($lines as $line) {
if (empty($line)) {
continue;
}
$logs[] = json_decode($line, true);
}
}
} catch (S3Exception $e) {
exit('S3Exception: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
echo "<table border=\"1\">\n";
echo "<tr>\n";
echo "<th>eventType</td>\n";
echo "<th>timestamp</td>\n";
echo "<th>messageId</td>\n";
echo "<th>source</td>\n";
echo "<th>destination</td>\n";
echo "<th>headers From</td>\n";
echo "<th>headers To</td>\n";
echo "<th>headers Subject</td>\n";
echo "</tr>\n";
foreach ($logs as $data) {
if ($data['eventType'] == 'Send') {
continue;
}
$headers = [];
foreach ($data['mail']['headers'] as $header) {
$headers[$header['name']] = $header['value'];
}
echo "<tr>\n";
echo "<td>" . $data['eventType'] . "</td>\n";
echo "<td>" . date('Y-m-d H:i:s', strtotime($data['mail']['timestamp'])) . "</td>\n";
echo "<td>" . $data['mail']['messageId'] . "</td>\n";
echo "<td>" . $data['mail']['source'] . "</td>\n";
echo "<td>" . implode(', ', $data['mail']['destination']) . "</td>\n";
echo "<td>" . $headers['From'] . "</td>\n";
echo "<td>" . $headers['To'] . "</td>\n";
echo "<td>" . $headers['Subject'] . "</td>\n";
echo "</tr>\n";
}
echo "</table>\n";
■バウンスメールの設定
別途バウンスメールの設定をしておくといい
メールログからバウンスメールが発生したことを確認できたとしても、バウンスメールほどの情報量が無い
詳細は、このファイル内の「SES メール送信 > バウンスメールの設定」を参照
■引き続き
ログファイル名、ログファイルの内容とも9時間の時差がある(1月26日19時に送ったものが1月26日10時として記録された)
調整できるか
■SES メール受信
AWS SESでメールを受信してS3へ保管してみる
http://qiita.com/foxtrack/items/435bd6a77a04c23e03f3
[新機能]Amazon SES でメール受信が出来るようになりました!
http://dev.classmethod.jp/cloud/receiving-email-with-amazon-ses/
[ACM] SSL証明書発行時のドメイン認証メールをSESで受け取ってみた
http://dev.classmethod.jp/cloud/aws/acm-verifydomain-ses/
■AWS SES ドメイン設定設定
SES → Domains → Verify a New Domain
Domain: refirio.net
「Verify This Domain」をクリックすると、以下が表示された
(「ドメイン認証用のTXTレコード」と「メール着信先を示すMXレコード})
Domain Verification Record
Name Type Value
_amazonses.refirio.net TXT oKdxQRp67rLugqoSyc8ts6fWA7utUxu1dUifEdxPmX0=
Email Receiving Record
Name Type Value
refirio.net MX 10 inbound-smtp.us-east-1.amazonaws.com
「Use Route 53」をクリック
ドメインがRoute53のHostedZoneで管理されている場合、次に「Use Route53」の画面が表示される
Create Record Sets
Name Type Value
_amazonses.refirio.net TXT oKdxQRp67rLugqoSyc8ts6fWA7utUxu1dUifEdxPmX0=
Email Receiving Record
Name Type Value
refirio.net MX 10 inbound-smtp.us-east-1.amazonaws.com
Hosted Zones
refirio.net. - develop
「Domain Verification Record」「Email Receiving Record」「Hosted Zones」にチェックを入れる
(「Domain Verification Record」「Hosted Zones」は初めからチェックが入っていた)
「Create Record Sets」をクリックすると、Route53にレコードが登録される
(既存の設定があると置き換えられるので注意)
■AWS SES 設定確認
Route53の「Hosted zones」に移動し、MXレコードとTXTレコードが追加されていることを確認する
SESの「Domains」に移動し、該当ドメインの「Status」が「verified」になっていることを確認する(反映されるまで5分ほどかかる)
■AWS SES メール受信設定
SES → Email Receiving → Rule Sets → Create a Receipt Rule
Step 1: Recipients
受信したいメールアドレスを登録する。登録しなければ、ドメインに届いたすべてのメールを受信するみたい
Recipient: admin@refirio.net
「Add Recipient」をクリック
「Next Step」をクリック
Step 2: Actions
受信メールに対する処理を設定する。
1. S3
S3 bucket: ses-develop
Object key prefix: refirio.net
2. Stop Rule Set
(設定なし)
「Next Step」をクリック
Step 3: Rule details
Rule name: received
「Next Step」をクリック
Step 4: Review
内容を確認して「Create Rule」をクリック
ルール一覧に「Enabled」というステータスとともに反映されているのを確認する
■メール受信テスト
送信先: admin@refirio.net
件名: SESへの送信テスト
本文: テスト。これはSESへの送信テストです。
メールを送信すると、すぐにS3に保存されているのを確認できた
■メーラーでメールを受信
「Amazon WorkMail」を使えば、Webメールだけでなくメーラーでメールを受信することもできるようになる
詳細は後述の「Amazon WorkMail」を参照
「Amazon WorkMail」を使わない場合、メール転送で対応する必要がある
詳細は後述の「SES メール転送」を参照
■その他参考
S3 静的ウェブサイトにサーバーレスなお問い合わせフォームを実装してみた(Amazon SES + AWS Lambda + API Gateway) | DevelopersIO
https://dev.classmethod.jp/articles/serverless-mailform-s3-website-hosting/
■SES メール転送
※未検証
SESやS3からPOP3でメールを読みだすことはできない
そのような運用をしたければ
・Amazon WorkMail を使う(AWSのマネージドメーラー。有料サービス)
・Lamdaで転送する
のいずれかを行うことになる
以下、Lamdaで転送するために調べた内容(未検証)
見ながらやろう! AWSを使った「簡単!! 独自ドメインの送受信システム構築」#前編 - Qiita
https://qiita.com/nago3/items/bdcbc7fac604aea9b2c1
見ながらやろう! AWSを使った「簡単!! 独自ドメインの送受信システム構築」#後編 - Qiita
https://qiita.com/nago3/items/df0d4705841d22404d10
aws-lambda-ses-forwarder/index.js at master - arithmetric/aws-lambda-ses-forwarder - GitHub
https://github.com/arithmetric/aws-lambda-ses-forwarder/blob/master/index.js
SESで受信したメールをLambdaで別の宛先に転送してみた | DevelopersIO
https://dev.classmethod.jp/articles/ses-lambda-mail-transfer/
Amazon SESで受信したメールを転送したい - Qiita
https://qiita.com/onooooo/items/0ba9438f502bfcc39e88
EC2を使わないAWSでメール送信/受信(転送)(SES + S3 + Lambda) - 技術メモ
https://www.tech-note.info/entry/ses_s3_lambda
AWS SESでメールを受信してGmailに転送する
https://sunday-morning.app/posts/2021-03-16-aws-ses-forward-to-gmail
■Amazon WorkMail
Amazon WorkMail(安全な企業向け E メールおよびカレンダーサービス)| AWS
https://aws.amazon.com/jp/workmail/
マネージドなメールサービス
利用料金は、1ユーザーあたり1か月につき4USD
最大25人のユーザーを対象とした、30日間の無料試用期間がある
メールクライアントは、Microsoft Outlook、Apple Mail、Mozilla Thunderbird などにも対応している
アカウントを発行するとIMAPの情報が発行される
SESのSMTP情報(別途発行する)と組み合わせて
・受信サーバーにはWorkMailのIMAP情報を指定する
・送信サーバーにはSESのSMTP情報を指定する
とすることで、通常のメーラーでの送受信もできる
以下はWorkMailのデメリットメモ
・利用人数が多い場合に、アカウント料金が高額になる可能性がある
・日本リージョンが無い。メールデータが国内に保存されないので、案件の規約などに引っかからないかは確認が必要
・日本の携帯メールに届くかは要確認(SESと同じだと思われる)
・メールクライアントで受信する場合はIMAPのみ(POPは非対応なので、例えばGmailはクライアントに使用できない)
以下、参考になりそうなページをメモ
【AWS】独自ドメインを取得しメールサービスを構築してみた|コラム|クラウドソリューション|サービス|法人のお客さま|NTT東日本
https://business.ntt-east.co.jp/content/cloudsolution/column-try-34.html
自社メールをAmazon WorkMailへ移行してみた | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2021-03-02-101058/
Amazon WorkMailのメリット|できることや始め方も紹介 | ITエンジニアの派遣なら夢テクノロジー
https://www.yume-tec.co.jp/column/awsengineer/4511
Amazon WorkMail で独自ドメインのメール設定 - Qiita
https://qiita.com/stangler/items/5a73458b27c831db42fe
Amazon WorkMailを初めてさわってみました - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/workmail
Microsoft Outlook、Apple Mail、Mozilla Thunderbird などでの送受信にも対応しているみたい
よくある質問 - Amazon WorkMail | AWS
https://aws.amazon.com/jp/workmail/faqs/
Amazon WorkMail 用の IMAP の設定 - Amazon WorkMail
https://docs.aws.amazon.com/ja_jp/workmail/latest/userguide/using_IMAP.html
■SNS
※メールに通知する場合、
「トピック作成 → AWSにメールアドレス登録 → AWSから送信される英語メールでURLをクリックして送信承認」
という承認が必要なフローとなるので注意
通常のメール送信の代替になるものではないみたい。関係者への一斉通知などに使うものみたい
[基本操作]Amazon SNSでメールを送信する | Developers.IO
https://dev.classmethod.jp/cloud/aws/amazon-sns-2017/
■トピックの作成
Simple Notification Service → 今すぐ始める → トピック → 新しいトピックの作成
トピック名: SNS-Sample (半角英数字で入力)
表示名: SNSの動作テスト
入力したら「トピックの作成」をクリックする
■送信先の追加(Emailの場合)
作成したトピックを選択し、「アクション → トピックへのサブスクリプション」を選択する
プロトコル: Email
エンドポイント: (送信先となる任意のメールアドレス)
入力したら「サブスクリプションの作成」をクリックする
登録したメールアドレスに「AWS Notification - Subscription Confirmation」というメールが送信される
本文に記載されているURLをクリックすると「Subscription confirmed!」と表示され、承認される
追加したメールアドレスは、トピック一覧で「ARN」のリンクをクリックすると確認できる
■通知の作成と送信(Emailの場合)
トピック一覧画面でトピックを選択し、「トピックに発行」ボタンを押す
もしくは各々のトピックの画面で「トピックに発行」ボタンを押す
件名: Amazon SNS のテスト(メールの件名)
メッセージ形式: Raw
メッセージ: テスト。これは Amazon SNS のテストです。(メールの本文)
と入力し、「メッセージの発行」ボタンを押す
登録したメールアドレスに対し、一斉にメールが送信される
届いたメールの最後には、以下の文言が挿入されている
前のURLは配信停止を行うためのリンク。クリックすると、メッセージの送信先から直ちに削除された
メッセージを変更したり削除したり…という機能は見当たらない
ただしCLIから「トピック所有者のみ購読解除できる」という設定にできるみたい
Amazon SNSのUnsubscribeのリンクを無効化する - Qiita
https://qiita.com/mitsubachi/items/ac0bd90e15ce6098cb87
「その他トピックの操作」にある「トピックのポリシーの編集」や「トピックの配信ポリシーの編集」から設定できるかも?要調査
■送信先の追加(HTTPの場合)
プロトコル: HTTP
エンドポイント:
http://example.com/aws-sns/post.php
入力したら「サブスクリプションの作成」をクリックする
なお、post.php にはあらかじめ以下を記述しておく
post.txt も作成しておき、書き込み権限を与えておく
file_put_contents('post.txt', file_get_contents('php://input'));
exit('OK');
サブスクリプション一覧に表示されたら、それに対して「リクエストの確認」を行う
post.txt に以下の内容が記録された
{
"Type" : "SubscriptionConfirmation",
"MessageId" : "079b5019-25a3-444e-a2a4-97f6e2755001",
"Token" : "2336412f37fb687f5d51e6e241da92fd72d76856412a51e0d9c1e0c2b2f8910cb52e3563d2b095c292b263025a160cf0c180dde14d6e40577ee2736bf042f3b4db127384b2f1526966f79855f573ecfad373c2e26ca0934996c4fe3bb5be7f776bd242ae06e4ecbe5a94ebd928d56e226b31e659713311827387cf248b983444",
"TopicArn" : "arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample",
"Message" : "You have chosen to subscribe to the topic arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample.\nTo confirm the subscriptionDataBuilder, visit the SubscribeURL included in this message.",
"SubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=ConfirmSubscription&TopicArn=arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample&Token=2336412f37fb687f5d51e6e241da92fd72d76856412a51e0d9c1e0c2b2f8910cb52e3563d2b095c292b263025a160cf0c180dde14d6e40577ee2736bf042f3b4db127384b2f1526966f79855f573ecfad373c2e26ca0934996c4fe3bb5be7f776bd242ae06e4ecbe5a94ebd928d56e226b31e659713311827387cf248b983444",
"Timestamp" : "2018-07-11T12:48:47.567Z",
"SignatureVersion" : "1",
"Signature" : "Od9wdcWzD6THORNxKZPRrmLUOVda3sTXU6ArwgblXitZfXOP/D+s+qlKq28euDRvdUGUddYl7C8W/IWZE/OQ0JYG0ttt4g1M0kqd9jtuHhW4kYuvrY4uFVVLpJFgzw+jtwBsVDGS1tHkQpgpEFghupv7jqYPr8BxVpRXXgaLtdMqlQmRH/lTjo+HITVhY0bHSG+9fAOLCDmX+LfJuJ82lLgu/1qnz5YvooPhVnqXTrAdqWsHmFrA4xsR9+4HgbQrmp6G430kq2OJK+KJ1RSTwrKoSQaaep5c8s9wkuouwW7IGK5HAcc668g5+1GDzynvsSg5FlE+V5ZptT+2b+ZWuw==",
"SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-eaea6120e66ea12e88dcd8bcbddca752.pem"
}
「SubscribeURL」に表示されているURLをクリックすると、以下のXMLが表示された
<ConfirmSubscriptionResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<ConfirmSubscriptionResult>
<SubscriptionArn>arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample:944c1604-8850-45bc-83f7-1fbf6039332c</SubscriptionArn>
</ConfirmSubscriptionResult>
<ResponseMetadata>
<RequestId>880508cb-93cc-59af-82f2-5b0b93eadc77</RequestId>
</ResponseMetadata>
</ConfirmSubscriptionResponse>
これにより、登録したサブスクリプションが有効になった。これでEmailの場合と同様、認証できた状態
(実際は、「リクエストの確認」に対して自動でSubscribeURLにアクセスするようにプログラムを作成する)
以降はEmailとまったく同じ手順で、通知の作成と送信ができる
メッセージを送信すると、post.txt に以下の内容が記録された
{
"Type" : "Notification",
"MessageId" : "e9ee5726-caf2-555c-bc7b-04e6ca1bb18b",
"TopicArn" : "arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample",
"Subject" : "HTTPテスト",
"Message" : "テスト。\nこれはテストです。",
"Timestamp" : "2018-07-11T12:57:13.404Z",
"SignatureVersion" : "1",
"Signature" : "hEZhRORitFvXUaDN/9vQTenHBXIAjEhGg+cx3GFYwvT2iBx3aEPI+Aioj8LhaRLwZQLDu71UMvhOlUNpHPnhFBWXarmn2zrgfbWcdaLfLWTyZpHk+G8gqQ2yTnkP7x0UL3KBfMSe7lY5NmsK+zpn2CnvHXLxoB+caSVhqw3BFCWHcVLxdguFQoLRmPqxJ6DfgyByQoJ6RipZndYMMjgNSbBwT4zIHN09z75wOsBuDiRyhOr6j+RTdPbRYz3J5vmzDcGloO2yZDWh6xrlQoyXPAihI5mtqmT+OOjQmADtyDaMBCewy6/493uOvC3WQRXcP8n4+lQ0kRlqjsSC4w97HQ==",
"SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-eaea6120e66ea12e88dcd8bcbddca752.pem",
"UnsubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:123456789012:SNS-Sample:944c1604-8850-45bc-83f7-1fbf6039332c"
}
SigningCertURLにアクセスすると、メッセージの送信先から直ちに削除された
Amazon SNS のHTTP(S)通知を試す - 続 カッコの付け方
http://iga-ninja.hatenablog.com/entry/2014/08/15/205625
■SMSへの送信
Amazon SNSでメールとSMS通知を飛ばす | It works for me
https://www.blog.danishi.net/2019/06/02/post-1360/
※以下、上の解説に合わせてメールの送信から検証している
※トピックはメールとSMSで共通のものを使えるため、「トピック名に『Mail』や『SMS』を入れると不自然かもしれない」
□メールアドレスへの送信
Amazon SNS → トピック → トピックの作成
名前: Mail-Test
表示名: (空欄)
「トピックの作成」をクリックし、完了すると「Mail-Test」の画面へ遷移する
「サブスクリプションの作成」をクリック
トピック ARN: (変更せず)
プロトコル: Eメール
エンドポイント: info@refirio.net (送信先のメールアドレス)
「サブスクリプションの作成」をクリック
「AWS Notification - Subscription Confirmation」という確認メールが送られてくるので、本文内のURLをクリックして承認する
「Subscription confirmed!」と表示されれば成功
トピックの画面に戻り、「メッセージの発行」をクリックする
件名: Test for Amazon SNS(日本語は不可)
メッセージ構造: すべての配信プロトコルに同一のペイロード。
エンドポイントに送信するメッセージ本文: テストメッセージ。
「メッセージの発行」をクリックするとメールが送信される
以下のメールが届く
□SMSへの送信
引き続き、SMSへの送信を試す
「サブスクリプションの作成」をクリック
トピック ARN: (変更せず)
プロトコル: SMS
エンドポイント: +819012345678 (送信先の電話番号)
「サブスクリプションの作成」をクリック
SMSの場合、特に認証は無い
トピックの画面に戻り、「メッセージの発行」をクリックする
件名: Test for Amazon SNS(日本語は不可)
メッセージ構造: すべての配信プロトコルに同一のペイロード。
エンドポイントに送信するメッセージ本文: テストメッセージ2。
「メッセージの発行」をクリックするとメールが送信される
先に登録したメールアドレスにメールが届き、さらにSMSに以下のメッセージが届く
送信元: NOTICE
本文: テストメッセージ2。
SMSには件名は反映されないみたい
□SMSへの送信元の名前を変更する
AWS SNSを利用しSMS送信に任意の送信者名を利用する | Skyarch Broadcasting
https://www.skyarch.net/blog/?p=13041
Amazon SNS → Mobile → テキストメッセージング(SMS)
「テキストメッセージングの優先設定」欄にある「編集」をクリック
デフォルトの送信者 ID: Sample(日本語は不可)
この状態でメッセージを発行すると、SMSでは送信元が「Sample」と表示される
(メールの内容には反映されない)
□SMSの文字数制限
何文字まで送信可能?SMSで送信できる文字数を徹底解説 | SMS送信サービス「空電プッシュ」
https://www.karaden.jp/column/sms-word-count.html
携帯キャリア、SMSの送信文字数上限を70文字→670文字に拡大 - iPhone Mania
https://iphone-mania.jp/news-258353/
現在では全角670文字まで送信できるとなっているが、古い機種では全角70文字(半角英数字で160文字)という制限がある
iPhoneの場合、iPhone4Sとそれ以前の機種は全角70文字が最大とされている
ただしiPhone4Sは8年ほど前の機種で、Appleからもサポートが打ち切られている
Androidの場合、2017年4月以前の端末だと機種によっては全角70文字制限にひっかかる可能性があるらしい
3年半前の機種を優先してメッセージを短くするか否かで対応がわかれるが、
より多くの人に届けたいなら全角70文字以内にしておくと無難
□SMSの利用料金
以下で紹介されている
キャリアによって金額が異なり、以下のようになっている。SMSの場合、無料利用枠は無い
NTTドコモ ... $0.07098/通
au ... $0.07985/通
Softbank ... $0.04983/通
SMS(ショートメッセージ)送信サービス - Qiita
https://qiita.com/kidatti/items/93832b9959d3ad2390dd
以下に公式の記載がある
料金 - Amazon SNS | AWS
https://aws.amazon.com/jp/sns/pricing/
以下のページで「1通あたり0.7円」程度となっている?
…と思ったが、これはあくまでも米国内での利用料金
「Enter your country / region」に「Japan」を入力すると日本での利用金が表示され、$0.07451(8円程度)となる
Amazon Simple Notification Service (SNS) SMS Pricing - AWS
https://aws.amazon.com/jp/sns/sms-pricing/
公式のPricingのページでは以下のように書かれている
「米国の電話番号に送信された最初の100件のSMSメッセージは無料です。」
「この価格設定は定期的に変更されます。」
「月間300万通以上のSMSメッセージを送信する場合は、カスタム価格についてお問い合わせください。」
よくある質問 - Amazon SNS | AWS
https://aws.amazon.com/jp/sns/faqs/#SMS_pricing
以下のように記載されている。やはり無料利用枠は米国内への配信限定みたい
「米国内の送信先に送信される SMS メッセージは、毎月 100 件まで AWS 無料利用枠に含まれています。
この利用枠には有効期限はありません。ここでの「メッセージ」とは、以前の質問の回答で説明したように、140 バイト以下の情報を含む 1 つの送信を指します。
米国内で複数の宛先に 100 通を超えるメッセージを送信する場合、または米国外の宛先にメッセージを送信する場合には、現在の料金に基づいて、送信される各メッセージが課金されます。」
1ヶ月の上限は、デフォルトで1USDに設定されているみたい(10通ほど送信できる)
申請すれば100USDに引き上げてもらえるみたい(1000通ほど送信できる)
上限に引っかかっても、SDKからの送信時は特別なエラーメッセージは確認できなかったので注意
AWSコンソールの「Amazon SNS → テキストメッセージング(SMS → 配信統計(UTC))」ではエラーがあったことを確認できる
申請については「SMS送信数の制限緩和」の項目を参照
Amazon SNSを使い、RailsからSMSを送信する - Qiita
https://qiita.com/tomoeine/items/76a633809af3fea1643d
□送信元電話番号
ソフトバンクにSMSを送信すると、送信元電話番号は以下になった
837727678
電話をかけてみると「こちらはソフトバンクです。おかけになった電話番号は現在使われておりません。」と自動応答された
つまり、その番号は送信専用のものとなる
キャリアの持つ電話番号から送られているのかもしれないが、上の自動応答は単に「ソフトバンクの携帯からかけたから」というだけの可能性はある
要調査
□トピックではなく電話番号に対して直接送信
Amazon SNS → Mobile → テキストメッセージング(SMS) → テキストメッセージの発行
メッセージのタイプ: プロモーション(特に変更せず)
電話番号: +819012345678 (送信先の電話番号)
メッセージ: AWSのダッシュボードから電話番号に対して直接送信。
「メッセージの発行」をクリックすると、SMSを直接送信できる
□PHPのSDKからトピックに対して送信
以下のようにして送信できる
<?php
require_once '/var/www/html/aws/html/vendor/autoload.php';
use Aws\Sns\SnsClient;
/* アクセスキー */
$aws_access_key = 'XXXXX';
$aws_secret_access_key = 'YYYYY';
/* AmazonSNS */
$snsClient = new SnsClient([
'version' => 'latest',
'credentials' => [
'key' => $aws_access_key,
'secret' => $aws_secret_access_key,
],
'region' => 'ap-northeast-1',
]);
$result = null;
$code = null;
$data = null;
try {
$result = $snsClient->publish([
'Message' => 'トピックを指定して一斉送信。',
'TopicArn' => 'arn:aws:sns:ap-northeast-1:0123456789:Mail-Test',
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['MessageId'];
} catch (Exception $e) {
$result = $e->getMessage();
}
□PHPのSDKから電話番号に対して送信
以下のようにして送信できる
電話番号は「09012345678」なら「+819012345678」のように指定する
<?php
require_once '/var/www/html/aws/html/vendor/autoload.php';
use Aws\Sns\SnsClient;
/* アクセスキー */
$aws_access_key = 'XXXXX';
$aws_secret_access_key = 'YYYYY';
/* AmazonSNS */
$snsClient = new SnsClient([
'version' => 'latest',
'credentials' => [
'key' => $aws_access_key,
'secret' => $aws_secret_access_key,
],
'region' => 'ap-northeast-1',
]);
$result = null;
$code = null;
$data = null;
try {
$result = $snsClient->publish([
'Message' => '電話番号を直接指定してSMSに個別送信。',
'PhoneNumber' => '+819012345678',
]);
$code = $result->get('@metadata')['statusCode'];
$data = $result['MessageId'];
} catch (Exception $e) {
$result = $e->getMessage();
}
以下のようにすれば、送信元の名前をプログラムから直接指定できる
ただしプログラムからの指定は、東京リージョンでは正式にサポートされていないかもしれない
その影響か、指定して送信すると電話番号が国外と思われるものからになる
$result = $snsClient->publish([
'Message' => '電話番号を直接指定してSMSに個別送信。',
'PhoneNumber' => '+819012345678',
'MessageAttributes' => [
'AWS.SNS.SMS.SenderID' => [
'DataType' => 'String',
'StringValue' => 'SendTester',
],
],
]);
□引き続き要調査
・各キャリアに送れるか(Softbankのみ検証した)
■アプリへの送信
以下が参考になりそう。検証したい
amazon SNSでiOSアプリにプッシュ通知を送る!画像つきで詳しく使い方もまとめました! | イリテク
https://iritec.jp/app_dev/16197/
Rails + Swiftのプッシュ通知をAmazonSNSで実現する - Qiita
https://qiita.com/3kuni/items/62c4739cf1316b2c2ef4
トピック型のモバイルPush通知をRails + Amazon SNSで実装する - メドピア開発者ブログ
https://tech.medpeer.co.jp/entry/2018/03/15/080000
Amazon SNS で、iOS・Androidにpush通知する方法 - Qiita
https://qiita.com/papettoTV/items/f45f75ce00157f87e41a
[Swift] Amazon SNS で iOSアプリにPush通知を送信する #アドカレ2015 | Developers.IO
https://dev.classmethod.jp/cloud/aws/aws-amazon-sns-mobile-push-swift/
Apple Push Notification Service の使用開始 - Amazon Simple Notification Service
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/mobile-push-apns.html
以下はAmazonSNSでは無いが参考になりそう
【Swift】いまさらですがiOS10でプッシュ通知を実装したサンプルアプリを作ってみた - Qiita
https://qiita.com/natsumo/items/ebba9664494ce64ca1b8
プッシュ通知に必要な証明書の作り方2018 - Qiita
https://qiita.com/natsumo/items/d5cc1d0be427ca3af1cb
以下は大量送信についての考察
大規模ネイティブアプリへのプッシュ通知機能導入にあたって考えたこと - Qiita
https://qiita.com/gomi_ningen/items/ab31aa2b3d46bb6ffa5e
[AWS][iOS] Amazon SNS で APNs に大量 Publish してみた
http://dev.classmethod.jp/cloud/aws/sns-apns-push/
■SQS
要勉強だが、すぐに使うことは無さそう
■メールを送信する際、迷惑メール扱いされないための設定
Network.txt の「メールを送信する際、迷惑メール扱いされないための設定」を参照
■QuickSight
※未検証
マネージドのBI(Business Intelligence)ツール
BIツールとは企業に蓄積された大量のデータを集めて分析し、迅速な意思決定を助けるのためのツール
【図解】BIツール(ビジネスインテリジェンスツール)とは?基本とメリット・デメリットを解説 - データのじかん
https://data.wingarc.com/what-is-bitool-6123
Amazon QuickSight(あらゆるデバイスからアクセス可能な高速BIサービス)| AWS
https://aws.amazon.com/jp/quicksight/
Amazon QuickSightのBIダッシュボードで小売りデータを分析する | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/quicksight-dashboard-analysis-retail/
AWS BIサービス Quick Sightを触ってみた - Qiita
https://qiita.com/suzukihi724/items/5baa33c316ad0cb178df
Amazon QuickSight ノウハウ総まとめ!
https://pages.awscloud.com/rs/112-TZM-766/images/%5B%E3%82%A4%E3%83%B3%E3%83%88%E3%83%AD%5DAmazonQui...
■Cognito
※未検証
認証の仕組みを利用できる
AWS SDK for JavaScriptでCognito User Poolsを使ったログイン画面を作ってみた | DevelopersIO
https://dev.classmethod.jp/cloud/aws/login-form-by-using-aws-sdk-for-javascript/
AWS SDK for JavaScriptを使ってブラウザーからCognito User Poolsへサインアップしてみた | DevelopersIO
https://dev.classmethod.jp/cloud/aws/singup-to-cognito-userpools-using-javascript/
Amazon Cognito と仲良くなるために歴史と機能を整理したし、 Cognito User Pools と API Gateway の連携も試した | DevelopersIO
https://dev.classmethod.jp/server-side/serverless/amazon-cognito-api-gateway-idtoken/
Android から Amazon SNS を使ってみる - Qiita
https://qiita.com/kusokamayarou/items/27e023ad06cade20c731
■Amazon Rekognition
高精度で物体認識をできる
顔認識&顔認証もできる
Amazon Rekognition(高精度の画像・動画分析サービス)| AWS
https://aws.amazon.com/jp/rekognition/
Amazon Rekognition をPHPで使って顔のパーツの位置を取得する手順 - Qiita
https://qiita.com/nowmura/items/7d6437298e15d7c9d4d4
Amazon Rekognitionを使って顔の部分を切り取る - Qiita
https://qiita.com/ran/items/8bdf17d546a3ed1ec440
Amazon Rekognitionで顔認証してみた - Qiita
https://qiita.com/OMOIKANESAN/items/c5d1dfe5c00105739dcf
Amazon Rekognitionで顔分析LINE BOT - Qiita
https://qiita.com/keeey999/items/3f3975770bba1ce19817
Amazon Rekognitionで顔分析LINE BOT - Qiita
https://qiita.com/keeey999/items/3f3975770bba1ce19817
Amazon Rekognitionのテキスト検出を利用して、新しいアーキテクチャアイコンのサービス名を取得してみた | Developers.IO
https://dev.classmethod.jp/cloud/aws/new-architecture-icon-detect-by-rekognition/
イメージ内のテキストの検出 - Amazon Rekognition
https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/text-detecting-text-procedure.html
■オブジェクトとシーンの検出
以下の記事を参考に試してみたときのメモ
Amazon Rekognitionを使いPHPを通してレシピ画像を分析してみる - Qiita
https://qiita.com/takenori-ooba/items/4eb8a15ea1a41c5ef1eb
コンソール → Amazon Rekognition → デモを試す
から、任意の画像をアップロードして検出結果を得ることができる
引き続きSDKからも検証
Vagrantの CentOS7+PHP7.1 環境で試した
php-xml が必要だったので追加インストール
その後以下のコマンドでAWSのSDKをインストール
$ cd /path/to/directory
$ curl -sS
https://getcomposer.org/installer | php
$ php composer.phar require aws/aws-sdk-php
一例だが、以下のコードで画像を認識できる
人が写っているというだけでなく、「Female」「Smile」のような情報も取得できる
<?php
require 'vendor/autoload.php';
use Aws\Rekognition\RekognitionClient;
use Aws\Rekognition\Exception\RekognitionException;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$rekognition = new RekognitionClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// オブジェクトとシーンの検出
$result = $rekognition->detectLabels([
'Image' => [
'Bytes' => file_get_contents('images/female.jpg'),
],
]);
print('<pre>');
print_r($result['Labels']);
print('</pre>');
exit;
} catch (RekognitionException $e) {
exit('RekognitionException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■顔の分析
一例だが、以下のコードで顔を認識できる
<?php
require 'vendor/autoload.php';
use Aws\Rekognition\RekognitionClient;
use Aws\Rekognition\Exception\RekognitionException;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$rekognition = new RekognitionClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// 顔の分析
$result = $rekognition->detectFaces([
'Image' => [
'Bytes' => file_get_contents('images/female.jpg'),
],
]);
print('<pre>');
print_r($result['FaceDetails']);
print('</pre>');
exit;
} catch (RekognitionException $e) {
exit('RekognitionException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■有名人の認識
一例だが、以下のコードで有名人を認識できる
<?php
require 'vendor/autoload.php';
use Aws\Rekognition\RekognitionClient;
use Aws\Rekognition\Exception\RekognitionException;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$rekognition = new RekognitionClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// 顔の分析
$result = $rekognition->recognizeCelebrities([
'Image' => [
'Bytes' => file_get_contents('images/mayu1.jpg'),
],
]);
print('<pre>');
print_r($result['CelebrityFaces']);
print('</pre>');
exit;
} catch (RekognitionException $e) {
exit('RekognitionException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■顔の比較
一例だが、以下のコードで顔を比較できる
<?php
require 'vendor/autoload.php';
use Aws\Rekognition\RekognitionClient;
use Aws\Rekognition\Exception\RekognitionException;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$rekognition = new RekognitionClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// 顔の比較
$result = $rekognition->compareFaces([
'SourceImage' => [
'Bytes' => file_get_contents('images/female1.jpg'),
],
'TargetImage' => [
'Bytes' => file_get_contents('images/female2.jpg'),
],
]);
print('<pre>');
print_r($result['FaceMatches']);
print_r($result['UnmatchedFaces']);
print('</pre>');
exit;
} catch (RekognitionException $e) {
exit('RekognitionException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■イメージ内のテキスト
一例だが、以下のコードでテキストを認識できる
英語は認識できるが、現時点で日本語は認識できなかった
<?php
require 'vendor/autoload.php';
use Aws\Rekognition\RekognitionClient;
use Aws\Rekognition\Exception\RekognitionException;
try {
// アクセスキーとシークレットアクセスキーを指定して接続
$rekognition = new RekognitionClient([
'credentials' => [
'key' => 'XXXXX',
'secret' => 'YYYYY',
],
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
// イメージ内のテキスト
$result = $rekognition->detectText([
'Image' => [
'Bytes' => file_get_contents('images/text.png'),
],
]);
print('<pre>');
print_r($result['TextDetections']);
print('</pre>');
exit;
} catch (RekognitionException $e) {
exit('RekognitionException: ' . $e->getMessage());
} catch (Exception $e) {
exit('Exception: ' . $e->getMessage());
}
■Amazon Translate
※未検証
Amazon Translate(高速で高品質なニューラル機械翻訳サービス)| AWS
https://aws.amazon.com/jp/translate/
Amazonの翻訳サービス Amazon Translate が日本に上陸! | Developers.IO
https://dev.classmethod.jp/articles/amazon-translate-landed-in-japan/
■機械学習用の環境構築について調査
■調査した環境
Amazon Linux 2 で調査
Python2.7 と Python3.7 がデフォルトでインストールされていた
今回はこの Python3.7 を使うものとする
$ python --version
Python 2.7.18
$ pip --version
-bash: pip: command not found
$ python3 --version
Python 3.7.10
$ pip3 --version
pip 20.2.2 from /usr/lib/python3.7/site-packages/pip (python 3.7)
■MeCab
yumでインストールできないので、ソースコードを取得してインストールする
Amazon Linux 2 で MeCab + NEologd - Qiita
https://qiita.com/hoto17296/items/7add794de677112566bc
※この手順だと、NEologdは t2.medium でなければインストールできなかった(small でも駄目だった)
※最後に掲載されているプログラム、「import mecab」は恐らく「import MeCab」 の間違い
そのままだと「No module named 'mecab'」のエラーになる
※とは言え、全体的に参考になった
$ sudo yum update -y
$ sudo yum groupinstall -y "Development Tools"
MeCab: Yet Another Part-of-Speech and Morphological Analyzer
https://taku910.github.io/mecab/
「ダウンロード → MeCab 本体 → Source」の「mecab-0.996.tar.gz:ダウンロード」からダウンロードURLを確認できる
$ wget 'https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE' -O mecab-0.996.tar.gz
$ tar xzf mecab-0.996.tar.gz
$ cd mecab-0.996
$ ./configure
$ make
$ make check
$ sudo make install
$ cd ..
$ rm -rf mecab-0.996*
さらに以下で辞書を導入
$ git clone --depth 1
https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ ./bin/install-mecab-ipadic-neologd -n -p /var/lib/mecab/dic/mecab-ipadic-neologd
$ cd ..
t2.small 環境でインストールできた
(t2.micro 環境では以下のエラーになった。メモリ不足で処理が中断されている)
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
/home/ec2-user/mecab-ipadic-neologd/bin/../libexec/make-mecab-ipadic-neologd.sh: line 525: 27555 Aborted ${MECAB_LIBEXEC_DIR}/mecab-dict-index -f UTF8 -t UTF8
以下で動作確認できる
$ echo メイが恋ダンスを踊っている。 | mecab -d /var/lib/mecab/dic/mecab-ipadic-neologd
メイ 名詞,固有名詞,人名,一般,*,*,M.A.Y,メイ,メイ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
恋ダンス 名詞,固有名詞,一般,*,*,*,恋ダンス,コイダンス,コイダンス
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
踊っ 動詞,自立,*,*,五段・ラ行,連用タ接続,踊る,オドッ,オドッ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル
。 記号,句点,*,*,*,*,。,。,。
EOS
以下でPythonから使用できる
$ pip3 install mecab-python3
$ python3
Python 3.7.10 (default, Jun 3 2021, 00:02:01)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import MeCab
>>> mecab = MeCab.Tagger("-d /var/lib/mecab/dic/mecab-ipadic-neologd")
>>> print(mecab.parse("メイが恋ダンスを踊っている。"))
メイ 名詞,固有名詞,人名,一般,*,*,M.A.Y,メイ,メイ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
恋ダンス 名詞,固有名詞,一般,*,*,*,恋ダンス,コイダンス,コイダンス
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
踊っ 動詞,自立,*,*,五段・ラ行,連用タ接続,踊る,オドッ,オドッ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル
。 記号,句点,*,*,*,*,。,。,。
EOS
>>> exit()
実行できた
インストール後、上記プログラムは t2.micro でも実行できた
以降、特に断りが無ければ t2.micro で実行している
■sklearn
問題なくインストールできた
$ sudo pip3 install sklearn
$ python3
Python 3.7.10 (default, Jun 3 2021, 00:02:01)
[GCC 7.3.1 20180712 (Red Hat 7.3.1-13)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from sklearn.svm import LinearSVC
>>> from sklearn.metrics import accuracy_score
>>> exit()
■scikit-learnでスパムメールを判定
Python.txt の「scikit-learn(機械学習)でスパムメールを判定」をもとに作業した
以下、部分的な作業メモ
test_spamcheck.py と makedb_spamcheck.py で以下を調整した
(今回の環境に合わせて、辞書ファイルの場所を指定した)
#tagger = MeCab.Tagger()
tagger = MeCab.Tagger("-d /var/lib/mecab/dic/mecab-ipadic-neologd")
以下のように実行できた
$ python3 makedb_spamcheck.py
単語頻出データベース作成完了
$ python3 train_spamcheck.py
0.9777777777777777
1.0
0.9777777777777777
1.0
0.9777777777777777
〜略〜
1.0
1.0
1.0
----
平均= 0.9919999999999994
$ python3 test_spamcheck.py
テキスト1
結果= OK
テキスト2
結果= SPAM
最初「テキスト1」「テキスト2」ともスパム判定されたが、
「テキスト1」を以下の文章にするとスパム判定されなかった
お世話になっています。山田太郎です。
昨日はありがとうございました。
また、実際の仕事メールと実際のスパムメールを張り付けてテストして、それぞれ正しく判定してくれた
■TensorFlow
以下などを試したがインストールできず
# pip3 install tensorflow
実行すると「MemoryError」と表示された
試した環境は t2.micro なので、単純にスペック不足だと思われる
t2.small で試してみる
Successfully installed absl-py-0.13.0 astunparse-1.6.3 cached-property-1.5.2 cachetools-4.2.2 certifi-2021.5.30 charset-normalizer-2.0.3 flatbuffers-1.12 gast-0.4.0 google-auth-1.33.1 google-auth-oauthlib-0.4.4 google-pasta-0.2.0 grpcio-1.34.1 h5py-3.1.0 idna-3.2 importlib-metadata-4.6.1 keras-nightly-2.5.0.dev2021032900 keras-preprocessing-1.1.2 markdown-3.3.4 numpy-1.19.5 oauthlib-3.1.1 opt-einsum-3.3.0 protobuf-3.17.3 pyasn1-0.4.8 pyasn1-modules-0.2.8 requests-2.26.0 requests-oauthlib-1.3.0 rsa-4.7.2 six-1.15.0 tensorboard-2.5.0 tensorboard-data-server-0.6.1 tensorboard-plugin-wit-1.8.0 tensorflow-2.5.0 tensorflow-estimator-2.5.0 termcolor-1.1.0 typing-extensions-3.7.4.3 urllib3-1.26.6 werkzeug-2.0.1 wheel-0.36.2 wrapt-1.12.1 zipp-3.5.0
と表示されてインストールできた
$ python3
Python 3.7.3 (default, Apr 3 2019, 05:39:12)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
2021-07-21 20:13:01.552836: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory
2021-07-21 20:13:01.552963: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
実行しようとすると、ライブラリが無いと言われてエラーになる
AWSでも動作しないわけではなさそうだが、一筋縄ではいかないみたい
TensorFlowではGPU環境が必要だが、AWSでCentOS系で無料インストールできるもので…となるとAMIが無いみたい
TensorFlow-GPUの環境構築(Amazon Linux) : シェルスクリプトとかperlとか
http://blog.livedoor.jp/s06280hk/archives/1915199.html
AWSインスタンス上にTensorFlow:GPGPU環境を作成する - 技術情報 | テクノスデータサイエンス・エンジニアリング株式会社
https://www.tdse.jp/tec_info/588/
AmazonLinux2にTensorFlow環境を構築する - Qiita
https://qiita.com/ground0state/items/928e3a5dea02f1f44685
TensorFlow-GPUの環境構築(Amazon Linux) : シェルスクリプトとかperlとか
http://blog.livedoor.jp/s06280hk/archives/1915199.html
なお Raspberry Pi 環境にすんなりインストールできるのは、標準でGPUが搭載されているからみたい
ラズパイ4の新GPUをハックしてディープラーニング推論を高速化、一体なぜ開発できた? | 日経Robotics(日経ロボティクス)
https://xtech.nikkei.com/atcl/nxt/mag/rob/18/012600001/00062/
■動画配信サーバについて簡単に調査
HTTP Live Streamingで動画を配信してみる
http://dev.classmethod.jp/tool/http-live-streaming/
Amazon Elastic Transcoder メディア変換サービス来た!
http://dev.classmethod.jp/cloud/amazon-elastic-transcoder-start/
【AWS初心者向けWebinar】AWSから始める動画配信
https://www.slideshare.net/AmazonWebServicesJapan/awswebinaraws
動画配信プラットフォーム on AWS
https://www.slideshare.net/AmazonWebServicesJapan/on-aws
AWS+Video.jsでお手軽ストリーミング動画配信
http://qiita.com/mechamogera/items/a91848b0c3b6fe9f18f5
AWS WAFを使うためシステムにCloudFrontを導入した時の注意点まとめ
http://dev.classmethod.jp/cloud/aws/setup-amazon-waf-and-cloudfront/
AWSを利用した動画変換から動画配信まで
http://qiita.com/uda0922/items/900bd9977d93d77bba19
料理動画を支える技術
http://techlife.cookpad.com/entry/2014/06/17/160905
オンデマンド動画配信のためのクラウド構成とお見積り例
https://aws.amazon.com/jp/cdp/cdn/
・1本250MBの動画が1ヶ月4,000回再生される想定。1ヶ月1TBのデータが配信される
…という条件なら月額2万円程度
・ただし見積もりにWebサーバやDBサーバなどは含まれていない
・配信制限するなら、キャッシュは利用しづらい?そうでもない?要調査
・AWSと動画についての学習コストが必要
・動画をアップロード&管理する仕組みの作成も必要
Amazon CloudFront で HLS動画のプライベートオンデマンド配信を行う方法
http://akiyoko.hatenablog.jp/entry/2015/08/24/192618
CloudFront+S3で署名付きURLでプライベートコンテンツを配信する
http://dev.classmethod.jp/cloud/aws/cf-s3-deliveries-use-signurl/
CloudFrontの署名付きURLでS3にアクセスする方法 - Qiita
https://qiita.com/jeayoon/items/c148a8637a177c0f8c9f
試したいこと
CloudFront+EC2での配信
CloudFront+ELB+EC2での配信
CDN の 仕組み
http://blog.redbox.ne.jp/what-is-cdn.html
AWS Elemental MediaConvert というものもある
Elastic Transcoder との違いなどについて、また確認したい
AWS Elemental MediaConvert と Amazon ElasticTranscoderの違いってなに? - Qiita
https://qiita.com/r-wakamatsu/items/f2e77c41a0f07373b232
■2021年5月に追加調査
AWSで動画配信(オンデマンド配信)をするための手順 - Qiita
https://qiita.com/right1121/items/97beff9f2c300d868e69
いつでもどこでも動画が見られる『ストリーミング』の仕組みとは|TIME&SPACE by KDDI
https://time-space.kddi.com/ict-keywords/kaisetsu/20151126/
オンデマンド配信:
あらかじめサーバーに用意されたファイルにアクセスし、データをダウンロードしながら視聴できるもの
配信中に一時停止や巻き戻し、早送りができる
ライブ配信:
リアルタイムでデータが作成されるため、視聴者は巻き戻しなどの操作はできない
Amazon IVS(Interactive Video Service)を使用すれば、簡単にライブストリーミングの環境が作れるらしい
名称に「Elemental」が含まれていないので、既存サービスとは異なるものと思われる
要検証
[新サービス] 数クリックでライブストリーミング配信環境が作成されるサービス「Amazon Interactive Video Service」が登場しました! | DevelopersIO
https://dev.classmethod.jp/articles/ga-amazon-interactive-video-service/
【初心者】Amazon Interactive Video Service (Amazon IVS) を使ってみる - Qiita
https://qiita.com/mksamba/items/051b6ccde5a58cd2d732
簡単にライブストリーミング配信ができる Amazon IVS がリリース - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2020/07/20/introducing-amazon-ivs/
■2022年5月に追加調査
HLSとは?:ストリーミング配信を実現する技術 | 動画サイト運営ノウハウブログ by ソーシャルキャスト
https://blog.socialcast.jp/05/post-729/
HLS(HTTP Live Streaming)で動画を配信・再生してみよう | アプリ開発・制作/システム開発のYAZ
https://www.yaz.co.jp/tec-blog/web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9/212
Video.jsのvideojs-http-streaming(VHS)を使ってHLS形式のストリーミング配信を再生する最低限度の設定 | DevelopersIO
https://dev.classmethod.jp/articles/videojs-http-streaming-vhs-hls-streaming-minimum-setting/
大容量の動画データをサーバにアップロードする手段については、以下なども参考になりそう
【presigned url】サーバーを経由せずにS3に画像・動画などのファイルをアップロードする - Qiita
https://qiita.com/MasashiFujiike/items/3cf0373cf89462c4c983
ブラウザからS3へのダイレクトアップロード - Qiita
https://qiita.com/minsu/items/a3bfc8f8f807f6b51fdf
■ライブストリーミング
要調査
ライブ動画配信のためのクラウド構成と料金試算例 | AWS
https://aws.amazon.com/jp/cdp/cdn-live/
ライブストリーミング | AWS ソリューション
https://aws.amazon.com/jp/solutions/implementations/live-streaming-on-aws/
AWS でライブストリーミングを実現するには ? - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS
https://aws.amazon.com/jp/builders-flash/202011/aws-solutions-livestream/?awsf.filter-name=*all
【完全無料】Flutterを使って簡易ライブ配信アプリを構築する
https://zenn.dev/gakin/articles/set_up_flutter_live_streaming_demo
■ビッグデータ
■事例
ビッグデータ活用における AWS 国内導入事例 Powered by AWS クラウド | AWS
https://aws.amazon.com/jp/solutions/case-studies/big-data/
AWS 導入事例:株式会社大創産業 | AWS
https://aws.amazon.com/jp/solutions/case-studies/daiso/
■Amazon Redshift
※未検証
データを蓄積して分析できる
MySQLで処理しきれないような規模にも対応できる
Amazon Redshiftって何ができるの?AWSのデータウェアハウスサービスを解説 | NHN テコラス Tech Blog | AWS、機械学習、IoTなどの技術ブログ
https://techblog.nhn-techorus.com/archives/8232
Redshiftの利用事例が紹介されている
ダイソーが6年でIT内製化、マイクロサービス化、サーバレスに成功した理由 (1/2):105億レコードの処理が課題 - @IT
https://www.atmarkit.co.jp/ait/articles/1911/21/news010.html
以下引用
既存のRDBMSでは数万〜数百万件ほどのデータであれば高い性能を示すが、100億を超えるようなデータだと性能が劣化してしまう。
そこで列指向の「Amazon Redshift」をテストすると、1億を超える辺りからRDBMSの速度を超え、ダイソーの持つ105億レコードの処理において、はるかに高い性能を示したという。
PoCのときは既存のRDBMSだったため、パフォーマンスが追い付かなかった。
しかし、Redshiftであれば全店舗のデータ処理もまかなえる。自動発注システムで十分に処理できることが分かったことは大きな前進だった。
■Amazon Athena
※未検証
S3に保存・蓄積したログに対してSQLクエリを投げて分析を行える
MySQLで処理しきれないような規模にも対応できる
Amazon Athena(SQL を使用した S3 でのデータクエリ)| AWS
https://aws.amazon.com/jp/athena/
重たい集計バッチをAthenaを利用して高速化した話 - Tech Do | メディアドゥの技術ブログ
https://techdo.mediado.jp/entry/2020/04/23/090000
Amazon Athenaではじめるログ分析入門 - Qiita
https://qiita.com/miyasakura_/items/174dc73f706e8951dbdd
■マルチAZ環境でWordPress
※Webサーバが2台構成(オートスケールではない)の環境でWordPressを使おうとしたら、なかなか厄介だったので作業内容をメモ
AWSのマルチAZ環境を前提とした調査だが、複数台構成の環境全般に言える
■下調べの内容
アマゾン ウェブ サービスで WordPress ウェブサイトを構築する
http://docs.aws.amazon.com/ja_jp/getting-started/latest/wordpress/hosting-wordpress-on-aws.html
AWSでWordPressを使おうと試してみたが、管理画面側ではメディアはS3ではなくローカルファイルが参照される。
管理画面側ではロードバランサを経由せずにアクセス…とすれば使えるが、可用性が下がるのでそのような運用は避けたい。
また、WordPressが何かとローカルのファイルを更新しようとするので、スケーリング環境だとファイルの同期が厄介。
ステップ 5: アプリケーションバージョンを更新する
http://docs.aws.amazon.com/ja_jp/getting-started/latest/wordpress/update-application-version.html
AWS公式の解説通りに構築すると、WordPressやプラグインのバージョンアップが面倒すぎて耐えられる自信は無い。
(複数台構成のWebサーバを一時的に1台にし、WordPressの管理画面でアップデートを実行し、
サーバからファイルをダウンロードして、それを新しいバージョンのアプリとして登録しなおす)
…だったが、上の詳細解説ページは無くなって、簡易な解説に差し替えられている
以下は転送先のページ
外部 Amazon RDS データベースを備えた高可用性の WordPress ウェブサイトを Elastic Beanstalk にデプロイする - AWS Elastic Beanstalk
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/php-hawordpress-tutorial.html
以下は解説が差し替えられる前のメモ
■基本方針
WordPressは複数台サーバを前提とした設計になっていない(WordPressがローカルファイルを書き換える)ので、マルチAZ環境には向いていない。
どうしても複数台サーバにしたければ、一案としてrsyncでファイル同期する方法がある。
データベースは通常通り、RDSを使える。
ただし単純に「web1をweb2に同期」としても、WordPressがweb2サーバのファイルを書き換える可能性がある。
(「rsyncで双方向同期+ロードバランサーでスティッキーセッション」で対応する。)
また、gitでファイルを管理していてもWordPressがファイルを書き換えるため、この対策も必要となる。
(「専用のテーマのみgit管理対象」で対応する。)
[ようやく見つけたかもしれない]WordpressサイトをGit管理する方法[メモ]
http://qiita.com/goosys/items/5c66cb912986afcd86f3
wordpressサイトをgitで管理する際のgitignore
http://eturlt.net/blog/20130520/gitignoreforwordpress/
■具体的な構築内容
サーバ構成
Webサーバはweb1とweb2の二台構成とする。アクセスはELBで割り振るものとする
データベースにはRDSを使うものとする
(EC2にMySQLをインストールしてデータベースサーバを構築する場合も、作業の流れは同じ)
公開ディレクトリ
一例として /var/www/html とする
(/var/www/vhosts/wordpress/html など他の場所の場合も、作業の流れは同じ)
同期設定
rsyncで /var/www を双方向同期する。同期ユーザは一例としてrsyncとする(専用に作成する)
意図しないファイルの削除&復元を避けるため、/etc/lsyncd.conf のsyncブロックで以下の指定を行う
delete = "running",
init = false,
WordPress設置場所のディレクトリに以下の指定を行い、この中で作成されたファイル&ディレクトリの所有グループをapacheにする
chown apache. /var/www
chmod 0777 /var/www
chmod g+s /var/www
セッション切れを防ぐため、ELBでスティッキーセッションを有効にする
「Aサーバでメディアをアップロードしたが、直後にBサーバにアクセスしたのでメディアが表示されない」(同期が完了していない)
もこれで防げる
更新方法
ファイルアップロードユーザは一例としてweb-userとする(専用に作成する)
アップロードはweb1サーバからweb-userで行う(web2サーバから行っても問題ないはずだが、統一しておくと無難)
これでファイル&ディレクトリの所有者&所有グループは
・アップロードした ... web-user / apache
・WordPressが作成した ... apache / apache
・同期された ... rsync / apache
となる。すべて同じグループになるので、グループに対して読み書きの権限を与えれば、各ファイルの読み書きができる
gitを使う場合
デプロイの仕組みを作る場合、web1サーバからapacheユーザでデプロイする。rsyncで同期されるので、web2サーバでのデプロイは不要
ただしWordPress自体が自身のプログラムを書き換えるため、最低限のファイルのみgitで管理する
Git管理の詳細は Git.txt を参照
■所有者と権限を保持して同期(未検証)
# visudo -f /etc/sudoers.d/users
Cmnd_Alias RSYNCCOMMANDS = /usr/bin/rsync
rsync ALL=PASSWD: ALL, NOPASSWD: RSYNCCOMMANDS
追加後、下記コマンドで追加されているか確認できる
# su - rsync -s /bin/bash
… rsyncユーザへ切り替え
# cat /etc/sudoers.d/users
… usersファイルの所有者はrootの為、権限エラー
# sudo cat /etc/sudoers.d/users
… sudoに追加されていても、許可されたコマンドではないためパスワードが要求される
# sudo rsync --version
… sudoに追加されており、且つ許可されたコマンドなのでパスワードが要求されず実行
rsyncの設定を以下のようにすると、ファイルの所有者と権限を保持して同期できる
設定後、rsyncを再起動する
# vi /etc/lsyncd.conf
rsync = {
owner = true, … 追加
group = true, … 追加
rsync_path = "sudo /usr/bin/rsync", … 追加
archive = true,
compress = false,
rsh = "ssh -p 10022"
}
SFTPでアップロードするファイルのumaskを設定する場合、以下のようにする
設定後、sshdを再起動する
# vi /etc/ssh/sshd_config
#Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp -u 002
■オートスケールに対応させるなら
双方向同期では対応できないので、素直にAWS公式の解説通りにするといいかも(未検証)
■メモ
展開済みのWordPressの全ファイルをFTP経由でアップロードすると非常に時間がかかる
圧縮ファイルのままアップロードし、SSHで unzip wordpress-4.7.2-ja.zip として展開すると早い
ただしファイルの所有者に注意。FTPでアップロードしたときと同じ所有者になるように一括変更しておく
chown -R apache wordpress
… 所有者をapacheに変更(再帰的)
find wordpress -type d -print | xargs chmod 775
… ディレクトリの権限を775に変更(再帰的)
find wordpress -type f -print | xargs chmod 664
… ファイルの権限を664に変更(再帰的)
以下はハマりどころなのでメモしておく
【決定版】WordPressの引っ越し!サーバー移行・移転手順 | FASTCODING BLOG
https://fastcoding.jp/blog/all/system/moving-wordpress/
searchreplacedb2 を使った、データベースの移行について紹介されている
SSL対応後のWordpress管理画面で発生した無限リダイレクトループの修正方法 - Qiita
https://qiita.com/hirror/items/bb96e236c3ffc41e890e
リダイレクトループが発生したら、wp-config.php に $_SERVER['HTTPS'] = 'on'; を書けば、何とかなるかも
■RDSを使わずにMySQLのレプリケーションを設定
レプリケーションの設定については、サーバメモの「Etcetera.txt」も参照
■DBサーバ1 DB Master
203.0.113.4
MySQL root パスワード LkXhg9Yja2
GRANT ALL PRIVILEGES ON test.* TO dbmaster@localhost IDENTIFIED BY 'qazwsxedc';
GRANT ALL PRIVILEGES ON test.* TO dbmaster@203.0.113.2 IDENTIFIED BY 'qazwsxedc';
GRANT ALL PRIVILEGES ON test.* TO dbmaster@203.0.113.3 IDENTIFIED BY 'qazwsxedc';
外部サーバのMySQLに接続を試すの巻
http://blog.trippyboy.com/2010/mysql/%E5%A4%96%E9%83%A8%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AEmysql%E3%...
■DBサーバ2 DB Slave
203.0.113.5
■レプリケーションを設定(データベースの多重化)
※CHANGE MASTER の際に MASTER_LOG_FILE と MASTER_LOG_POS を指定する
※各DBサーバのファイヤーウォールを設定する
SELECT Host, User, Password FROM mysql.user;
SHOW BINARY LOGS;
SHOW SLAVE STATUS\G;
Slave_IO_Running、Slave_SQL_RunningがYesになっていればOK。
MySQL レプリケーションのセットアップ手順
http://wadslab.net/wiki/index.php?MySQL%20%A5%EC%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3%A4%CE%A5%...
EC2でMySQL(リージョン間レプリケーション編)
http://memocra.blogspot.jp/2011/08/ec2mysql_16.html
MySQLのレプリケーション設定とエラー時のメモ
http://takuan93.blog62.fc2.com/blog-entry-72.html
SQL_SLAVE_SKIP_COUNTERについて教えてもらったよ
http://zentoo.hatenablog.com/entry/20120116/1326734086
SQL_SLAVE_SKIP_COUNTER がまずいもう一つの理由
https://yakst.com/ja/posts/14
DBサーバ1とDBサーバ2のファイヤーウォールを設定する(相互にアクセスできるようにする)
□DBサーバ1
# vi /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id = 1001
# service mysqld restart
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO repl@203.0.113.2 IDENTIFIED BY 'qazwsxedc';
FLUSH PRIVILEGES;
SELECT host,user FROM mysql.user;
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 | 1686 | | |
+------------------+----------+--------------+------------------+
□DBサーバ2
# vi /etc/my.cnf
[mysqld]
server-id=1002
CHANGE MASTER TO
MASTER_HOST='203.0.113.3',
MASTER_USER='repl',
MASTER_PASSWORD='qazwsxedc',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=355;
MASTER_LOG_FILE ... 「SHOW MASTER STATUS」の「File」
MASTER_LOG_POS ... 「SHOW MASTER STATUS」の「Position」
FLUSH PRIVILEGES;
■レプリケーションを開始
□DBサーバ1
# service mysqld restart
□DBサーバ2
# service mysqld restart
START SLAVE;
■WordPress
WordPressの場合、HyperDBというプラグインを使えば、マスター/スレーブのデータベースを参照させることができる
たった30分でWordPressを冗長化する方法 - (っ´∀`)っ ゃー
https://nullpopopo.blogcube.info/2012/08/%E3%81%9F%E3%81%A3%E3%81%9F30%E5%88%86%E3%81%A7wordpress%E3...
HyperDB でお手軽に WP の MySQL サーバを複数分散 | dogmap.jp
https://dogmap.jp/2013/10/28/wordpress-with-hyperdb/
■memcached
Cache用にサーバを用意する
以下はmemcached用の設定
# yum install memcached php-pecl-memcache
# vi /etc/php.ini
#以下の2行をコメントアウト(先頭に;を付与)
session.save_handler = files
session.save_path = "/var/lib/php/session"
/etc/php.d/memcache.iniを編集
# vi /etc/php.d/memcache.ini
#以下の行のコメントアウトを外す(先頭の;を除去)
;session.save_handler=memcache
#以下の行のコメントアウトを外す。?以下は除去
;session.save_path="tcp://localhost:11211?*******"
#こんな感じになる。,以降にもう一台のサーバのアドレスを指定する
session.save_path="tcp://localhost:11211"
# service httpd restart #Apacheを再起動
# service memcached start #memcacheを起動
セッションを扱うPHPプログラムで動作確認をする
# vi /etc/php.d/memcache.ini
session.save_handler=memcache
session.save_path="tcp://cacheinstance.example.cfg.apne1.cache.amazonaws.com:11211"
;session.save_path="tcp://cacheinstance.example.cfg.apne1.cache.amazonaws.com:11211"
session.save_path="tcp://cacheinstance-multi.example.cfg.apne1.cache.amazonaws.com:11211"
memcacheとmemcachedは別物。memcachedの方が早くシンプルなので多く使われるらしい
memcachedの場合、tcp:// は付けないらしい
ファイヤーウォールの設定を忘れずに
■AWS Organizations
■組織の作成
AWSコンソール → AWS Organizations
「組織を作成する」ボタンを押すと、確認画面なく直ちに組織が作成される
■組織の作成をキャンセルする場合
組織の作成をキャンセルしようとしたが、
AWSコンソール → AWS Organizations → AWSアカウント
「AWSアカウント」の画面に「refirio(管理アカウント)」が表示されている
このアカウントにチェックを入れて「アクション → 組織から除外」としてみたが、以下のエラーになった
アカウント #123456789012 を除外できませんでした。
refirio (#123456789012): MasterCannotLeaveOrganizationException
AWSコンソール → AWS Organizations → 設定
「組織を削除する」から削除できた
削除について、以下の説明が書かれている
組織は、組織からすべてのメンバー AWS アカウントを除外して、マスターアカウントのみが残った状態になった後で削除できます。
これで元どおりになった…はず
■子アカウントの作成&招待
以下などが参考になりそう
AWS Organizationsとは?rootユーザも制御するその強力さを手を動かして体感してみる | DevelopersIO
https://dev.classmethod.jp/articles/organizations-gettingstarted/
AWS Organizationsから新規AWSアカウントを作成してスイッチロールしてみた | DevelopersIO
https://dev.classmethod.jp/articles/create-new-aws-account-by-organizations/
AWS Organizations で子アカウントを招待したり作ったりしてみた - ablog
https://yohei-a.hatenablog.jp/entry/20180901/1535773040
■子アカウントの作成
AWSコンソール → AWS Organizations → AWSアカウントを追加
「AWSアカウントを追加」画面へ遷移する
画面上部で「AWS アカウントを作成」が選択されていることを確認する
AWSアカウント名: (任意のアカウント名を入力)
アカウント所有者のEメールアドレス: (作成したいメールアドレスを入力)
IAMロール名: OrganizationAccountAccessRole(変更せず)
「AWSアカウントを作成」ボタンを押す
「組織内に1つ以上のAWSアカウントを作成するリクエストを送信しました。」
「AWSは1件のアカウントを作成しています。」
と表示された
1分ほど待つと、入力したメールアドレスに「お客様のAWSアカウントの準備ができました - 今すぐ始めましょう」というメールが送信された
さらに3分ほど後に「Amazon Web Services へようこそ」というメールも届いた
AWSコンソールに「AWSは1件のアカウントを作成しています。」は表示されたままだったが、
ページを再読み込みすると、アカウントが作成済みになっていた
ルートのサインイン画面にアクセスし、メールアドレスを入力する
パスワードの入力画面で「パスワードをお忘れですか?」リンクをクリックする(この時点ではパスワードが設定されていないため)
パスワードリセットのURLが送られてくるので、メール内にあるリンクからパスワードを設定する
■子アカウントの招待
AWSコンソール → AWS Organizations → AWSアカウントを追加
「AWSアカウントを追加」画面へ遷移するので、ここで招待したいアカウントを指定する
画面上部の「既存のAWSアカウントを招待」をクリックして進める
「招待するAWSアカウントのEメールアドレスまたはアカウントID」に、メールアドレスもしくはアカウントIDを入力する
「招待を送信」ボタンを押す
「AWS組織に参加するための招待が送信されました。」と表示される
左メニューから「AWSアカウント → 招待」をクリックすると、過去の招待を確認できる
招待されたアカウントに、「Your AWS account has been invited to join an AWS organization」というメールが送信される
招待されたアカウント(子アカウントになる)にrootでログインする
AWSコンソール右上のメニューから「組織」をクリックする
「AWS Organizations」の画面に遷移する
左側メニューに「招待」が表示されているので、クリックする
「example@example.comからの招待」のように招待が表示されている
招待の内容は以下のとおり
以下の詳細情報を持つ組織は、AWSアカウントを組織のメンバーになるよう招待します。
この組織ではすべての機能が有効になっており、アカウントを完全に制御できることを想定しています。
管理アカウント名: refirio
管理アカウントのEメールアドレス: example@example.com
組織ID: o-x3wptj2tjb
内容を確認し、問題無ければ「招待を承認する」をクリックする
「組織に参加するための招待を承認しました。」と表示されれば完了
以降、「AWS Organizations」の画面にアクセスすると、「組織の詳細」として所属組織の情報が表示されるようになる
組織ID: o-xxxxxxxxxx
管理アカウントのEメールアドレス: example@example.com
管理アカウントID: 123456789012
組織に所属した後でも、rootアカウントにログインして「請求ダッシュボード」から、請求内容を確認できる
招待したアカウント(親アカウント)にログインして「AWS Organizations」の画面を確認すると、
招待を承認したアカウントが表示されている
「請求ダッシュボード」には何も表示されていない
…だったが、翌日には子アカウントの請求内容が表示されるようになった
「サービスごとの料金明細」と「アカウント毎の請求明細」をそれぞれ確認できるようになっている
招待されたアカウント(子アカウント)にログインして「請求ダッシュボード」を確認すると、
こちらでも親アカウントと同じく請求内容が表示されている
ただし「請求支払いアカウント: アカウント 123456789012」のように請求アカウントが表示されるようになっている
「お支払い情報」画面で、相変わらずクレジットカード情報も表示されている
組織から抜けたとき用にこのクレジットカード情報は保持され続けているが、このクレジットカードからの支払いは発生しない
Organizations画面から新規にAWSアカウントを作成した場合、クレジットカード情報はナシになる
よって情報を削除したり、カードの有効期限を更新したりは不要
…ということみたい
■AWS Single Sign-On
AWS Single Sign-On(クラウドシングルサインオン (SSO) サービス)| AWS
https://aws.amazon.com/jp/single-sign-on/
AWS Single Sign-On が東京リージョンで利用できるようになりました | Amazon Web Services ブログ
https://aws.amazon.com/jp/blogs/news/aws-single-sign-on-tokyo/
AWS SSOを図解してみた | DevelopersIO
https://dev.classmethod.jp/articles/aws-sso-wakewakame/
AWS SSO経由でマネジメントコンソールにサインインするときに常に東京リージョンのホーム画面を表示する方法 | DevelopersIO
https://dev.classmethod.jp/articles/aws-sso-relaystate-setting/
「シングルサインオンはいいぞ」 AWS Single Sign-Onのいいところ・イマイチなところ - ログミーTech
https://logmi.jp/tech/articles/323827
初期設定は以下が参考になるか
「バージニアリージョンでのみ利用可能」と書かれているが、今は東京リージョンでも使えるみたい
Organizationの親アカウントにログインして設定を行う
AWS SSOを使って複数AWSアカウントのログインを簡単にする! | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2019-12-26-082000/
■AWS SSO を有効化
主に以下の記事を参考に、SSOを実際に設定してみる
AWS Single Sign-On(SSO)でAWSアカウントへシングルサインオン - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2020/03/06/sso/
※今は東京リージョンに対応している
AWSコンソール → AWS Single Sign-On → AWS SSO を有効化
有効にすると、ダッシュボードが表示される
■グループを作成
※原則としてユーザに直接権限を割り当てずに、グループに割り当てる方が良さそう
左メニューから「グループ」をクリックし、さらに「グループを作成」ボタンをクリック
グループ名に「refirio-power-user」と入力し、「グループを作成」をクリック
■ユーザーを作成
左メニューから「ユーザー」をクリックし、さらに「ユーザーを追加」ボタンをクリック
ユーザーの詳細の指定
ユーザー名: refirio
パスワード: パスワードの設定手順が記載されたEメールをユーザーに送信します。
Eメールアドレス: info@refirio.net
名: Taro
姓: Yamada
グループ: refirio-power-user
上記の内容で「ユーザーを追加」ボタンをクリック
ユーザーが作成され、設定したメールアドレスに「Invitation to join AWS Single Sign-On」というメールが送られる
Hello Taro Yamada,
Your AWS Organization (AWS Account #123456789012) uses AWS Single Sign-On (SSO) to provide access to AWS accounts and business applications.
Your administrator has invited you to access the AWS Single Sign-On (SSO) user portal.
Accepting this invitation activates your AWS SSO user account so that you can access assigned AWS accounts and applications.
Click on the link below to accept this invitation.
[ Accept invitation ]
This invitation will expire in 7 days.
Accessing your AWS SSO User Portal
After you've accepted the invitation, you can access your AWS SSO user portal by using the information below.
Your User portal URL:
https://d-123456c78f.awsapps.com/start/
Your Username:
refirio
メール内の「Accept invitation」ボタンから承認する
「新規ユーザーのサインアップ」画面になるので、パスワードを設定する
パスワードを設定するとログイン画面が表示されるので、試しにログインしてみる
(メール内にある「Your User portal URL」からもアクセスできる)
この時点では、ログインしても「You do not have any applications.」とだけ表示される
■許可セットを作成
左メニューから「許可セット」をクリックし、さらに「許可セットを作成」ボタンをクリック
今回は「事前定義された許可セット」から「PowerUserAccess」を選択し、「次へ」をクリック
「許可セットの詳細」は特に変更せずに「次へ」をクリック
確認画面が表示されるので、問題無ければ「作成」をクリック
■グループに許可セットを割り当て
左メニューから「AWSアカウント」をクリック
「AWS accounts」の一覧でアクセスを許可したいアカウントにチェックを入れ、「ユーザーまたはグループを割り当て」をクリック
ユーザーもしくはグループを選択できるようになる
選択して「次へ」をクリック
許可セットを選択できるようになる
選択して「次へ」をクリック
確認画面が表示されるので、「送信」ボタンをクリック
少し待つと、AWSアカウント一覧画面に戻った
「Permission sets」の列に「PowerUserAccess」が表示されているので、完了できたみたい
■ログイン画面のURLを設定
※設定すると変更できないので注意
AWSコンソール → AWS Single Sign-On → 設定 → アイデンティティソース → アクション → ユーザーポータルURLのカスタマイズ
サブドメインとして「xxxxxx」を入力して保存
■動作確認
以下からログインできる
https://xxxxxx.awsapps.com/start
変更前の以下でもログインできる
https://d-123456c78f.awsapps.com/start/
ログインすると、「AWS Account (3)」のように表示されている
クリックすると、上で設定したアカウント3つが表示される
その中から「Management console」をクリックすると、AWSコンソールに遷移できる
とりあえず、捜査対象を「東京」リージョンにしておく
これでひとまず完了
■引き続き
ひととおりのアカウントをOrganizationsに紐づける
紐づけたら、許可セットは都度調整が必要のはず
問題無く扱えるようになったら、サーバメモにも記載しておく(パスワードは除いておく)
ポータルのURLは変更しておくと良さそう
ただし一度しか変更できないようなので慎重に
AWS SSOを使って複数AWSアカウントのログインを簡単にする! | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2019-12-26-082000/
■AWSアカウント追加時の作業
左メニューから「AWSアカウント」をクリック
「AWS accounts」の一覧でアクセスを許可したいアカウントに改めてチェックを入れ、「ユーザーまたはグループを割り当て」をクリック
※refirio, refirio-billing, refirio-security以外にチェックを入れた
ユーザーもしくはグループを選択できるようになる
選択して「次へ」をクリック
※refirio-power-userにチェックを入れた
許可セットを選択できるようになる
選択して「次へ」をクリック
※PowerUserAccessにチェックを入れた
確認画面が表示されるので、「送信」ボタンをクリック
少し待つと、AWSアカウント一覧画面に戻った
「Permission sets」の列に「PowerUserAccess」が表示されているので確認する
また、SSOでAWSコンソールにログインし、操作できるアカウントが変化していることを確認する
ログイン済みの場合、画面を再読み込みするだけでアカウントが変化した
■メモ1
SSOでAWSコンソールにログインすると、リージョンは「北カリフォルニア」になっていた
最初から「東京」にしたければ、以下が参考になりそう
とは言え、最初に選択すればいいだけ…なら、そのままでも大した問題では無いが
AWS SSO経由でマネジメントコンソールにサインインするときに常に東京リージョンのホーム画面を表示する方法 | DevelopersIO
https://dev.classmethod.jp/articles/aws-sso-relaystate-setting/
■メモ2
以下ページの最後に「どの環境にログインしているかわからなくなる」と書かれているが、実際判りづらい
良い方法が無いか調べる
AWS SSOを使って複数AWSアカウントのログインを簡単にする! | SEEDS Creators' Blog | 株式会社シーズ
https://www.seeds-std.co.jp/blog/creators/2019-12-26-082000/
■メモ3
「事前定義された許可セット」は以下から選択できる
「Billing」の権限なら、請求だけ確認できるユーザを作成できそうな
つまり、請求閲覧用の専用AWSアカウントを作るというより、専用ユーザを作るということ
同様に「SecurityAudit」の権限なら、セキュリティの確認だけできるユーザを作成できそうな
同様に、サーバ負荷を確認するだけのアカウントも作れるか
許可セットにそれらしいものは無いが、「ViewOnlyAccess」で専用ユーザを作るのがいいか
対応できたとして、AWSアカウントを作るたびに権限セットの調整が必要か
…と思ったが、そもそも勝手に権限が調整される方が問題ありそうなので、都度権限を調整すれば良さそう
・AdministratorAccess
Provides full access to AWS services and resources.
・Billing
Grants permissions for billing and cost management.
This includes viewing account usage and viewing and modifying budgets and payment methods.
・DatabaseAdministrator
Grants full access permissions to AWS services and actions required to set up and configure AWS database services.
・DataScientist
Grants permissions to AWS data analytics services.
・NetworkAdministrator
Grants full access permissions to AWS services and actions required to set up and configure AWS network resources.
・PowerUserAccess
Provides full access to AWS services and resources, but does not allow management of Users and groups.
・SecurityAudit
The security audit template grants access to read security configuration metadata.
It is useful for software that audits the configuration of an AWS account.
・SupportUser
This policy grants permissions to troubleshoot and resolve issues in an AWS account.
This policy also enables the user to contact AWS support to create and manage cases.
・SystemAdministrator
Grants full access permissions necessary for resources required for application and development operations.
・ViewOnlyAccess
This policy grants permissions to view resources and basic metadata across all AWS services.
■Cost Explorer
費用の詳細を確認できる
コンソール → AWS Cost Explorer
例えば
左のメニューから「コストと使用状況」を選択し、
右のフィルタから「サービス」を「Relational Database Service (RDS)」にして「フィルタの適用」を選択
すると、RDSの費用を確認できる
■リザーブドインスタンス
※未検証
1年もしくは3年間使うことを前提に、EC2やRDSなどの利用料金を抑えることができる
適用のさせかたは少々ややこしいようなので注意
リザーブドインスタンス(RI)- Amazon EC2 | AWS
https://aws.amazon.com/jp/ec2/pricing/reserved-instances/
リザーブドインスタンス - Amazon RDS | AWS
https://aws.amazon.com/jp/rds/reserved-instances/
AWS再入門2018 リザーブドインスタンス購入編 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-ri-2/
AWS再入門2018 リザーブドインスタンス購入編 その2 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/2018-aws-re-entering-ri-3/
AWSのリザーブドインスタンスで大失敗した件(前半)
https://novelel.com/index.php/2017/02/10/2317/
AWSのリザーブドインスタンスで大失敗した件(後半)
https://novelel.com/index.php/2017/02/11/2323/
■公式ツールによる試算
AWS Pricing Calculator
https://calculator.aws/
開始方法 - AWS Pricing Calculator
https://docs.aws.amazon.com/ja_jp/pricing-calculator/latest/userguide/getting-started.html
簡単にわかるAWS見積計算方法〜計算次第でAWS利用料は50%抑えられる〜|サービス|法人のお客さま|NTT東日本
https://business.ntt-east.co.jp/content/cloudsolution/column-245.html
AWS料金の見積もり方法を徹底解説 | SunnyCloud
https://www.sunnycloud.jp/column/20210122-01/
■試算例
月額 $ 181.41
・「Webサーバ2台、DBサーバ2台(RDSのマルチAZ)、ロードバランサーやS3も使う」というごく普通の構成
・t2.small 2台、db.t2.small 2台(マルチAZ)
・転送料は仮で「EC2から10GB/月」「S3から10GB/月」としている
「ALB + Web(2台) + DB(マルチAZ) + S3」という定番の構成で見積もりしたものを以下に作成した。旧ツールと金額に大差ないので大丈夫そう
https://calculator.aws/#/estimate?id=284aa4398f8d86c77c0620722f1b9152b3044007
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
ロードバランサー
│
┌───────┴───────┐
│ │
Webサーバ Webサーバ
│ │
└───────┬───────┘
│
データベースサーバ(2台構成)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■EC2の見積もりを作成したときのメモ
AWS Pricing Calculator
https://calculator.aws/
「見積もりの作成」ボタンをクリック
「サービスの選択」で「Search by location type」「リージョン」「東京」を選択する
「Find Service」に「EC2」と入力し、一覧に表示される「Amazon EC2」の「設定」をクリック
「Amazon EC2 を設定する」画面が開く
説明: Webサーバ
ロケーションタイプの選択: リージョン
リージョンの選択: アジアパシフィック(東京)
見積もり: 高度な見積もり
EC2インスタンスの仕様
オペレーティングシステム: Linux
ワークロード
毎月のワークロードを最もよく表すグラフ: 一定の使用量
インスタンス数: 2
EC2インスタンス
選択したインスタンス: t2.small
価格モデル: オンデマンド ... 実際に使うときに選択すべきものは、改めて検討したい
Amazon Elastic Block Storage (EBS)
各EC2インスタンスのストレージ: 汎用SSD(gp2)
ストレージ量: 50GB ... デフォルト値である30GBのままでいいかも
スナップショットの頻度: 毎日 ... 適切な値は改めて考えたい
スナップショットごとの変更量: 3GB ... 適切な値は改めて考えたい
データ転送
受信データ転送: Internet 1GB ... 適切な値は改めて考えたい
リージョン内データ転送: 1GB ... 適切な値は改めて考えたい
送信データ転送: Internet 10GB ... 適切な値は改めて考えたい
これで以下の金額になった
以前の見積もりには「スナップショット」が考慮されていなかったので、その分コストが追加されている
合計前払いコスト: 0.00 USD
合計月額コスト: 66.02 USD
「サービスを保存して追加」ボタンをクリック
これで「AWS Pricing Calculator → 自分の見積もり」に「Webサーバ」として見積もりが追加される
https://calculator.aws/#/estimate
画面左上にある「編集」をクリック
今回は名前を「基本的な構成」として「保存」をクリック
画面右上にある「共有」をクリック
パブリックサーバーに保存される旨が確認される。問題無ければ「同意して続行する」をクリック
以下のようにURLが発行され、後から確認や編集ができる
https://calculator.aws/#/estimate?id=9a286a5d07ea25d9fd9a84d3bbd751b5daad8657
■旧公式ツールによる試算
※旧公式ツールは廃止される予定らしい
原則「公式ツールによる試算」を参照する
※金額比較メモ1のだいぶ後に、仕事で見積もりを作成したときのメモ
※ある程度大きな案件なら、ElastiCacheも使う前提で考えておく方がいいかもしれない
また、メール送信のためにSESも大抵必要になる
(それぞれ、見積もりには含めていないので注意)
ロードバランサーを使う場合、WebサーバにEIPを割り当てて直接アクセスを許可するか、PrivateIPのみにしてデプロイサーバ経由でアクセスするか
メール送信のためにSPFや、外部APIを叩く際に固定IPでアクセス許可してもらう場合を考慮するなら、とりあえずEIPは割り当てるか
予算が許すなら、さらにBatchサーバ2台を追加して、その2台にEIPを割り当てるのも有効そう
メール送信や外部API連携など、固定IPが好ましい処理はそのサーバ経由で行う
要件によっては、S3やCloudFrontなども必要になる
運用のためにはCloudWatch、CloudWatchLogs、Zabbixなどの導入も考慮する
■1. Webサーバ2台、DBサーバ2台(ごく普通の推奨構成)
月額 $ 162.29
・「Webサーバ2台、DBサーバ2台(RDSのマルチAZ)、ロードバランサーやS3も使う」というごく普通の構成
・t2.small 2台、db.t2.small 2台(マルチAZ)
・転送料は仮で「10GB/月」としている
見積もり:
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=files/calc-2dbf71fce105f5593d...
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
ロードバランサー
│
┌───────┴───────┐
│ │
Webサーバ Webサーバ
│ │
└───────┬───────┘
│
データベースサーバ(2台構成)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■2. Webサーバ2台、DBサーバ2台(デプロイ用サーバがある場合の推奨構成)
月額 $ 161.25
・t2.small 2台、db.t2.small 2台(マルチAZ)
・デプロイ用サーバに t2.micro 1台
・その他ロードバランサーや転送料(仮で「10GB/月」としている)なども含めて
見積もり:
http://calculator.s3.amazonaws.com/index.html#r=NRT&key=calc-5A9B69FD-0569-4E7D-A7E0-3A2CC7B4E74...
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
ロードバランサー
│
┌───────┴───────┐
│ │
Webサーバ Webサーバ
│ │
└───────┬───────┘
│
データベースサーバ(2台構成)
※デプロイ(Webサーバの設定やコンテンツの配置)はデプロイサーバから行う
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■3. Webサーバ2台、DBサーバ1台
月額 $ 120.43
・上記からデータベースをシングルAZにしたもの
・シングルAZでも、RDSのバックアップ機能などは利用できる
見積もり:
http://calculator.s3.amazonaws.com/index.html#r=NRT&key=calc-FB1018C4-9266-40DA-A2A5-F88775F44CE...
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
ロードバランサー
│
┌───────┴───────┐
│ │
Webサーバ Webサーバ
│ │
└───────┬───────┘
│
データベースサーバ(1台構成)
※デプロイ(Webサーバの設定やコンテンツの配置)はデプロイサーバから行う
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■4. Webサーバ1台、DBサーバ1台
月額 $ 98.17
・上記からWebサーバもシングルAZにしたもの
・ロードバランサーはあるので、後々サーバの追加には対応できる
見積もり:
http://calculator.s3.amazonaws.com/index.html#r=NRT&key=calc-8609F2E1-8502-46C5-8AC5-979F2C190D3...
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
ロードバランサー
│
Webサーバ
│
データベースサーバ(1台構成)
※デプロイ(Webサーバの設定やコンテンツの配置)はデプロイサーバから行う
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■5. Webサーバ1台(非推奨構成)
月額 $ 47.94
・上記からデータベースサーバも無くしたもの。ロードバランサーやデプロイ用サーバも無し
・ロードバランサーを使わないので、AWS提供の無料SSLも使えない(Let's Encrypt などはもちろん使える)
・メンテナンスなどのためにWebサーバ(サイト)が止まっても支障が無い場合の構成
・サーバ台数を増やすなどの拡張性も考慮していない
・1台になる分、サーバスペックは少し上げている
・金額を重視する場合の構成。VPSのような感覚だが、AWSを使うメリットはあまり享受できない
見積もり:
http://calculator.s3.amazonaws.com/index.html#r=NRT&key=calc-60DE0C2F-1251-4B46-A4CF-9655BD6AD56...
構成図:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
インターネット
│
Webサーバ
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
■6. 転送量の多いバージョン
1ページ5MB、1ヶ月600万アクセス
よって1ヶ月のOUT転送料30TB
10TBはEC2からOUT、20TBはS3からOUTとする
転送料を月10GBにした場合(普段よく使う転送料設定)
$ 341.57
http://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=calc-264D2D35-E091-4E9E-8A16-7...
上の見積もりから、EC2からの転送料(OUT)を10TBに、S3からの転送料(OUT)を20TBに、RDSからの転送料を100GBに
$ 3662.04
http://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=calc-7487A647-CB17-4F4A-A08B-8...
■7. 色々なスペック
Webサーバ・DBサーバともにmedium
$ 341.57
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=calc-47410FB3-E165-46D3-94CF-...
Webサーバ・DBサーバともにsmall
$ 191.67
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=calc-52919F8B-066D-4687-8C70-...
Webサーバ・DBサーバともにmicro
$ 127.24
https://calculator.s3.amazonaws.com/index.html?lng=ja_JP#r=NRT&key=calc-409B5BE7-6705-4ECA-ACF2-...
■制限内容をコンソールから確認・申請
以下 AWS Service Quotas にアクセスすると、制限内容の確認と緩和の申請ができる
http://console.aws.amazon.com/servicequotas/
2019年9月24日時点で、コンソールホームのサービス一覧にはリンクがない?
リリースされて間もないサービスだからかも?
Amazon SES など、現時点では対応してないサービスもあるとのこと
サービスクォータのご紹介: AWS のサービスのクォータを一元的な場所から表示および管理する
https://aws.amazon.com/jp/about-aws/whats-new/2019/06/introducing-service-quotas-view-and-manage-quo...
Introducing Service Quotas: View and manage your quotas for AWS services from one central location | AWS Management Tools Blog
https://aws.amazon.com/jp/blogs/mt/introducing-service-quotas-view-and-manage-your-quotas-for-aws-se...
■メールの制限緩和
※メールの制限緩和は、どんどんハードルが高くなっている
AWSとしてはEC2からのメール送信ではなく、SESからのメール送信を推奨しているらしい
SESでの制限解除については、このファイル内の「SES メール送信 > 送信制限の解除」を参照
※メールの制限緩和は、今は以下のページからボタンを押すだけで簡単に申請できるみたい
この制限緩和申請に対応しているかは未確認だが、次回申請の際に確認したい
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/services/ec...
※逆引き設定は、今は「EC2 → Elastic IP」のページで申請なしに行なえるみたい
対象のEIPを選択して「アクション → 逆引きDNSを更新」から設定できるみたい
設定後、数分で反映されるみたい(未検証)
https://dev.classmethod.jp/articles/vpc-customers-customize-reverse-dns-elastic-ips-in-all-regions/
https://dev.classmethod.jp/articles/amazon-virtual-private-cloud-vpc-customers-customize-reverse-dns...
EC2インスタンスからメール送信のための準備
https://cloudpack.media/11249
Request to Remove Email Sending Limitations
https://aws.amazon.com/forms/ec2-email-limit-rdns-request?catalog=true&isauthcode=true
メール送信のための申請。
「申請方法」のスライドのP.5を参考に
メールを送りたいEC2のIPアドレスとドメインを記載する
逆引き設定の申請を行っておかないと、Gmailに迷惑メール判定される可能性が高い
上限緩和のみではなく、合わせて逆引き設定の申請を行っておく方が良さそう
以前はすんなり許可されたが、途中から具体的な説明を求められるようになった
以下、2020年5月にすんなり許可された内容
(この後に記載している「やりとり参考」をもとに書いた文章)
Use Case Description:
Removal of E-mail sending limit ... Eメール上限緩和のみの場合
Removal of E-mail sending limit width rDNS registration ... Eメール上限緩和/逆引き(rDNS)設定の場合
I develop Web applications and Web sites on business. I belong to the following company.
https://refirio.net/
We are developing a number of Web services. And You can also contact us on the company website.
We also describe our 'Privacy policy' and our 'Deal with personal information' in the footer text.
https://refirio.net/info/privacy-policy
https://refirio.net/info/deal-with-personal-information
Below is the client's website.
https://example.com/
Email is used by Contact form. (Under construction.)
And below is the privacy policy.
https://example.com/privacy/
https://example.com/personal/
I use email to receive inquiries. It does not transmit to the unspecified number of people.
Elastic IP address: 203.0.113.1
Reverse DNS record: web1.refirio.net
Elastic IP address: 203.0.113.2
Reverse DNS record: web2.refirio.net
$ dig -x 203.0.113.1
$ dig -x 203.0.113.2
で反映を確認できる
EC2のメール送信の制限解除申請およびDNS逆引き申請
https://forums.aws.amazon.com/thread.jspa?threadID=153660
メールの送信制限は、アカウント単位で解除される
AWS上にメールサーバを立てる(Postfix+Dovecot)
http://qiita.com/gitya107/items/06ab7c90960a2d2d9f46
AWS 逆引き申請手順(rDNS) - Qiita
https://qiita.com/tomozo6/items/5f3f4f674d3bcd924f17
なお、DNSがRoute53以外(お名前.comなど)で管理されている場合でも、申請先はAWSで大丈夫だった
ドメインに対する設定ではなく、IPアドレスに対する設定だから?要勉強
■やりとり参考1
申請解除を依頼すると以下のメールが届いた
Hello,
Thank you for submitting your request to have the email sending limit removed from your account and/or for an rDNS update.
We will require the following before this request can be processed:
* A clear/detailed use-case for sending mail from EC2.
* A statement indicating how you intend to ensure this account is not implicated in sending of unwanted mail.
Please reply directly to this message with the above information. Once this has been received we can process your original request.
As a reference, please make sure to review the AWS Acceptable Use Policy (https://aws.amazon.com/aup/) for more information regarding prohibited uses of AWS services.
Note: Violations of the AWS Acceptable Use Policy may result in mitigation of identified activity or content.
Best regards,
http://aws.amazon.com
---- Original message: ----
AWS AccountId 1234567890
AccountEmailAddress example@refirio.net
UseCaseDescription Removal of E-mail sending limit
ElasticIPAddress1 203.0.113.1
ElasticIPAddress2 203.0.113.2
ReverseDNSRecord1
ReverseDNSRecord2
Submission received from source IP Address 203.0.113.0
AWS Account ID 1234567890
Root Customer ID A1MR1I664SN08C
IAM Account No
Email Address example@refirio.net
Name salute-lab
DNS調整後、以下の内容を返信した
さらに改めて以下の問い合わせを送った
以下の返信が来て制限が解除された
■やりとり参考2
以下のような返信が来ることもある
Hello,
Thank you for your response
Please provide us with the following information as well:
* A statement indicating how you intend to ensure this account is not implicated in sending of unwanted mail.
We appreciate your cooperation, as soon as we receive this information we can move forward with your request.
If you have any questions, please reach out to us.
Regards,
Amazon Web Services
このときは、以下のような返信をして、制限が解除された
Thank you for support.
> * A statement indicating how you intend to ensure this account is not implicated in sending of unwanted mail.
I develop Web applications and Web sites on business. I belong to the following company.
https://refirio.net/
We are developing a number of Web services. And You can also contact us on the company website.
We also describe our 'privacy policy' and our 'handling of personal information' in the footer text.
https://refirio.net/privacy-policy
https://refirio.net/privacy-policy-deal
Is this the information you need?
If you need more information, please tell me the details.
■やりとり参考3
以下のような返信が来ることもある
Thank you for submitting your request to have the email sending limit removed from your account and/or for an rDNS update.
This account, or those linked to it, have been identified as having at least one of the following:
* A history of violations of the AWS Acceptable Use Policy
* A history of being not consistently in good standing with billing
* Not provided a valid/clear use case to warrant sending mail from EC2
Unfortunately, we are unable to process your request at this time, please consider looking into the Simple Email Service.
https://aws.amazon.com/ses/
Regards,
Amazon Web Services
このときは、以下のような返信をして、制限が解除された
Thank you for your review.
> Not provided a valid/clear use case to warrant sending mail from EC2
・Send mail from only web system.
・Send auto-reply email based on user action.
・Build MTA and take necessary measures such as SPF / DKIM / rDNS.
・Establish a secretariat and check bounce emails.
・User can refuse to receive email.
Regards.
■やりとり参考4
何度申請しても以下の返信が送られてくることがあった
This account, or those linked to it, have been identified as having at least one of the following:
* A history of violations of the AWS Acceptable Use Policy
* A history of being not consistently in good standing with billing
* Not provided a valid/clear use case to warrant sending mail from EC2
このときは、最終的に「やりとり参考3」の返信をして制限が解除されたが、
AWSの「ISV/SaaS営業本部」の方に確認すると以下の返信があった
SESの制限緩和についてはGlobalサポートの専門部署が対応しており、
貴社AWSアカウントIDにおいて具体的に却下された理由を確認することができないのですが、
そのうえで過去の経験から、以下の可能性がございます。
今回の件ですが、おそらく引っかかっているのが「新規作成アカウント」であるという点かと思います。
「2.請求に関して一貫して良好な状態にない」で確認しているのは、「そのアカウントにおいて支払い実績があるか」という点だと思いますが、
新規作成アカウントで支払い実績が無い場合は信頼できるアカウントではない、ということで却下された事例が過去にもありました。
AWSで特定の利用実績を条件としている場合、基本的に新規アカウントでは申請が通りにくい、という傾向があります。
もし他の既存のAWSアカウントにてSESを用いたワークロードの構築が可能なのであれば
そのアカウントから再度申請いただくことで解決する可能性がありますが、
お試しいただくこと可能でしょうか?
「SESの制限緩和」と書かれてはいるが、EC2の場合でも同じとのこと
「新規アカウントだから=支払い実績が無いから」が申請却下の理由になりうるなら、
新規にアカウントを作って、すぐにメールの制限緩和申請をして、すぐにリリース…という予定を立てるのはリスクがあるかもしれない
(ただし前述のとおり、今回は支払い実績は関係なかったみたい)
■やりとり参考5
以下の返信が送られてきて、やり取りを終了させられたことがあった
Thank you for submitting your request to have the email sending limit removed from your account and/or for an rDNS update.
After a thorough review, we confirmed our original finding and cannot grant your request.
Please consider looking into the Simple Email Service (SES)
https://aws.amazon.com/ses/.
We cannot assist you further with this issue and we may not respond to additional messages on this subject.
「リクエストは許可できません。SESの利用を検討してください。
この問題に関しては、これ以上のサポートはできません。追加のメッセージにも応答しないことがあります。」
とのこと。やはりAWSとしてはEC2からのメール送信ではなく、SESからのメール送信に切り替えさせたいのか。
このときはSESの利用申請を出し、それはすぐに(申請した翌日に)許可された
■ElasticIP数の制限緩和
■Service Quotasから制限緩和
本番環境用にElasticIPを割り当てる際、以下が表示された
Elastic IP アドレスを割り当てることができませんでした。
The maximum number of addresses has been reached.
AWSコンソールにアクセス(rootアカウントでなくてもいい)
サポート → Service Quotas → Amazon Elastic Compute Cloud (Amazon EC2) → EC2-VPC Elastic IPs
以下にたどり着く
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home/services/ec2/quotas/L-0263D0A3
「クォータの引き上げをリクエスト」ボタンをクリック
「クォータの引き上げをリクエストする: EC2-Classic Elastic IPs」画面に以下が表示される
クォータの名称: EC2-VPC Elastic IPs
説明: The maximum number of Elastic IP addresses that you can allocate for EC2-VPC in this Region.
使用率: 利用不可
適用されたクォータ値: 5
AWS のデフォルトのクォータ値: 5
リージョン: アジアパシフィック (東京) ap-northeast-1
画面下部の「クォータ値を変更」に、今回は「8」を入力して「リクエスト」ボタンを押した
画面上部に「EC2-VPC Elastic IPs に対してクォータの引き上げがリクエストされました。」と表示された
「最近のクォータ増加リクエスト」に、ステータスが「保留中」として記録されている
3時間ほどしてから確認すると、ステータスが「承認されたクォータリクエスト」になっていた
(承認されたタイミングは不明なので、実際はもっと早かったかもしれない)
改めてElasticIPの割り当てを行うと、すんなり完了された
■サポートセンターから制限緩和(以前のメモ)
AWS サービス制限
http://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html
AWS アカウント当たり、1 リージョン内の Elastic IP アドレスの数: 5
Amazon固定IP追加申請画面
http://aws.amazon.com/jp/contact-us/eip_limit_request/
ElasticIP数は5つまでに制限されているので、緩和には申請が必要
以下から申請できる
サポート(メニュー右上) → サポートセンター → Create case
以下、記載例。
CC:
(メールアドレスを入力)
内容:
サービス制限の増加
制限タイプ:
Elastic IPs
リクエスト1 リージョン:
アジアパシフィック(東京)(固定IP追加したいリージョンを選択)
制限:
ご希望のVPC Elastic IP アドレスの合計数(VPCを使っているので「EC2-Classic Elastic IP アドレス上限」では無い…はず)
新しい制限値:
10(あくまでも一例)
リクエスト2:
(設定せず)
申請理由の説明:
弊社の新サービスを構築するためにIPアドレスが必要です。(あくまでも一例)
お問い合わせ言語:
日本語
連絡方法:
Web
AWSの固定IPアドレスのリミットを解除する方法
http://x-moemoe.blogspot.jp/2015/02/awsip.html
■EC2インスタンス数の制限緩和
※今は以下のページから、ボタンを押すだけで簡単に申請できるみたい
この制限緩和申請に対応しているかは未確認だが、次回申請の際に確認したい
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/services/ec...
[AWS]EC2インスタンス上限緩和申請をしてみた
http://shomi3023.com/2017/11/10/post-1073/
EC2インスタンス数は20まで(インスタンスサイズによる)に制限されているので、緩和には申請が必要
以下から申請できる
サポート(メニュー右上) → サポートセンター → Create case
以下、記載例。
内容:
サービス制限の緩和
制限タイプ:
EC2インスタンス
リクエスト1
リージョン: アジアパシフィック(東京)(設置したいリージョンを選択)
プライマリインスタンスタイプ: t2.small
制限: インスタンス上限
新しい制限値: 25
申請理由の説明:
弊社の新サービスを構築するために、上限数以上のインスタンスを起動する必要があります。(あくまでも一例)
お問い合わせ言語:
日本語
連絡方法:
Web
■SMS送信数の制限緩和
※今は以下のページから、ボタンを押すだけで簡単に申請できるみたい
この制限緩和申請に対応しているかは未確認だが、次回申請の際に確認したい
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/
https://ap-northeast-1.console.aws.amazon.com/servicequotas/home?region=ap-northeast-1#!/services/ec...
AmplifyでSMS認証を導入する際に注意すること!SNSの上限緩和申請に迫る | Ragate ブログ
https://www.ragate.co.jp/blog/articles/713
AWSでSMSを送る際の月々の利用制限緩和 - Qiita
https://qiita.com/Kuchitama/items/0ed375b0ae439e367b1d
標準では1ドル分(10数通程度)までしか送信できないので、緩和には申請が必要
rootアカウントでログインして申請する
サポート → サポートセンター → Your support cases → Create case
以下の内容で申請
Create case: Service limit increase
Limit type: SNS Text Messaging
Request 1: 一般的な制限事項
New limit value: 10
Use case description: サービス検証にあたり、SESのSMS送信上限を、10ドルに設定したいです。ご検討のほどお願いいたします。
Preferred contact language: 日本語
「Submit」をクリックすると登録された
翌日に以下の返信が来た。情報が不足しているとのこと
平素は Amazon Web Servicesをご利用いただき、誠にありがとうございます。
お客様の使用限度額の引き上げの申請内容を慎重に審査した結果、
申請をお受けするにはお客様のユースケースに関する情報が不十分であるという判断に至りました。
ケースの審査をお受けいただくには、以下の追加詳細をこのメールへ返信してください。
-- SMS を送信するサイトまたはアプリのリンクまたは名前:
-- メッセージの種類 (トランザクション/プロモーション/ワンタイムパスワード)
-- オプトインプロセスと、リクエストした人にのみメッセージが送信されるようにするその他の方法の詳細:
-- ユーザーによる API/サービスの呼び出し元になる AWS リージョン:
-- メッセージの受信者が所在している国の一覧:
-- 1 日あたりに送信することが見込まれる最大メッセージ数:
-- この国用のメッセージテンプレート:
この情報を受け取り次第、お客様の申請を審査させていただきます。24時間以内にご連絡をいたします。
必要な情報をすべてご提示いただいた場合は、24時間以内に申請を承認いたします。追加で情報が必要な場合は、実装に長くかかる可能性がございますことをご了承ください。
しばらくの間ケースへ返信がない場合、システムが自動的にケースをクローズする場合があることをご了承ください。
ケースがクローズされる前に、お客様には通知をお送りいたします。ケースをオープン状態に保持する場合、本ケースにご返信くださいますようお願いいたします。
SMS メッセージの送信における各国の現在のキャリア料金については、ワールドワイド SMS 料金ページをご覧ください。
https://aws.amazon.com/jp/sns/sms-pricing/
Amazon Web Services をご利用いただき、誠にありがとうございます。
以下の内容を返信した。
お世話になります。
ご返信ありがとうございます。
ご依頼いただいた情報につきまして、以下の通り提供させていただきます。
-- SMS を送信するサイトまたはアプリのリンクまたは名前:
開発中のシステムの実験と検証のために利用させていただきます。従いまして、外部へ公開するものではございません。
-- メッセージの種類 (トランザクション/プロモーション/ワンタイムパスワード)
トランザクション
-- オプトインプロセスと、リクエストした人にのみメッセージが送信されるようにするその他の方法の詳細:
あくまで開発のための検証に利用するため、利用は社内の開発者のみになります。
-- ユーザーによる API/サービスの呼び出し元になる AWS リージョン:
東京リージョン
-- メッセージの受信者が所在している国の一覧:
日本
-- 1 日あたりに送信することが見込まれる最大メッセージ数:
50通程度
-- この国用のメッセージテンプレート:
検証用のため、定型文はありません。
以上、よろしくお願いいたします。
半日ほどで以下の返信が来た。制限が緩和された
■逆引き(rDNS)設定解除(EIPを開放できなかったとき)
■2023年時点で確認した内容
「EC2 → ElasticIP」で対象のIPアドレスを選択し、「アクション → 逆引きDNSの更新」から自身で登録更新削除できるようになっている
設定の反映には、少し時間がかかるみたい
ただしこの操作を行って3日ほど経ってからEIPの解放を試しても、以下のようなエラーになった
Elastic IP アドレスを解放できませんでした。
203.0.113.1: The address with allocation id [eipalloc-01234567890123456] cannot be released because it is locked to your account. Please contact AWS Support to unlock it.
以下を参考に、
「The address with allocation id cannot be released (割り当て ID を持つアドレスをリリースできません)」というエラーを解決する
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-address-errors/
AWSでのElastic IP逆引き解除申請の正しいやり方 2021年3月版 - 株式会社ネディア │ネットワークの明日を創る│群馬
https://www.nedia.ne.jp/blog/2021/03/16/17601
以下の内容で申請を行った
Email address: (使用しているメールアドレス)
Use case description: rDNS の削除をリクエストする特定のユースケースです。
IPs information: 203.0.113.1 / DNS を削除してください
翌日に以下の返信が来た
対応してくれたが「反映されるまで最大1週間かかることがある」とのこと
We have removed the reverse DNS record you requested!
Please note that propagation of this update to DNSBL services that Amazon works with may take up to a week.
Please let us know if you have any questions.
さらに翌日にEIPの解放を試すと、無事に完了できた
■以前試した内容
EIPが解放できなかった場合の対応方法 | DevelopersIO
https://dev.classmethod.jp/cloud/aws/eip-cannot-be-released/
Request to Remove Email Sending Limitations
https://aws.amazon.com/forms/ec2-email-limit-rdns-request?catalog=true&isauthcode=true
メール送信のための申請。
以下、記載例。
Use Case Description:
Reset rDNS
Elastic IP Address 1:
203.0.113.1
Elastic IP Address 2:
(空欄)
Reverse DNS Record for EIP 1:
(空欄)
Reverse DNS Record for EIP 2:
(空欄)
申請後、3時間ほどで返信が来て設定が解除された
■AWS Organizationsアカウント数の制限緩和
招待しようとしたとき、以下のように表示された
招待済みのアカウントは10になっている。上限に引っかかったみたい
「3」個のアカウントを正常に招待しました。
招待されたアカウント
・111111111111
・222222222222
・333333333333
「2」個のアカウントを招待できませんでした。
・444444444444: HandshakeConstraintViolationException
You have exceeded the allowed number of AWS accounts.
・555555555555: HandshakeConstraintViolationException
You have exceeded the allowed number of AWS accounts.
AWS Organizations のクォータ - AWS Organizations
https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/orgs_reference_limits.html
「組織のAWSアカウントの数: 10」となっている
「Service Quotas コンソールを使用して、これらの値の一部を引き上げるよう要求できます。」とある
案内に従って、以下にアクセスしてみる
https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/organizations/quotas
「AWS Organizations」のサービスクォータが表示される
リージョンは「us-east-1」になっているが、Organizationsは物理的にはここでホストされているらしいので、問題無いらしい
「Default maximum number of accounts」のデフォルトのクォータ値は「10」となっていて、調整可能は「はい」と表示されている
以下で申請してみる(「クォータ値を変更」を「20」に変更した)
クォータの名称: Default maximum number of accounts
説明: The default maximum number of accounts allowed in an organization.
使用率: 利用不可
適用されたクォータ値: 利用不可
AWS のデフォルトのクォータ値: 10
リージョン: 米国東部 (バージニア北部) us-east-1
クォータ値を変更: 20
16:30 に申請。ステータスは「保留中」となっていた
16:40 に確認すると、ステータスは「リクエストされたクォータ」となっていた
また少し時間をおいて確認する
https://us-east-1.console.aws.amazon.com/servicequotas/home/requests
同日の 17:40 に「I’m happy to inform you that we've approved and processed the below request:」な内容のメールが来た
「Please keep in mind that it can sometimes take up to 15 minutes for the new limit to take effect and become available for use.」
と書かれているが、増加はすぐに確認できなかった
翌日に確認しても特に表示は変わっていなかったが、10以上の子アカウントを持つことができるようになっていた
■侵入テスト
脆弱性テストと侵入テスト
https://aws.amazon.com/jp/security/penetration-testing/
侵入テストを行うには、あらかじめ申請が必要…だったが、2019年からは申請不要になっている
AWS、侵入テスト申請やめるってよ - とある診断員の備忘録
http://tigerszk.hatenablog.com/entry/2019/03/05/190815
【ELB】AWS ELBの負荷テストをJMeterServer群でやる【負荷テスト】
http://qiita.com/takudo/items/1e4dac976cfbd3c775d2
ELB経由で負荷テストを行う場合、DNSキャッシュに注意
■中国向けコンテンツの作成メモ
■チャイナリスク
チャイナリスクには常に注意が必要
予告なく変化する可能性があるので、「後から状況が変わった場合は別途検証してお見積り」などと書いておくか
中国進出の際に考えておきたいチャイナリスクとは? | BizAppチャンネル
https://www.cloudtimes.jp/dynamics365/blog/considering-china-risks
■グレートファイアウォール
中国内から日本のサイトを自由に閲覧するにはVPNが必須となっているらしい
2017年に無料のVPNに規制がかかり、中国政府に認可されたVPNしか利用できなくなっているらしい
コロナウイルスの影響で、さらに規制が厳しくなったりもしているらしい
予告なしに規制が強まる可能性も十分ありそう
ある日突然アクセス制限されても緊急対応は難しい旨を明記しておくか
グレートファイアウォールとは?世界最高峰のセキュリティシステム | SKYARCHのITあんちょこ
https://www.skyarch.net/column/great-firewall/
中国のVPN規制ますます厳しく!【2021年1月最新】今使えるおすすめは? - たびハック
https://tabihack.jp/vpn/
中国で使えるおすすめのVPN 8選【2021年】
https://ja.vpnmentor.com/blog/%E4%B8%AD%E5%9B%BD%E3%81%AB%E6%9C%80%E9%81%A9%E3%81%AAvpn%E3%83%A9%E3%...
【2021年6月更新】中国で使えるおすすめVPN|全て現地で徹底比較・接続確認済み!
https://bestvpn.jp/best-vpn-in-china/
中国で必須|VPNとはなにか - 中国Wi-Fi・VPN研究所
https://lb-hikaku.com/vpn-naninani/
中国でのVPN利用はもう不可能?通信制限を回避できるVPNとは | ITreviewブログ
https://www.itreview.jp/blog/archives/3803
グレートファイアウォールの制限対象かどうかは以下で確認できるらしい
Test if Any Site is Blocked in China and Learn How to Access it
https://www.comparitech.com/privacy-security-tools/blockedinchina/
■AWSアカウント
「中国国内から直接閲覧可能」を重視する場合、中国国内にサーバを置く必要があるかもしれない
AWSには中国リージョンがあるが、
・AWSの中国リージョンは他リージョンとは切り離されている
・中国リージョンを使うには、中国専用のアカウントが必要
・現地法人がない場合には、アカウント自体が発行できない
・日本側から運用管理を行う場合、国際回線経由で中国のAWS環境にアクセスする必要があるが、国際回線でしばしば障害が発生してつながらなくなる
などがあり、簡単には進められ無さそう
また、Route53やVPN Gatewayなど使えない機能もあるみたい
どうしてもAWSの中国リージョンを使いたい場合、元請けにAWSアカウントを用意してもらうなどを考えたほうが良さそう
AWSに限らず、
・中国でWebに公開する仕組みを提供する場合は、必ずICP登録の申請を行う必要がある
申請できるのは現地企業のみとなっている
・個人情報や重要情報の保管が中国国内に限定されている
らしい
【知っておきたい】中国でAWSを使う時、注意すべき3つのポイント
https://www.tis.jp/special/platform_knowledge/cloud05/
中国でのビジネス展開のために知っておくべきこと - AWS中国の最新情報とベストプラクティス
https://pages.awscloud.com/rs/112-TZM-766/images/H1-07.pdf
■クレジットカード情報の更新
※以下は同一クレジットカードで有効期限だけ更新したときのメモ
有効期限を変更するだけなら、カード番号やCVCは不要だった
ルートアカウントでAWSコンソールにログインする
右上のアカウント名をクリックし、「マイ請求ダッシュボード」へ遷移する
左メニューの「お支払方法」から、対象のカードの「編集」からカード情報を更新できる
有効期限を編集し、ページ下の「更新」ボタンを押せば完了
■クレジットカード不備による決済の遅延
請求の未払いによりアカウントが一時停止された場合、対応せずに放置するとアカウントが削除されてしまう
・停止から 60 日以内にアカウントが最有効化されない場合、アカウントのリソースが失われ、アカウントが解約される
・解約から 90 日以内にアカウントが再有効化されない場合、アカウントが削除される
・削除された アカウントは再開できず、アカウントの全リソースが失われる
AWS の請求書を支払おうとしたときにクレジットカードが拒否された
https://aws.amazon.com/jp/premiumsupport/knowledge-center/credit-card-declined/
一時停止された AWS アカウントの再有効化
https://aws.amazon.com/jp/premiumsupport/knowledge-center/reactivate-suspended-account/
AWSの料金支払いが遅れるとどうなるのか - DENET 技術ブログ
https://blog.denet.co.jp/what-happens-when-aws-fees-are-delayed/
■サービス終了時のリソース削除
※後ろから停止させていくとエラーが出るので、原則として前から順に停止させるといい
ElasticIPの開放時に以下のエラーが表示された
DNS逆引きの解除が必要とのこと
52.69.207.90:
The address with allocation id [eipalloc-112d8f74] cannot be released because it is locked to your account.
Please contact AWS Support to unlock it.
解除については、このファイル内の「逆引き(rDNS)設定解除(EIPを開放できなかったとき)」を参照
以下、実際に行った作業内容メモ
・Zabbixでの監視を停止
・CloudWatchの設定を削除
・ロードバランサーを削除
・各EC2を停止&AMIを作成&削除
・各ElasticIPの関連付けを解除&アドレスの開放
・ElastiCacheのバックアップを作成
・ElastiCacheを削除(削除時に最終バックアップを作成)
・RDSを削除(削除時に最終スナップショットを作成)
・AWS Config にも課金があったので、「設定」から記録をオフに
・Route53のレコードセットをすべて削除(一括削除しても、NSとSOAの設定は残った)
・Rtoute53のホストゾーンを削除
・S3の公開バケットを削除(config用とcloudtrail用は残している)
・VPCは無課金なのでそのまま(削除するなら、必要に応じてCloudFormationも削除する)
・EIPの逆引き解除申請がとおってから、削除できなかったEIPを削除
以下についても、削除し忘れないように注意する
・EC2のAMIやEBS
・RDSのスナップショット
・S3のバケット
・CloudTrailやConfig
AMIユーザとアクセスキーも、残しておくとセキュリティホールになりかねないので無効化もしくは削除する
■アカウントの解約
アカウントを残しておく必要自体がなければ、以下で紹介されているようにアカウントの解約を行うといい
アカウントの解約 - AWS 請求情報とコスト管理
https://docs.aws.amazon.com/ja_jp/awsaccountbilling/latest/aboutv2/close-account.html
解約の前に、各リソースの削除を行っておく
詳細はこのファイル内の「サービス終了時のリソース削除」を参照
シングルサインオンの設定をしている場合、先にアカウントの割り当てを解除しておくと良いかもしれない
アカウント解約後だと、組織アカウントから除外するまで表示され続けるかもしれない
以下、実際にアカウントを解約したときのメモ
画面右上のアカウント名部分から「アカウント」をクリック
※「アカウント設定」の右にある「編集」から、必要に応じてメールアドレスを編集する
(アカウントに設定されていたメールアドレスと同じアドレスで、次回AWSアカウントを作ることはできないので注意)
ページ最下部の「アカウントの解約」から解約
以下について同意を求められるので、確認してチェックを入れる
・私はこのチェックボックスをクリックすることにより、自分の AWS アカウントが閉鎖されることを理解しています。私は AWS アカウントの解約をもって、自身のアカウントに限定して当該アカウントを規定する AWS カスタマーアグリーメントを含むすべてのアグリーメントを終了させる意思を AWS に通知いたします。
特定の AWS サービスの月次使用料金は翌月の月初に算出、請求されます。当月にこれらのサービスを私が使用していた場合は、アカウント閉鎖以前に発生した使用料金の請求を翌月月初に受領します。さらに現在有効なサブスクリプションがある場合は (月次支払い指定リザーブドインスタンスなど)、そのサブスクリプションの終了、または当該サブスクリプションを規定する条件に従って売却されるまで、アカウント閉鎖後であっても引き続きサブスクリプションに対する請求を受けることについて差し支えありません。
私は、アカウント閉鎖から 90 日以内 (「閉鎖後期間」) は、自分の AWS アカウントを再開できることを認識しています。閉鎖後期間中に私がアカウントを再開した場合は、アカウント閉鎖以前に未終了であった AWS サービスすべてに対する料金が私に請求されることについて差し支えありません。自分の AWS アカウントを再開した場合は、再開した AWS アカウントに対して同じ条件が AWS サービスに対するアクセスと利用に適用されることに同意します。
閉鎖後期間が過ぎてもアカウントを再開しない場合、AWS アカウントに残っているコンテンツはすべて削除されます。詳細については、Amazon Web Services の [アカウント閉鎖 ページ] を参照してください。
・私は、閉鎖後期間が過ぎると、閉鎖したアカウントを再開できなくなることを認識しています。
・私は、閉鎖後期間が過ぎると、請求コンソールにアクセスして過去の請求書や課税書類をダウンロードできなくなることを認識しています。
[#/請求の明細書はすべて、こちらからダウンロード]。月を選択し、概要セクションを展開し、支払い請求書や課税書類をダウンロードします。
・私は、閉鎖後期間が過ぎると、このアカウントと現在関連付けられている E メールアドレスを使用して AWS アカウントを新規作成できなくなることを認識しています。
E メールアドレスの更新をご希望の場合は、こちらの指示に従ってください。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/change-email-address/
しばらく待ち、削除された旨が表示されたらコンソールからログアウトする
ログインできないことを確認する
5〜10分程度で、AWSから「AWS Unified Registration Cancellation」というメールが届く
内容は以下のとおり
Greetings from Amazon Web Services,
This e-mail confirms that you have closed your Amazon Web Services account.
If you closed your AWS account after the first day of any month you may still receive another bill.
In addition, if you have any active subscriptions (such as a Reserved Instance for which you have elected to pay in monthly installments), then even after your account is closed you may continue to be billed for the subscription until the subscription expires or is sold in accordance with the terms governing the subscription.
Please see the Billing & Cost Management page at
https://console.aws.amazon.com/billing/home for details about any remaining charges applicable to the services you have used.
If you feel you have received this e-mail in error or wish to reopen your AWS account, please contact AWS Customer Service via the Support Center at
https://aws.amazon.com/support.
You may only reopen your AWS account within 90 days after you closed your account.
After 90 days, you will not be able to reopen your account, and any remaining content in your closed account will be deleted.
For more details, please visit the Amazon Web Services Account Closure page at
https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/close-account.html
Sincerely,
Amazon Web Services
Amazon Web Services, Inc. is a subsidiary of Amazon.com, Inc. Amazon.com is a registered trademark of Amazon.com, Inc. This message was produced and Distributed by Amazon Web Services Inc., 410 Terry Ave. North, Seattle, WA 98109-5210
アカウントによっては日本語のメールで送信されてきた
内容は以下のとおり
アマゾン ウェブ サービスをご利用いただきありがとうございます。
この E メールは、お客様のアマゾン ウェブ サービスアカウントが閉鎖されたことを確認するものです。
月の 1 日目以降に AWS アカウントを閉鎖した場合、引き続き別の請求書が届く可能性があります。
使用したサービスに適用される未請求の料金の詳細については、請求とコスト管理コンソールを参照してください。
請求とコスト管理コンソールでは、過去の請求書や税金書類をダウンロードすることもできます。
この E メールが間違って送信されたと思われる場合、または AWS アカウントの再開を希望される場合は、サポートセンター (https://aws.amazon.com/support) を通じて AWS カスタマーサービスにご連絡ください。
AWS アカウントを再開できるのは、アカウントの閉鎖後 90 日以内に限ります。
90 日を過ぎると、アカウントの再開、このアカウントに関連付けられた E メールアドレスを使用した新しい AWS アカウントの作成、請求とコスト管理コンソールへのアクセスはできなくなり、閉鎖されたアカウントに残っているコンテンツは削除されます。
過去の請求書や税金書類のダウンロードを希望する場合は、こちらで行うことができます (月を選択し、概要セクションを展開して、請求書、税金書類、またはその両方をダウンロードします)。この操作は閉鎖後 90 日を過ぎるとできなくなります。
詳細については、アマゾン ウェブ サービスアカウントの閉鎖ページを参照してください。
今後ともどうぞよろしくお願いいたします。
アマゾン ウェブ サービス
Amazon Web Services, Inc. は Amazon.com, Inc. の子会社です。Amazon.com は Amazon.com, Inc. の登録商標です。このメッセージは、Amazon Web Services, Inc., 410 Terry Ave.North, Seattle, WA 98109-5210 によって配信されています。
これでアカウントの解約は完了
上記メールにあるように、閉鎖後90日以内ならアカウントを再開できるとのこと
組織アカウントに参加させている場合、完全に閉鎖されたら組織からも除外しておく(もしくは自動的に除外されるか)