Memo

メモ > サーバ > サービス: AWS

■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/ AWSコスト削減とリソース管理 | 外道父の匠 https://blog.father.gedow.net/2023/08/24/aws-cost-saving/ ■無料利用枠 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の特徴とCentOSとの違い まとめ http://dev.classmethod.jp/cloud/aws/amazon-linux-centos-rhel-difference/ 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 Linux 2 はRHEL7ベースなので、CentOS7の知識が役に立つ Amazon Linux2とAmazon Linuxの違いについて(メモ) - Qiita https://qiita.com/akira345/items/2a09c4d06d2e3415bc8d 新世代の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 を使うといい(2022年時点) 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 へのアップグレードを計画しよう | Developers.IO https://dev.classmethod.jp/articles/planning-al-to-al2/ Amazon Linux 2 での LAMP のインストール - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html Amazon Linux 2(AWS)の初期設定 - あおぶる https://aoilo.blue/amazon-linux-2/ ■Amazon Linux 2023 Amazon Linux 2023 が正式にリリースされた Fedoraベースで、デフォルトでSELinuxが有効になっているとのこと AWSが提供する第3世代のOS、Amazon Linux 2023の機能や特徴を解説|サービス|法人のお客さま|NTT東日本 https://business.ntt-east.co.jp/content/cloudsolution/ih_column-31.html 検証用 Amazon Linux 2023 初期設定メモ(2023/05/08 版) | らくがきちょう v3 https://sig9.org/archives/5061 Amazon Linux 2023 の初期設定が Amazon Linux 2 と違いすぎて戸惑ったので、その内容と対処方法のまとめ - Qiita https://qiita.com/t-kigi/items/36012331ba67e6995b23 Amazon Linux 2023 での LAMP のインストール - Amazon Elastic Compute Cloud https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2023.html 以下は安定版(General Availability版)がリリースされたときの記事 予定が遅れたので、「Amazon Linux 2022」ではなく「Amazon Linux 2023」という名前でリリースされた Amazon Linux 2023がGAされました | DevelopersIO https://dev.classmethod.jp/articles/amazon-linux-2023-ga/ 以下は「Amazon Linux 2022」として紹介されていたときの記事 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/ ■セキュリティ クラウドセキュリティ | AWS https://aws.amazon.com/jp/security/ セキュリティ、アイデンティティ、およびコンプライアンス製品 - アマゾン ウェブ サービス (AWS) https://aws.amazon.com/jp/products/security/ 責任共有モデル | AWS https://aws.amazon.com/jp/compliance/shared-responsibility-model/ 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/ ■第三者認証 AWS クラウドコンプライアンス https://aws.amazon.com/jp/compliance/ AWSセキュリティ編 今回は第三者認証について詳しくご紹介します。 https://recipe.kc-cloud.jp/archives/5135 ■サポート 技術的なお問い合わせに関するガイドライン 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円程度かかることになる(加入月は日割によって若干価格が下がる) 対応時間は「平日9時〜18時」なので、金曜日の17時に問い合わせたら回答は火曜日の11時以降となる 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】アカウント契約の準拠法をワシントン州法から日本法に、管轄裁判所をワシントン州キング群州裁判所から東京裁判所に変更する方法 - 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 ■ロゴ Webページ掲載用のロゴが以下にある AWS 共同マーケティングツール | AWS https://aws.amazon.com/jp/co-marketing/ 商標ガイドラインとライセンス条項が以下にある 「Powered by AWS ロゴのフォーマット要件」部分に、ロゴを掲載する際の注意点などが書かれている AWS 商標使用ガイドライン https://aws.amazon.com/jp/trademark-guidelines/ 以下にSVGデータがある 印刷データなどに利用できるかもしれない 作者に「Amazon.com Inc.」とあるので公式なデータだと思われる が、「ライセンス」の項目には注意点が書かれているものの、使用ガイドラインへのリンクなどが無いのは気になる ファイル:Amazon Web Services Logo.svg - Wikipedia https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB:Amazon_Web_Services_Logo.svg 上記ページの「ファイルの使用状況」によると、以下のページから参照されている Amazon Web Services - Wikipedia https://ja.wikipedia.org/wiki/Amazon_Web_Services APNに参加すれば、専用ページからロゴをダウンロードできるとある また詳細を確認しておきたい AWSのLOGOの使用条件やダウンロードの方法、ロゴのガイドライン | ポテパンスタイル https://style.potepan.com/articles/34690.html ■素材 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ユーザの作成(より操作が限定されたユーザを作る場合の例1) S3のみ操作できるユーザを作成してみる 画面右上のアカウント名 → セキュリティ認証情報 → ユーザー → ユーザーを追加 ユーザー名: s3-user アクセスの種類: AWS マネジメントコンソールへのアクセス コンソールのパスワード: (案件に合わせて選択) パスワードのリセットが必要: (案件に合わせて選択) 「次のステップ: アクセス権限」をクリック 既存のポリシーを直接アタッチ → AmazonS3FullAccess にチェックを入れて「次のステップ: タグ」をクリック 次の画面で必要に応じてタグを設定して「次のステップ: 確認」をクリック(いったんタグは設定せずで大丈夫) 確認画面が表示されるので、内容を確認して「ユーザーの作成」をクリック 認証情報をCSVでダウンロードできるので、手元にダウンロードしておく。「閉じる」をクリックして完了 これでS3のみ操作できるアカウントとなる AWSコンソールにログインして確認すると、EC2やRDSなどメニューには表示されるが、 「取得中にエラーが発生しました」「取得に失敗しました」 などのエラーになる ■IAMユーザの作成(より操作が限定されたユーザを作る場合の例2) 特定のS3バケットのみ、プログラムから操作できるユーザを作成してみる バケットの名前は「example-develop」であるとする 画面右上のアカウント名 → セキュリティ認証情報 → ポリシー → ポリシーの作成 ポリシー名: ExampleDevelopS3Access 許可:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": [ "arn:aws:s3:::example-develop", "arn:aws:s3:::example-develop/*" ] } ] }
画面右上のアカウント名 → セキュリティ認証情報 → ユーザー → ユーザーを追加 ユーザー名: example-develop-app-user AWSマネジメントコンソールへのユーザーアクセス: 提供しない ポリシー: ExampleDevelopS3Access 以下のとおりアクセスキーを発行 ユースケース: コマンドラインインターフェイス (CLI) Access key ID: XXXXX Secret access key: YYYYY 発行したアクセスキーで、SDKから「ファイルのアップロード」「ファイルのダウンロード」ができることを確認する 【こんなときどうする?】特定のS3バケットにだけIAMからアクセスしたい | SunnyCloud https://www.sunnycloud.jp/column/20230107-01/ 特定のAmazon S3バケットにだけアクセスを許可する - JPCYBER https://www.jpcyber.com/support/create-iam-user-with-limited-s3-access ■IAMユーザの作成(請求を確認できるユーザを作成する) デフォルトではIAMユーザから請求情報を確認できない ただし「経理の人に請求だけは直接確認してもらいたい」のような場合に、ルートユーザを渡すのは避けたい これには、以下の手順で対応できる ルートユーザでAWSコンソールにログイン 画面右上のメニューから「アカウント」に遷移 遷移先の画面下部に「IAM ユーザーおよびロールによる請求情報へのアクセス」の項目がある デフォルトでは「無効化済み」となっているので、編集ボタンからアクティブ化する ポリシー「AWSBillingReadOnlyAccess」が付与されると、請求情報にアクセスできるようになる ここではIAMユーザ「billing-user」を新規に作成し、上記のポリシーをアタッチする (ポリシー「AdministratorAccess」が付与されたユーザも、請求情報にアクセスできるようになる) IAMユーザ「billing-user」でAWSコンソールにアクセスすると、請求情報を確認できる 他の操作は許可されていないことも確認する [小ネタ]AWSアカウントの請求情報をIAMユーザに見せる方法 | DevelopersIO https://dev.classmethod.jp/articles/show-your-aws-billing-info-to-iam-users/ 【AWS】IAMユーザからアカウントの請求内容を見れるようにする | chibinet https://chibinfra-techblog.com/aws-billing-iam-setup/ 【AWS】IAMユーザーから請求情報にアクセスする方法 #AWS - Qiita https://qiita.com/ponponpoko/items/19c077d3133ff8922007 ■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などと組み合わせる前提となるか [神アップデート]GuardDutyがEC2やECSのマルウェア検知時のスキャンに対応したので実際にスキャンさせてみた #reinforce | DevelopersIO https://dev.classmethod.jp/articles/guardduty-support-malware-protection/ マルウェアの検知に対応したらしい また改めて確認したい ■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
■IAM
※AWSのサービスやリソースにアクセスできるユーザーやグループを指定し、アクセス許可を一元管理する AWS IAM(ユーザーアクセスと暗号化キーの管理)| AWS https://aws.amazon.com/jp/iam/ AWS IAMとは?初心者でもわかるざっくり解説 | フューチャーウェブ https://www.future.ad.jp/futuremedia/20231109/ AWS IAMによる権限設定のメリットと設定方法|コラム|クラウドソリューション|サービス|法人のお客さま|NTT東日本 https://business.ntt-east.co.jp/content/cloudsolution/column-24.html 以下の違いについて把握しておく ・Root User ... 最初に登録したユーザ。AWSリソースに対して全権限を持つ ・IAM User ... Root Userによって作成された個別のユーザ。一般に、このユーザで運用・開発を行なう ・IAM Group ... IAM Userの集まり。複数のIAM Userに同じ権限を付与できる ・IAM Policy ... AWSリソースの操作権限、アクセス許可権を表したもの。IAM Userなどに割り当てて使用する ・IAM Role ... AWSリソースに権限を付与するもの。IAMユーザには割り当てられない ■Roleについて 「IAMロールはAWSリソースにつけるもので、IAMユーザにはアタッチできない」もの AWSのIAM Roleについて整理してみた #AWS - Qiita https://qiita.com/NMRchan/items/7d5adc44bed2b53f0347 IAMユーザにIAMロールをアタッチする話 #AWS - Qiita https://qiita.com/yukitsuboi/items/bf033c9d321dccdeedd4 ■AssumeRoleについて 「AssumeRoleはRoleArnを入力するとCredentialsを返すAPI」らしい 引き続き確認したい IAMロール徹底理解 〜 AssumeRoleの正体 | DevelopersIO https://dev.classmethod.jp/articles/iam-role-and-assumerole/ AssumeRole について DiveDeep する - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/assume-role-divedeep 一時的なセキュリティ認証情報のリクエスト - AWS Identity and Access Management https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumero... 特定の IAM ロールのみアクセスできる S3 バケットを実装する際に検討したあれこれ | DevelopersIO https://dev.classmethod.jp/articles/s3-bucket-acces-to-a-specific-role/ AssumeRoleの使用例として、後述の「S3バケットに他AWSアカウントからのアクセスを許可」がある
■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が必要な場合) ※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 ■amazon-linux-extrasについて 詳細は、後述の「amazon-linux-extras」を参照 ■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 … 任意の名前。仮で設定するならホスト名と同じにしておくなど
# systemctl start httpd # systemctl enable httpd # 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」に変更した) 以下の確認が表示される 内容を確認して「はい」を選択する
ボリューム vol-097ea05fd6c2462fd を変更してもよろしいですか? パフォーマンスの変更が完全に反映されるまでに時間がかかることがあります。 新しく割り当てられた領域を使用するには、ボリュームで OS ファイルシステムを拡張することが必要になる場合があります。 Linux および Windows での EBS ボリュームのサイズ変更について詳細を参照してください。 https://docs.aws.amazon.com/console/ec2/ebs/volumes/resizing-linux https://docs.aws.amazon.com/console/ec2/ebs/volumes/resizing-windows
ボリューム一覧ですぐに変更を確認できた ボリュームの状態は「使用中 - 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 スナップショットからの復元は以下が参考になる 「パターン2:スナップショットからAMIを作成し、インスタンスを起動させる」の方法が容易に対応できそうではある EC2のスナップショットからインスタンスを復元する方法2パターン | ソフトウェア開発のギークフィード https://www.geekfeed.co.jp/geekblog/restore-from-ec2-snapshot/ ■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ではインスタンスを「停止 → 起動」とすると物理的に別の領域にインスタンスが立ち上がる(再起動では同じ領域が使われる) つまり「停止 → 起動」で計画停止を回避できて、「再起動」では回避できない
■amazon-linux-extras
amazon-linux-extrasは、Amazon Linux 2上で利用できるパッケージ管理ツール 「エクストラリポジトリ」や「Extrasリポジトリ」のように呼ばれることもある よくある質問 - Amazon Linux 2 | AWS https://aws.amazon.com/jp/amazon-linux-2/faqs/ amazon-linux-extras コマンドに続けてオプションを指定して実行することにより、パッケージのインストールなどを行える ■list amazon-linux-extras コマンドで install オプションを使用すると、利用可能なソフトウェアパッケージを一覧表示できる 一覧の内容を絞り込みたい場合、grepを使うといい
$ amazon-linux-extras list $ amazon-linux-extras list | grep postgresql
■install amazon-linux-extras コマンドで install オプションを使用すると、指定したソフトウェアパッケージをインストールできる これにより、そのパッケージはシステムで直ちに使用できるようになる
# amazon-linux-extras install postgresql10
■enable amazon-linux-extras コマンドで enable オプションを使用すると、指定したソフトウェアパッケージが有効になる install オプションとは異なり、有効になるだけでインストールはされない ただし、パッケージのリポジトリがシステムのパッケージマネージャー(通常は「yum」)で利用できるようになる ユーザーがそのパッケージを手動で、または別の依存関係と一緒にインストールする際に使える
# amazon-linux-extras enable postgresql10 # yum install postgresql10
■disable amazon-linux-extras コマンドで disable オプションを使用すると、指定したソフトウェアパッケージが無効になる セキュリティ上の理由で、リポジトリへのアクセスを制限したい場合などに使える 無効化されたリポジトリからパッケージをインストールすることはできなくなるが、すでにインストールされているパッケージは影響を受けない (つまり、インストール済みのパッケージは引き続き利用できる)
# amazon-linux-extras disable postgresql10
■remove(amazon-linux-extrasには無い) amazon-linux-extras コマンドでインストールしたパッケージを削除する場合、 システムのパッケージマネージャー(通常は「yum」)を使用する もし将来そのパッケージを再インストールする予定がなく、関連するリポジトリも不要な場合、 amazon-linux-extras コマンドの disable オプションを使用して関連するリポジトリを無効にしておくといい(必須ではない)
# yum remove postgresql10 # amazon-linux-extras disable postgresql10
■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コンピューティングリソースに接続しない ネットワークタイプ: IPv4 Virtual Private Cloud: (あらかじめ作成したものを選択) DBサブネットグループ: (あらかじめ作成したものを選択) パブリックアクセス: なし VPCセキュリティグループ (ファイアウォール): (「default」と、データベース用に作成したセキュリティグループを割り当てる) アベイラビリティーゾーン: 指定なし 最初のデータベース名: (作成したいデータベース名を入力) DBパラメータグループ: (上で作成したものを選択) オプショングループ: default:mariadb-10-6 ※「ストレージタイプ」は、マルチ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 RDS作成時に「コンピューティングリソース」で「EC2コンピューティングリソースに接続」を選択し、一例だが以下のように設定する ただしこれまでどおり「EC2コンピューティングリソースに接続しない」として、自身で作成したセキュリティグループ単位で設定する…でいい気はする EC2インスタンス: (接続を許可したいEC2インスタンス。このEC2に自動作成されたセキュリティグループが追加されるらしい) Virtual Private Cloud: (選択済みで変更できなくなっていた) DBサブネットグループ: 既存の選択 既存のDBサブネットグループ: (あらかじめ作成したものを選択) パブリックアクセス: なし VPCセキュリティグループ (ファイアウォール): default ※「Amazon RDS は、コンピューティングリソースとの接続を許可 する新しい VPC セキュリティグループ rds-ec2-1 を追加します。」と表示されている ■データベースの文字コードを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)
コマンドで確認すると変更されている ■マルチAZにしたときのRDSの挙動 マルチAZにしておくことで、ダウンタイムを短くすることができる RDS起動後にマルチAZに変更する場合の解説は、後述の「RDSをシングルAZからマルチAZに変更」を参照 マルチAZか否かによっての停止時間の差は、後述の「RDSのインスタンスタイプを変更」を参照 【5分でわかる】スペックアップ&メンテナンス時のRDSの動作 - ナレコムAWSレシピ | AIに強い情報サイト https://recipe.kc-cloud.jp/archives/10806 ■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のストレージサイズを変更 以下は古い記事だが、「インスタンスがリブートし」と書かれている。 [AWS] RDSのストレージ容量を増やす - AWS講座 - [SMART] https://rfs.jp/server/aws/aws-rds_strage.html 以下は比較的最近の記事で、「RDSのストレージ追加にはダウンタイムは発生しません」と書かれている。 ただし「ほとんどの場合」とも書かれているので、念のためメンテナンスをスケジュール化して告知したい。 RDSストレージ追加する際に確認しておきたいこと|スクショはつらいよ https://chariosan.com/2020/09/20/rds_storage_add/ 自動スケーリングは停止時間が発生しないようなので、また検討しておきたい。 【DBのディスクサイズ管理が簡単に】RDSのストレージがストレージの自動スケーリングをサポートしました! | DevelopersIO https://dev.classmethod.jp/articles/rds-storage-auto-scaling/ 以下、実際にストレージサイズを変更したときのメモ RDSのスペックはdb.t2.micro 設定タブで「ストレージ」は「5GiB」となっている モニタリングによると、「4.7GB」の空きがある 「変更」で「ストレージ割り当て」を「5」から「6」に変更してみる PHPから数秒おきにRDSへ接続させていたが、ダウンタイムは確認できなかった 詳細は以下のとおり 11:40 インスタンスを変更 11:40 ステータスが「変更中」になった 11:44 ステータスが「Storage-optimization」になった。設定タブで「ストレージ」は「6GiB」になった 11:51 モニタリングでは「5.8GB」の空きがあるとなった(段階を経て拡張された) 11:59 ステータスが「利用可能」になった RDSのスペックはdb.t2.small 設定タブで「ストレージ」は「5GiB」となっている モニタリングによると、「890MB」の空きがある 「変更」で「ストレージ割り当て」を「5」から「20」に変更してみる ときどき画面をリロードしての確認では、ダウンタイムは確認できなかった。Cron実行エラーのメールも届いていない 詳細は以下のとおり 17:04 インスタンスを変更 17:04 ステータスが「変更中」になった 17:11 設定タブで「ストレージ」が「20GiB」になった 17:13 ステータスが「Storage-optimization」になった 17:22 モニタリングでは「16GB」の空きがあるとなった(段階を経て拡張された) 17:29 ステータスが「利用可能」になった ■RDSの再起動 RDSの再起動を行ったときのメモ スペックは db.t2.micro でマルチAZなし RDS → データベース → staging の画面で「アクション → 再起動」を実行する データが少ないからか、マルチAZでは無いのに1分ほどで完了した 詳細は以下のとおり 10:54 変更 10:54 ステータスが「再起動中」になり、データベースに接続できなくなった(「システムエラーが発生しました。」の表示になった) 10:55 ステータスが「利用可能」になり、データベースに接続できるようになった スペックは db.t2.small でマルチAZあり RDS → データベース → production の画面で「アクション → 再起動」を実行する 確認画面の「フェイルオーバーで再起動しますか?」にはチェックを付けなかった 再起動は30秒ほどで完了した 詳細は以下のとおり 11:02 変更 11:02 ステータスが「再起動中」になり、データベースに接続できなくなった(「システムエラーが発生しました。」の表示になった) 11:03 ステータスが「利用可能」になり、データベースに接続できるようになった マルチAZでの、フェイルオーバーについては以下に解説がある DB インスタンスの再起動 - Amazon Relational Database Service https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_RebootInstance.html > DB インスタンスのフェイルオーバーを強制的に実行すると、Amazon RDS によって別のアベイラビリティーゾーン内のスタンバイレプリカに自動的に切り替わり、スタンバイ DB インスタンスを参照するように DB インスタンスの DNS レコードが更新されます。 > したがって、DB インスタンスへの既存の接続のクリーンアップと再確立が必要になります。 > フェイルオーバーによる再起動が便利なのは、テスト用の DB インスタンスで障害をシミュレートするときや、フェイルオーバーの実行後にオペレーションを元の AZ に復元するときです。 メモリの回復を目的とした再起動なら、フェイルオーバーは不要そう 必要に応じて判断する ■RDSのマスターパスワードを変更 「RDS」→「インスタンス」→ 対象のインスタンスを選択 →「変更」 「新しいマスターパスワード」に設定したいパスワードを入力し、「次へ」ボタンを押す 内容を確認し、「変更のスケジュール」にある「すぐに適用」にチェックを入れて「DBインスタンスの変更」ボタンを押す ■Blue/Greenデプロイ データベースに対して、マイグレーションに丸2日かかるような変更を行う場合、メンテナンス期間を設けるのも難しい この場合、Blue/Greenデプロイを使えば1分ほどのダウンタイムで変更を行うことができる(準備には本来の時間がかかる) 【衝撃】AWSのRDSがデータを失わないBlue/Greenデプロイに対応しました #reinvent | DevelopersIO https://dev.classmethod.jp/articles/rds-bg-deploy/ Amazon RDS Blue/Green Deployments を色々と検証してみた! https://zenn.dev/stafes_blog/articles/117a003fa9a1ca RDS Blue/Green Deployments を使ってシュッと utf8mb4 にマイグレーションした話 - カミナシ エンジニアブログ https://kaminashi-developer.hatenablog.jp/entry/2023/07/03/migration-to-utf8mb4-with-rds-blue-green-... Amazon RDS ブルー/グリーンデプロイを利用してMySQLのアップグレードをした話 - Pepabo Tech Portal https://tech.pepabo.com/2024/05/10/rds-blue-green-deployment/ ■バックアップの概要 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のマイナーバージョンアップ = 後方互換あり バージョンアップの自動適用 = ダウンタイムが発生する となっている 意図しないダウンタイムを避けるためにも、本番環境では手動適用の方が良さそう ■メジャーバージョンアップグレード(MariaDB) 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/
■メジャーバージョンアップグレード(MariaDB / 失敗した手順) 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)
前述のとおり、パラメータグループを作り直す必要がある。 ■メジャーバージョンアップグレード(MySQL) MySQL5.7をMySQL8.0にバージョンアップしたときのメモ 基本的にはMariaDBと同じ手順で、MySQL8.0用のパラメータグループを作成して割り当てる必要がある 参考までに、MySQL6と7が飛ばされている理由は以下に記載されている What happened to MySQL 6 & 7? - Database Administrators Stack Exchange https://dba.stackexchange.com/questions/207506/what-happened-to-mysql-6-7 以下、実際に作業した時のメモ まずは準備から 以下の内容でパラメータグループを作成する パラメータグループファミリー: mysql5.7 グループ名: test-mysql5 説明: Parameter group for test-mysql 以下の内容でパラメータグループを設定する 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を作成する エンジンのオプション: MySQL エンジンバージョン: MySQL 5.7.44 テンプレート: 本番稼働用 可用性と耐久性: マルチAZ DBインスタンス DBインスタンス識別子: test-mysql マスターユーザの名前: rdsmaster マスターパスワード: abcd1234 DBインスタンスのクラス: db.t3.micro ストレージタイプ: 汎用SSD(gp3) ストレージ割り当て: 20 コンピューティングリソース: EC2コンピューティングリソースに接続しない ネットワークタイプ: IPv4 Virtual Private Cloud: Default VPC DBサブネットグループ: default パブリックアクセス: なし VPCセキュリティグループ (ファイアウォール): default 最初のデータベース名: test DBパラメータグループ: test-mysql5 オプショングループ: default:mysql-5-7 バックアップ保持期間: 1 以下の内容で接続ユーザを作成する
# mysql -h test-mysql.xxxxx.ap-northeast-1.rds.amazonaws.com -u rdsmaster -p > GRANT ALL PRIVILEGES ON test.* TO webmaster IDENTIFIED BY 'abcd1234'; # mysql -h test-mysql.xxxxx.ap-northeast-1.rds.amazonaws.com -u webmaster -p
テストデータを登録する
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('テストメッセージ1'); INSERT INTO table_test(text) VALUES('テストメッセージ2'); SELECT * FROM table_test;
ひとまず、terraport_testのEC2から接続を試みる (必要になれば新規にEC2を起動する)
# vi mysql.php
<?php try { $pdo = new PDO( 'mysql:dbname=test;host=test-mysql.xxxxx.ap-northeast-1.rds.amazonaws.com', 'webmaster', 'abcd1234' ); $stmt = $pdo->query('SET NAMES UTF8;'); $stmt = $pdo->query('SELECT VERSION() AS version;'); $data = $stmt->fetch(PDO::FETCH_ASSOC); echo 'version: ' . $data['version'] . "\n"; $stmt = $pdo->query('SELECT NOW() AS now;'); $data = $stmt->fetch(PDO::FETCH_ASSOC); echo 'now: ' . $data['now'] . "\n"; $stmt = $pdo->query('SELECT * FROM table_test WHERE id = 1;'); $data = $stmt->fetch(PDO::FETCH_ASSOC); echo 'text: ' . $data['text'] . "\n"; $pdo = null; } catch (PDOException $e) { exit($e->getMessage()); }
以下のとおり実行し、各値を取得できることを確認
$ php mysql.php version: 5.7.44 now: 2023-12-12 14:39:21 text: テストメッセージ1
ここまで準備 ここからバージョンアップ 以下の内容でパラメータグループを作成する パラメータグループファミリー: mysql8.0 グループ名: test-mysql8 説明: Parameter group for test-mysql 以下の内容でパラメータグループを設定する 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; ※MySQL5.7とMySQL8.0の両方で、パラメータグループの「sql_mode」はデフォルトで「NO_ENGINE_SUBSTITUTION」となっている ※MySQL5.7では、パラメータグループの「default_authentication_plugin」はデフォルトで「-」となっている MySQL8.0では、パラメータグループの「default_authentication_plugin」は「mysql_native_password」となっている エンジンバージョンを変更する 対象RDSの「編集」画面で以下のとおり設定を変更する DBエンジンバージョン: 5.7.44 → 8.0.35 DBパラメータグループ: test-mysql8 ※「DBエンジンバージョン」を変更すると、「DBパラメータグループ」が「default.mysql8.0」に変更された また、「オプショングループ」が「default.mysql8.0」に変更された 「DBパラメータグループ」を、上で作成した「test-mysql8」に変更する そのまま「続行」ボタンを押すと、変更内容の確認画面になる 「すぐに適用」にして「DBインスタンスを変更」ボタンを押す 14:50 変更を実行。ステータスが「アップグレード」になった 14:52 トップページで「SQLSTATE[HY000] [2003] Can't connect to MySQL server on 'test-mysql.xxxxx.ap-northeast-1.rds.amazonaws.com' (111)」のエラーが表示されるようになった 14:55 トップページが表示されるようになった 14:58 ステータスが「Configuring-enhanced-monitoring」になった。サイトにはアクセスできている 15:00 ステータスが「変更中」になった。サイトにはアクセスできている 15:02 ステータスが「利用可能」になった テストプログラムを実行して、各値を取得できることを確認
$ php mysql.php version: 8.0.35 now: 2023-12-12 15:02:20 text: テストメッセージ1
■メジャーバージョンアップグレード(MySQL / 失敗した手順) 対象RDSの「編集」画面で以下のとおり設定を変更する DBエンジンバージョン: 5.7.44 → 8.0.35 この時点で「DBパラメータグループ」と「オプショングループ」の設定がグレーアウトされた そのまま「続行」ボタンを押すと、変更内容の確認画面になる 「DBインスタンスを変更」ボタンを押すと、以下のエラーが表示された
申し訳ありません。DB インスタンス test-mysql の変更のリクエストが失敗しました。 Current Parameter Group (test-mysql) is non-default. You need to explicitly specify a new Parameter Group in this case (default or custom)
MariaDBのときと同じく、MySQL8.0用のパラメータグループを作成しておく必要があるのだと思われる ■RDSのメモリ 空きメモリ(FreeableMemory)がどんどん減少するので調査したときのメモ(2GBのメモリだが、空き容量が200MBくらいまで下がった) RDSの挙動としては ・パラメータ「innodb_buffer_pool_size」によって定められた値までメモリの割り当てを行う ・デフォルトで「{DBInstanceClassMemory*3/4}」となっており、この値を変更することは推奨されない ・RDSがsmallの場合、メモリ容量2GBのうち3/4である1.5GB程度は、InnoDBのバッファプールがメモリを使用することが想定された挙動となる ・RDSインスタンスの再起動により、FreeableMemoryの値が回復する可能性はあるが、運用していると同じ水準まで下がると思われる となっているらしい 今回はRDSを再起動することで、空きメモリは1GBくらいまで増えた その後徐々に下がっていったが、440MBくらいで下がるのが止まった。これなら想定の範囲内と言えそう さらい下がるようなら、RDSのスペックアップが必要なのかもしれない ■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認証の動作を確認する ■Basic認証(特定のユーザーエージェントなら素通りさせる) 「ChromiumからのアクセスならBasic認証を素通り」とする方法 「HTTPS:80」「HTTPS:443」の両方に対して、以下のルールを追加する(「HTTPS:443」だけでもいいかもしれない) なお既存のルールを編集して追加すると「AおよびB」という設定になり、両方のルールを満たす必要があるので注意。 ・ルールで「HTTPヘッダー」「User-Agent」「*HeadlessChrome*」を設定 ・ターゲットグループで「Refirio-Staging-ALB-TargetGroup に転送」を設定 ・優先度で「3」を設定(状況に合わせて設定する) 外部のサーバから、以下のリクエストを送ってアクセスできることを確認できる
$ curl -H "User-Agent: HeadlessChrome" https://test.refirio.net/
■ヘルスチェックのログ 初期設定では、ヘルスチェックのログが大量に記録される 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 $loggable { ~ELB-HealthChecker 0; default 1; } access_log /var/log/nginx/access.log main if=$loggable; 〜 略 〜 }
Nginx で ELB のヘルスチェックのログを出力させない - 長生村本郷Engineers'Blog https://kenzo0107.github.io/2021/05/19/2021-05-20-nginx-no-logging-at-elb-healthcheck/ NginxでAWS ELBのHealth Checkログを出力させない方法 - Qiita https://qiita.com/homoluctus/items/7f81ef8e7d23f3c18ffe NginxのアクセスログからELBのヘルスチェックを除外する方法 - Qiita https://qiita.com/masa1246/items/a79051a280ee2a6734c4 ■アクセスログの有効化 ロードバランサーへのアクセスログを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への導入は注意が必要みたい) 後にEC2に導入できるようになったが、「CPUが4vCPU以上」などの利用条件がある ・ドメイン認証(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 ■EC2への導入 ※未検証 ACMのSSL証明書(Amazonの無料証明書)をEC2(Apache)で利用してみた - DENET 技術ブログ https://blog.denet.co.jp/acm-ssl-apache/ ACMの証明書をEC2で利用可能になりました - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/2020/10/30/083000 比較的最近のアップデートで、ACMで発行したSSL証明書を、EC2のApacheに組み込めるようになっているらしい Nginxでは以前から対応できていたらしい …と思ったが、利用条件に「CPUが4vCPU以上」とある。 ACMのSSL証明書(Amazonの無料証明書)をEC2(Apache)で利用してみた - DENET 技術ブログ https://blog.denet.co.jp/acm-ssl-apache/ 4vCPUなのは「t3.xlarge」以上なので、t3.microやt3.smallには使えない 「ロードバランサーも不要な開発環境にちょっと使う」という用途では難しそう インスタンスタイプ - Amazon EC2 | AWS https://aws.amazon.com/jp/ec2/instance-types/ ■サイトシール サイトシールは発行されない 勝手にそれらしいものを作るのも禁止されている よくある質問 - 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/
■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サーバにアクセスできることを確認する 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/ ■フォルダの扱い Amazon S3における「フォルダ」という幻想をぶち壊し、その実体を明らかにする | DevelopersIO https://dev.classmethod.jp/articles/amazon-s3-folders/ > Amazon S3には実はフォルダという概念は無いのです。 > Amazon S3の基礎技術は、単純なKVS(Key-Value型データストア)でしかありません。 ■静的サイトホスティング ※未検証 S3に静的ページを配置し、それをWebサイトとして表示させることができる ただしPHPなど動的ページに対応させることはできない 対象バケットの「プロパティ → 静的ウェブサイトホスティング」から設定できそう Amazon S3 を使用して静的ウェブサイトをホスティングする - Amazon Simple Storage Service https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/WebsiteHosting.html > Amazon S3 はサーバーサイドスクリプトをサポートしていませんが、 > AWSには動的ウェブサイトをホストするための他のリソースがあります。 動的ページには対応していないので、別途EC2などを使用する必要がある CloudFrontとS3で作成する静的サイト構成の私的まとめ | DevelopersIO https://dev.classmethod.jp/articles/s3-cloudfront-static-site-design-patterns-2022/ ■バージョン管理 ※未検証 今さらだけどS3のバージョニングを試してみた。 https://qiita.com/kooohei/items/8775b380632e8b7940a3 ■セキュリティ ※未検証。2018年11月18日の記事 S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました | DevelopersIO https://dev.classmethod.jp/cloud/aws/s3-block-public-access/
■S3バケットに他AWSアカウントからのアクセスを許可
以下のAWSアカウントがあるとする account1(111111111111) account2(222222222222) このとき、account1アカウントが所持しているS3バケットを、account2アカウントから読み書きできるように設定する ■account1にて設定 ※外部AWSアカウント「222222222222」用に、S3を操作するためのロールを作成する ※ロールに割り当てる許可ポリシーは、検証なら「AmazonS3FullAccess」でもいいが、実案件ではできるだけ権限を絞るといい 以下の例では、特定バケットに限定して操作を許可している ポリシー ExternalExampleDevelopPolicy として以下を作成
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ … 許可したい操作を指定 "s3:ListBucket", "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": [ … 許可したいバケットを指定 "arn:aws:s3:::example-linkage-develop", "arn:aws:s3:::example-linkage-develop/*" ] } ] }
ロール ExternalExampleDevelopRole として以下を作成 信頼されたエンティティタイプ: AWSアカウント AWSアカウント: 別のAWSアカウント アカウントID: 222222222222 … 許可したいAWSアカウントを指定 オプション: 外部IDを要求する … 必須では無いが推奨されている 外部ID: Abcd1234 … 必須では無いが推奨されている 許可ポリシー: ExternalExampleDevelopPolicy … 上で作成したポリシーを指定 参考までに、作成後に ExternalExampleDevelopRole の「信頼関係」を確認すると、以下のJSONを確認できる 「Principal」の部分が、別のAWSアカウントを信頼するための指定 外部IDを指定しなかった場合、Conditionの部分は「"Condition": {}」となる
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::222222222222:root" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "sts:ExternalId": "Abcd1234" } } } ] }
■account2にて設定 ポリシー ExampleDevelopPolicy として以下を作成
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::111111111111:role/ExternalExampleDevelopRole" … 上で作成したロールの情報(アカウントIDとロール名)を指定する } ] }
ロール「ExampleDevelopRole」を作成し、上で作成した「ExampleDevelopPolicy」を割り当てる さらにEC2「Example-Develop-Web1(i-0e6194f055556b51b)」に対して、上で作成した「ExampleDevelopRole」を割り当てる 上で設定したEC2にSSHで接続し、以下のとおりコマンドを実行する(外部IDを指定しなかった場合、コマンドから「--external-id "Abcd1234"」部分は省く) AssumeRole に必要な認証情報(アクセスキー、シークレットキー、セッショントークン)が返される
$ aws sts assume-role --role-arn "arn:aws:iam::111111111111:role/ExternalExampleDevelopRole" --role-session-name "TestSession" --external-id "Abcd1234" … 上で作成したロールの情報(アカウントID、ロール名、外部ID)を指定する { "AssumedRoleUser": { "AssumedRoleId": "AROAXXXXXXXXXXXXX5CGE:TestSession", "Arn": "arn:aws:sts::111111111111:assumed-role/ExternalExampleDevelopRole/TestSession" }, "Credentials": { "SecretAccessKey": "G/u8iH7jXXXXXXXXXXXXXXXXXXXXXXXXzuYZ+BWH", "SessionToken": "FwoGZXIvYXdzEID//////////wEaDCa6rWxdIvTnBtc1MCKvAdsYLpWCFGwVeHNa3wY81UI8m4rhfWwqXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZjnF1Q0o/aCtsQYyLeltX4vBYejF6L6CbWk+nMrXkJ9Nv7DFb7W6vCOc59g9/Qj7tqRwWn2Tetopyg==", "Expiration": "2024-04-26T07:58:05Z", "AccessKeyId": "ASIAXXXXXXXXXXXX4C76" } }
上記内容をもとに、~/.aws/credentials に認証情報を設定する
$ mkdir ~/.aws $ vi ~/.aws/credentials
以下のとおり設定する
[cross-account] aws_access_key_id = ASIAXXXXXXXXXXXX4C76 … 取得したAccessKeyId aws_secret_access_key = G/u8iH7jXXXXXXXXXXXXXXXXXXXXXXXXzuYZ+BWH … 取得したSecretAccessKey aws_session_token = FwoGZXIvYXdzEID//////////wEaDCa6rWxdIvTnBtc1MCKvAdsYLpWCFGwVeHNa3wY81UI8m4rhfWwqXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZjnF1Q0o/aCtsQYyLeltX4vBYejF6L6CbWk+nMrXkJ9Nv7DFb7W6vCOc59g9/Qj7tqRwWn2Tetopyg== … 取得したSessionToken
以下のとおり接続する
$ export AWS_PROFILE=cross-account $ aws sts get-caller-identity --query 'Arn' | awk '{ print substr($1, index($1, "/")) }' | awk '{ sub("/", ""); sub("\"", ""); print }' ExternalExampleDevelopRole/TestSession
以下でS3の内容を参照できる
$ aws s3 ls example-linkage-develop $ aws s3 ls example-linkage-develop/images/
以降は以下で接続できる ただし、取得したセッショントークンの有効期限は1時間となっている(延長可能だが最大で12時間まで)
$ export AWS_PROFILE=cross-account $ aws s3 ls example-linkage-develop/images/
■PHPからの接続 以下のようにアクセスキー、シークレットキー、セッショントークンを指定することで、PHPからも接続できる ただし上記のとおり、この情報には有効期限がある(一定時間が経過すると「400 Bad Request」「ExpiredToken」「The provided token has expired.」のエラーになる)
<?php require_once 'vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; try { // アクセスキーとシークレットアクセスキーを指定して接続 $client = new S3Client([ 'credentials' => [ 'key' => 'ASIAXXXXXXXXXXXX4C76', 'secret' => 'G/u8iH7jXXXXXXXXXXXXXXXXXXXXXXXXzuYZ+BWH', 'token' => 'FwoGZXIvYXdzEID//////////wEaDCa6rWxdIvTnBtc1MCKvAdsYLpWCFGwVeHNa3wY81UI8m4rhfWwqXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXZjnF1Q0o/aCtsQYyLeltX4vBYejF6L6CbWk+nMrXkJ9Nv7DFb7W6vCOc59g9/Qj7tqRwWn2Tetopyg==', ], 'region' => 'ap-northeast-1', 'version' => 'latest', ]); // バケットとディレクトリを指定して取得 $result = $client->listObjects([ 'Bucket' => 'example-linkage-develop', 'Prefix' => 'images/', '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()); }
■PHPからの接続(改修版) 以下のようにすると、STSを使って都度認証情報を取得する。これにより、有効期限の問題を回避できる ただし「EC2インスタンスでプログラムを実行していて、そのインスタンスに適切なIAMロールが割り当てられている」必要がある
<?php require 'vendor/autoload.php'; use Aws\Sts\StsClient; use Aws\S3\S3Client; // STS Clientの初期化 $stsClient = new StsClient([ 'version' => 'latest', 'region' => 'ap-northeast-1', ]); try { // AssumeRole APIをコール $result = $stsClient->assumeRole([ 'RoleArn' => 'arn:aws:iam::111111111111:role/ExternalExampleDevelopRole', 'RoleSessionName' => 'TestSession', 'DurationSeconds' => 3600, // トークンの有効期限(秒) 'ExternalId' => 'Abcd1234', // 外部ID ]); // 取得した認証情報 $credentials = $result->get('Credentials'); // 認証情報を使って新しいクライアントを作成 $client = new S3Client([ 'version' => 'latest', 'region' => 'ap-northeast-1', 'credentials' => [ 'key' => $credentials['AccessKeyId'], 'secret' => $credentials['SecretAccessKey'], 'token' => $credentials['SessionToken'], ] ]); // バケットとディレクトリを指定して取得 $result = $client->listObjects([ 'Bucket' => 'example-linkage-develop', 'Prefix' => 'images/', 'Delimiter' => '/', ]); // ファイルを表示 foreach ($result['Contents'] as $content) { echo $content['Key'] . '(' . $content['LastModified'] . ')' . '<br>'; } } catch (Exception $e) { exit('Exception: ' . $e->getMessage()); }
■バケットポリシーの設定 ※ロールIDを変更しても変化なかったので、本当に設定できているかは改めて検証したい ただし最初に設定したポリシー ExternalExampleDevelopPolicy とロール ExternalExampleDevelopRole によってアクセス元を限定しているので、ここでの設定はあまり意味が無いような気はする 最後に、AWSアカウントaccount1にて、S3バケットexample-linkage-developに対して、バケットポリシーを設定する
$ export AWS_PROFILE=cross-account $ aws sts get-caller-identity { "Account": "111111111111", "UserId": "AROAXXXXXXXXXXXXX5CGE:TestSession", "Arn": "arn:aws:sts::111111111111:assumed-role/ExternalExampleDevelopRole/TestSession" } 「UserId」の値のうち、「:」より前がロールID、「:」より後ろがセッション名となっている この場合、以下のとおりバケットポリシーを設定する { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": "arn:aws:s3:::example-linkage-develop/*", "Condition": { "StringNotLike": { "aws:userId": [ "AROAXXXXXXXXXXXXX5CGE:*" … ロールIDを指定 ] } } } ] }
これで完了 特定の IAM ロールのみアクセスできる S3 バケットを実装する際に検討したあれこれ | DevelopersIO https://dev.classmethod.jp/articles/s3-bucket-acces-to-a-specific-role/#toc-7 ■メモ 受け入れ側でポリシーを変更すると、アクセスする側で再接続が必要みたい ただし「PHPからの接続(改修版)」の方法なら問題無いはず 以下は参考ページ AWSのIAM Roleについて整理してみた #AWS - Qiita https://qiita.com/NMRchan/items/7d5adc44bed2b53f0347 IAMユーザにIAMロールをアタッチする話 #AWS - Qiita https://qiita.com/yukitsuboi/items/bf033c9d321dccdeedd4 IAMロール徹底理解 〜 AssumeRoleの正体 | DevelopersIO https://dev.classmethod.jp/articles/iam-role-and-assumerole/ AssumeRole について DiveDeep する - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/assume-role-divedeep 一時的なセキュリティ認証情報のリクエスト - AWS Identity and Access Management https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumero...
■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 上記の記事を参考に として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にファイルを置くことで少し費用発生するが、プロビジョニング済みにするよりは費用は抑えられる」 のように紹介されている。やはり要検証 2024年5月に、スループットが高速になったという記事がある 改めて検証したい Amazon EFSのクライアント当たりの最大スループットが1.5GB/sに。これまでより3倍高速なファイルアクセスを実現 − Publickey https://www.publickey1.jp/blog/24/amazon_efs15gbs3.html ■EFSの作成 AWS → EFS → ファイルシステムの作成 ステップ 1: ファイルシステムアクセスの設定 作成済みのVPCを選択 作成済みのサブネットを選択(プライベートなサブネットを作成しておく必要があるかも) ステップ 2: オプション設定の構成 必要に応じてタグを追加 パフォーマンスは「汎用」のままでいい (「最大 I/O」は「数十、数百、または数千のEC2インスタンスがファイルシステムにアクセスするアプリケーション」を想定しているとある) スループットは「バースト」のままでいい (「プロビジョニング済み」にすると速度が向上するようだが、料金が跳ね上がる) ステップ 3: 確認と作成 内容を確認して作成する 作成するとファイルシステム一覧の画面に遷移する VPCの設定で「DNS解決の編集」と「DNSホスト名の編集」の両方が「はい」になっている必要がある 「はい」になっていなければその旨が案内されるので設定する ■EC2にマウント(AWSコンソールで設定する場合) ※未検証 EC2作成時に適切なVPCとサブネットを選択しておくと、 「ストレージを設定 → 0xファイルシステム → 編集 → 共有ファイルシステムを追加」 から、EFSとマウントポイントを指定できる マウントポイントは「/var/www/efs」のようなパスを指定できる(パスは一例) この場合、EC2内でマウントのための作業は不要 以下でマウントされているかを確認できる
# df -m
以下で自動マウントが設定されているかを確認できる
# cat /etc/fstab
マウントされていることが確認できたら、必要に応じてシステムに必要なディレクトリを手動作成する 所有者はパーミッションも適宜調整する
# cd /var/www/efs # mkdir xxx
もしマウントされていなければ、通常の手順でマウントを試みる エラーが出てマウントできない場合は、EFSとEC2のセキュリティグループ設定を確認する ■EC2にマウント(手動で設定する場合) ※特に理由が無ければ、AWSコンソールで設定する方が無難か 詳細は「EC2にマウント(AWSコンソールで設定する場合)」を参照 通常の手順で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などを考えなくても容易にファイル共有ができる 設定後、EC2を再起動して自動マウントを確認しておく ■サブディレクトリのマウント ※未検証 EFSのサブディレクトリにEC2をマウントさせる - Qiita https://qiita.com/hirai-11/items/8564791feed63a39ad2f EFSのサブディレクトリをマウントする - ハマログ https://blog.e2info.co.jp/2021/02/07/efs%E3%81%AE%E3%82%B5%E3%83%96%E3%83%87%E3%82%A3%E3%83%AC%E3%82... ■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/ 2022年に検証された記事が以下にある パフォーマンスは改善されているようだが、それでもEBSのような使い方は難しそう WordPressサイトのWebコンテンツ共有にAmazon EFSは使える? - TechHarmony https://blog.usize-tech.com/web-contents-share-on-amazon-efs/ ■参考 [速報] 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/ Amazon EFS を作成し EC2 からマウントしてみた | Wedding Park CREATORS Blog https://engineers.weddingpark.co.jp/amazon-efs/ Auto-Scalingが有効なEC2にEFSを自動マウントさせる https://zenn.dev/pero_nw/articles/5cb4e0ddd5ee56 以下のページで 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を割り当てなくても、インスタンスを停止させなければ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 RDS や ElastiCache にはEIPは不要 Amazon RDSにElastic-IPは紐づけられない(はず): ●○hinata_hisa○● http://drawing-hisa.seesaa.net/article/403402885.html ■料金 Elastic IP は、EC2に1つ割り当てている分には料金が発生しない 割り当てずに置いておいたり、割り当てたEC2を停止させていたり、1つのEC2に2つ以上割り当てたりすると料金が発生する …だったが、2024年2月からは、停止していても1時間あたり0.005ドルかかるようになるとのこと(日本円で月額500円ほど) 新着情報 - パブリック IPv4 アドレスの利用に対する新しい料金体系を発表 / Amazon VPC IP Address Manager が Public IP Insights の提供を開始 | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/new-aws-public-ipv4-address-charge-public-ip-insights/ AWS、IPv4アドレスの使用に課金、1時間当たり0.005ドル。2024年2月1日から − Publickey https://www.publickey1.jp/blog/23/awsipv410005202421.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レコードの内容。ただし最後のピリオド「.」は削除せずに登録する) 「レコードを作成」ボタンを押す ■外部のDNSからサブドメインの管理権限を委譲する ※やっていることは「別のAWSアカウントにサブドメインの管理権限を委譲する」と同じ refirio.net の表示はそのままに、dev.refirio.net の権限をAWSのRoute53に移譲する つまり refirio.net がムームードメインで管理されていても、dev.refirio.net に関してはAWS側の操作で内容を変更できる Route 53 → ホストゾーン → ホストゾーンの作成 から設定。 ドメイン名: dev.refirio.net タイプ: パブリックホストゾーン (変更せず) と入力して「ホストゾーンの作成」ボタンを押す NSレコードに以下の値が登録された。
ns-1234.awsdns-56.com ns-7890.awsdns-12.org ns-345.awsdns-67.net ns-8901.awsdns-23.co.uk
ムームードメイン側で dev.refirio.net に以下のとおり登録した(最後のピリオドは無しでいい。) サブドメイン 種別 内容 優先度 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - dev NS ns-1234.awsdns-56.com (空欄) dev NS ns-7890.awsdns-12.org (空欄) dev NS ns-345.awsdns-67.net (空欄) dev NS ns-8901.awsdns-23.co.uk (空欄) 少し待つと、以下のとおり反映された SOAレコードの値は、Route53にあるものが反映されている
$ dig dev.refirio.net any ;; ANSWER SECTION: dev.refirio.net. 300 IN SOA ns-1234.awsdns-56.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400 dev.refirio.net. 300 IN NS ns-1234.awsdns-56.com. dev.refirio.net. 300 IN NS ns-7890.awsdns-12.org. dev.refirio.net. 300 IN NS ns-8901.awsdns-23.co.uk. dev.refirio.net . 300 IN NS ns-345.awsdns-67.net. Route53で、dev.refirio.net のAレコードを 203.0.113.1 に向けてみる。 $ dig dev.refirio.net any ;; ANSWER SECTION: dev.refirio.net. 300 IN A 203.0.113.1 dev.refirio.net. 86400 IN NS ns-345.awsdns-67.net. dev.refirio.net. 86400 IN NS ns-1234.awsdns-56.com. dev.refirio.net. 86400 IN NS ns-7890.awsdns-12.org. dev.refirio.net. 86400 IN NS ns-8901.awsdns-23.co.uk. dev.refirio.net. 900 IN SOA ns-1234.awsdns-56.com. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400
DNSが反映されると、http://dev.refirio.net/ にアクセスしたとき http://203.0.113.1/ の内容が表示される つまり、サブドメインの管理移譲ができている サブドメイン権限移譲の手順は、以下の「サブドメインを作成したい既存ドメインの」以降も参考になりそう (登録すべき値は、もちろん解説とは異なる) ムームードメインでの設定例 - ワイメール 公式オンラインヘルプ https://www.y-ml.com/help/option-service/60-editable-ns-record/432-mu-mu-domain.html
■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
■Virtual Waiting Room
※未検証 ※仮想待合室(「〇人待っています」の仕組み)を用意し、アクセスの急激な増加に耐える Virtual Waiting Room on AWS | AWS ソリューション https://aws.amazon.com/jp/solutions/implementations/virtual-waiting-room-on-aws/ AWS Virtual Waiting Roomのご紹介 | Amazon Web Services ブログ https://aws.amazon.com/jp/blogs/news/introducing-aws-virtual-waiting-room/ 「AWS Virtual Waiting Room」のハンズオンをやってみた | NHN テコラス Tech Blog | AWS、機械学習、IoTなどの技術ブログ https://techblog.nhn-techorus.com/archives/26107 トラフィックの急増に耐えられるソリューション!? Virtual Waiting Room on AWS を試した - kakakakakku blog https://kakakakakku.hatenablog.com/entry/2024/01/25/185827
■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を使えるようになる 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 について最初から知りたかったこと8選 - ISID テックブログ https://tech.isid.co.jp/entry/8_things_i_wanted_to_know_about_aws_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がすごすぎる|ソニー|コラム|NURO Biz(ニューロ・ビズ) https://biz.nuro.jp/column/aws-mama-059/ 【初心者向け】Amazon Inspectorとは | SunnyCloud https://www.sunnycloud.jp/column/20230607-01/ Inspector → 使用を開始する 「Inspector をアクティブ化」の画面が表示される 「サービスの許可」として、以下の説明が表示されている 「Inspector をアクティブ化すると、ユーザーに代わって AWS の機密データを検出、分類、保護し、潜在的なセキュリティ上の問題に関する検出結果を生成するための許可を Inspector に付与することになります。これにより、Inspector はお客様のアカウントのためにのみアクティブ化されます。」 問題無ければ「Inspector をアクティブ化」ボタンをクリック 有効化に成功すると、画面に「Inspector へようこそ。最初のスキャンが進行中です。」と表示される (スキャン完了については表示されなかったが、最初のスキャンは2〜3分程度で完了したみたい) EC2、AMI、Lambda関数については、何も検出されなかった ECRリポジトリ、ECRコンテナイメージについては、それぞれ60件ほどの「緊急」が検出された(検証中のもの) ECRの「イメージの脆弱性スキャン」では対応しようが無いものが検出されることがあったが、今回同じようなものなのかは引き続き要調査 ■SSMエージェントを利用してスキャン Amazon Inspector (v2) を設定してみた - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/amazon-inspector-v2 Amazon Inspector v2でEC2インスタンスの脆弱性スキャンを実施する方法 | クラウド・AWSのIT技術者向けブログ SKYARCH BROADCASTING https://www.skyarch.net/blog/amazon-inspector-v2%E3%81%A7ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%... 以前(v1)はEC2に「エージェント」と呼ばれるものをインストールすることで、完全なスキャンができた 現在(v2)はAmazon Systems Manager (SSM) エージェントを使うことで対応できる Inspector → ダッシュボード 「環境カバレッジ」内の「インスタンス」を確認すると、「0%」「0/10インスタンス」と表示されている これは「リージョン内に10台のインスタンスがあり、スキャン対象は0台だった」ということ EC2がマネージドインスタンス化(ポリシー「AmazonSSMManagedInstanceCore」を与える)することでスキャン対象になるので、実際に行ってみる まずはロールを作成する セキュリティ認証情報 → ロール → ロールを作成 許可ポリシー: AmazonSSMManagedInstanceCore ロール名: AmazonSSMManagedInstanceCoreRole 対象のAmazon EC2に対して以下の操作を行う アクション → セキュリティ → IAMロールを変更 インスタンスID: 対象のインスタンスIDが表示されていることを確認 IAMロール: AmazonSSMManagedInstanceCoreRole 1時間ほど経ってから確認すると、ダッシュボードに「10%」「1/10インスタンス」という表示に変わった 左メニューから「検出結果 → インスタンス別」と辿ると、インスタンス別の検出結果を一覧できる (マネージドインスタンス化したものは、「オペレーティングシステム」にOS名が表示されていた) インスタンス名をクリックすると、検出内容の詳細を確認できる 左メニューから「検出結果 → 抑制ルール」と辿ると、不要な結果を非表示にできる (例えば「Medium以下のものについては表示しない」などができる) 「ルールを作成」をクリック 名前: exclude-medium 抑制ルールのフィルター: 重大性:Medium,Low 「このルールによって抑制された検出結果」に意図した内容が表示されていることを確認し、「保存」ボタンをクリックする これでインスタンスの検出内容の詳細を確認すると、設定した結果が除外されていることを確認できる (検出結果で非表示になるだけで、検出件数には反映されないみたい) ■スキャンのタイミング 任意のタイミングではなく、あらかじめ定められたタイミングでスキャンが行われる Amazon Inspector で Amazon EC2 インスタンスをスキャンする - Amazon Inspector https://docs.aws.amazon.com/ja_jp/inspector/latest/user/scanning-ec2.html > Amazon Inspector は 24 時間に 1 回、EC2 インスタンスのネットワーク到達可能性スキャンを実行します。 > アクティベーションを行うと、Amazon Inspector はアカウント内のすべての SSM 管理対象インスタンスをスキャンします。Amazon Inspector は、以下の状況で SSM 管理の EC2 インスタンスの新しい脆弱性スキャンを開始します。 > > ・新規 EC2 インスタンスを起動するとき。 > ・既存の EC2 インスタンス (Linux のみ) に新しいソフトウェアをインストールする場合。 > ・Amazon Inspector が新しい共通脆弱性と危険性 (CVE) 項目をデータベースに追加し、その CVE がお客様の EC2 インスタンス (Linux のみ) に関連している場合。 Amazon Inspector v2でEC2インスタンスの脆弱性スキャンを実施する方法 | クラウド・AWSのIT技術者向けブログ SKYARCH BROADCASTING https://www.skyarch.net/blog/amazon-inspector-v2%E3%81%A7ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%... > Inspector v2では、次のタイミングでスキャンが行われます。 > > ・EC2 インスタンスが Amazon Inspector によって検出されると即時 > ・新しいインスタンスを開始した際 > ・既存のインスタンスに新しいソフトウェアがインストールされた場合 > ・Amazon Inspector がデータベースに新しい一般的な脆弱性および例外 (CVE) 項目を追加したとき > > 「新しいソフトウェアをインストールする場合」ですが、yumやaptを利用したパッケージインストールが対象となります。 > makeは対象外のようですのでご注意ください。 > 毎日自動的にスキャンを走らせるなどの対応はできませんが、コスト的にも優れ、コントロールパネルもかなり見やすくなっており、非常に有用なサービスと感じました。 ■通知 Amazon Inspectorの通知を受け取る https://staff-blog.faith-sol-tech.com/amazon-inspector%E3%81%AE%E9%80%9A%E7%9F%A5%E3%82%92%E5%8F%97%... Amazon EventBridge → ルール → ルールの作成 以下の内容でルールを作成する ルールの詳細を定義 名前: AmazonInspectorNotificationRule ルールタイプ: イベントパターンを持つルール イベントパターンを構築 イベントソース: AWSイベントまたはEventBridgeパートナーイベント メソッド: パターンフォームを使用する イベントパターン イベントソース: AWSのサービス AWS のサービス: Inspector2 イベントタイプ: Inspector2 Finding ターゲットを選択 ターゲットタイプ: AWSのサービス ターゲットを選択: SNSトピック トピック: (あらかじめ作成しておいたSNSトピック) 上記設定だと、頻繁に何十通もの通知メールが届く 意図してポートを空けているような場合、これが毎回通知される 通知対象を制限したい場合、引き続き以下の設定を行う Amazon EventBridge → ルール → AmazonInspectorNotificationRule → イベントパターン → 編集 イベントパターンを以下のように編集した(detailの項目を追加した)
{ "source": ["aws.inspector2"], "detail-type": ["Inspector2 Finding"] } ↓ { "source": ["aws.inspector2"], "detail-type": ["Inspector2 Finding"], "detail": { "severity": ["HIGH", "CRITICAL"], "status": ["ACTIVE"] } }
これで重要度の低いものは通知されなくなる
■GuardDuty
GuardDutyの有効化は、このファイル内の「AWSの初期設定」を参照 以降では、後から機能追加されたマルウェア対策について確認する ■設定 いったん以下を参考に試してみる [神アップデート]GuardDutyがEC2やECSのマルウェア検知時のスキャンに対応したので実際にスキャンさせてみた #reinforce | DevelopersIO https://dev.classmethod.jp/articles/guardduty-support-malware-protection/ GuardDuty → 保護プラン → Malware Protection 「GuardDuty が開始するマルウェアスキャン」内のステータスを確認すると、 「GuardDuty が開始するマルウェアスキャン が有効になっていません」となっている 30日間の無料トライアルがあるらしいので、「有効にする」ボタンを押す 有効にするか確認ダイアログが表示されるので、「確認」ボタンを押す ステータスが「GuardDuty が開始するマルウェアスキャン が有効になっています」になった 同画面の「全般設定」にある「マルウェアが検出された場合、スキャンされたスナップショットを保持します。」をONにしておく ■検出 引き続き、マルウェアの検出を試してみる テスト用に適当なEC2を起動し、マルウェアのテストファイルを配置する
$ wget https://secure.eicar.org/eicar.com $ wget https://secure.eicar.org/eicar_com.zip $ ll total 8 -rw-rw-r-- 1 ec2-user ec2-user 68 Jul 1 2020 eicar.com -rw-rw-r-- 1 ec2-user ec2-user 184 Jul 1 2020 eicar_com.zip
マルウェアを配置するだけでは、GuardDutyからは検知されない 不審とされる挙動も行う(コインマイニングに関するドメインの名前解決を行う)
$ nslookup pool.supportxmr.com $ curl pool.supportxmr.com
GuardDuty → マルウェアスキャン 検知されたものがこの画面に表示されるが、すぐには表示されない(今回は1時間ほどで検知された) 一覧で選択すると、画面の右側に詳細情報が表示された 詳細情報の「概要 → CloudWatch」にあるリンクをクリックすると、以下のクエリが表示されている。
fields @timestamp, @message | filter @message like '46d701a8ebceb6c93f75de1809b2220a' | sort @timestamp desc | limit 200
「クエリの実行」をクリックすると、以下2つの結果が表示された。 これは単に「脅威が検知された」というイベントが表示されているだけか。
フィールド: 値 @ingestionTime: 1690342987254 @log: 123456789012:/aws/guardduty/malware-scan-events @logStream: c058d4e2-1a8d-4565-8b88-bc00e3c3e310 @message: {"eventDetails":{"accountId":"123456789012","eventType":"EC2_SCAN_COMPLETED","eventTime":"2023-07-26T03:42:49Z","detectorId":"4ec053a368f1c72497f5ad67e38dc04a","schemaVersion":"1.0"},"scanRequestDetails":{"requestType":"GUARDDUTY_FINDING_INITIATED","scanId":"46d701a8ebceb6c93f75de1809b2220a","guardDutyRequestDetails":{"findingId":"26c4c820d2c1b86d979c479dea6990ce"}},"resourceDetails":{"resourceType":"EC2_INSTANCE","instanceDetails":{"instanceId":"i-088a619d669f14c2d","volumeDetailsList":[{"volumeId":"vol-0a506a40eeea1edd1","deviceName":"/dev/xvda","volumeSizeGb":8,"volumeSnapshotId":"snap-05844b5e699b8bad8"}]}},"scanResultsSummary":{"scanResultStatus":"THREATS_FOUND","scannedItemCount":{"totalGb":2,"files":44446}}} @timestamp: 1690342969000 eventDetails.accountId: 123456789012 eventDetails.detectorId: 4ec053a368f1c72497f5ad67e38dc04a eventDetails.eventTime: 2023-07-26T03:42:49Z eventDetails.eventType: EC2_SCAN_COMPLETED eventDetails.schemaVersion: 1.0 resourceDetails.instanceDetails.instanceId: i-088a619d669f14c2d resourceDetails.instanceDetails.volumeDetailsList.0.deviceName: /dev/xvda resourceDetails.instanceDetails.volumeDetailsList.0.volumeId: vol-0a506a40eeea1edd1 resourceDetails.instanceDetails.volumeDetailsList.0.volumeSizeGb: 8 resourceDetails.instanceDetails.volumeDetailsList.0.volumeSnapshotId: snap-05844b5e699b8bad8 resourceDetails.resourceType: EC2_INSTANCE scanRequestDetails.guardDutyRequestDetails.findingId: 26c4c820d2c1b86d979c479dea6990ce scanRequestDetails.requestType: GUARDDUTY_FINDING_INITIATED scanRequestDetails.scanId: 46d701a8ebceb6c93f75de1809b2220a scanResultsSummary.scanResultStatus: THREATS_FOUND scanResultsSummary.scannedItemCount.files: 44446 scanResultsSummary.scannedItemCount.totalGb: 2 フィールド: 値 @ingestionTime: 1690342522740 @log: 123456789012:/aws/guardduty/malware-scan-events @logStream: c058d4e2-1a8d-4565-8b88-bc00e3c3e310 @message: {"eventDetails":{"accountId":"123456789012","eventType":"EC2_SCAN_STARTED","eventTime":"2023-07-26T03:35:00.795Z","detectorId":"4ec053a368f1c72497f5ad67e38dc04a","schemaVersion":"1.0"},"scanRequestDetails":{"requestType":"GUARDDUTY_FINDING_INITIATED","scanId":"46d701a8ebceb6c93f75de1809b2220a","guardDutyRequestDetails":{"findingId":"26c4c820d2c1b86d979c479dea6990ce"}},"resourceDetails":{"resourceType":"EC2_INSTANCE","instanceDetails":{"instanceId":"i-088a619d669f14c2d","volumeDetailsList":[{"volumeId":"vol-0a506a40eeea1edd1","deviceName":"/dev/xvda","volumeSizeGb":8}]}}} @timestamp: 1690342500795 eventDetails.accountId: 123456789012 eventDetails.detectorId: 4ec053a368f1c72497f5ad67e38dc04a eventDetails.eventTime: 2023-07-26T03:35:00.795Z eventDetails.eventType: EC2_SCAN_STARTED eventDetails.schemaVersion: 1.0 resourceDetails.instanceDetails.instanceId: i-088a619d669f14c2d resourceDetails.instanceDetails.volumeDetailsList.0.deviceName: /dev/xvda resourceDetails.instanceDetails.volumeDetailsList.0.volumeId: vol-0a506a40eeea1edd1 resourceDetails.instanceDetails.volumeDetailsList.0.volumeSizeGb: 8 resourceDetails.resourceType: EC2_INSTANCE scanRequestDetails.guardDutyRequestDetails.findingId: 26c4c820d2c1b86d979c479dea6990ce scanRequestDetails.requestType: GUARDDUTY_FINDING_INITIATED scanRequestDetails.scanId: 46d701a8ebceb6c93f75de1809b2220a
GuardDuty → 検出結果 検出結果の一覧に、重大な検出結果として「Execution:EC2/MaliciousFile」と「CryptoCurrency:EC2/BitcoinTool.B!DNS」が表示されている 「Execution:EC2/MaliciousFile」をクリックして詳細を確認する
2 security risk(s) detected including EICAR-Test-File (not a virus) on EC2 instance i-088a619d669f14c2d.
とあり、EICAR-Test-File が検出されたとなっている 下の方の「検出された脅威」部分で、ファイルの場所も確認できる /home/ec2-user/eicar.com /home/ec2-user/eicar_com.zip 「CryptoCurrency:EC2/BitcoinTool.B!DNS」をクリックして詳細を確認する
EC2 instance i-088a619d669f14c2d is querying a domain name that is associated with Bitcoin-related activity.
とあり、ビットコイン関連の活動に関連するドメイン名が照会されたとなっている ■通知 検出結果の通知方法について、以下などで紹介されている Amazon GuardDutyのマルウェア対策機能を使用する&通知方法 - NRIネットコムBlog https://tech.nri-net.com/entry/guardduty_malware_protection Amazon GuardDutyのマルウェアスキャン結果を受動的に受け取ることができるか確認してみた + 裏側の仕組みを推測してみた | DevelopersIO https://dev.classmethod.jp/articles/check-guardduty-malware-scan-event-spec/ 通知のためにはEventBridgeが必要みたい 以下などを参考に、改めて確認しておきたい Amazon EventBridge (サーバーレスイベントバスでアプリ同士を簡単に接続) | AWS https://aws.amazon.com/jp/eventbridge/ Amazon EventBridgeとは何か - Qiita https://qiita.com/ishibashi-futoshi/items/586ebe17b174a478eb6a 見せてやるよ、EventBridge の本気ってやつをな / The art of EventBridge - Speaker Deck https://speakerdeck.com/_kensh/the-art-of-eventbridge ひとまず以下をもとに、EventBridgeで「EC2の自動停止&自動起動」を試してみるのが良さそう 【AWS】Amazon EventBridge SchedulerでEC2を定期的に停止・起動し料金を節約する方法|サービス|法人のお客さま|NTT東日本 https://business.ntt-east.co.jp/content/cloudsolution/ih_column-08.html 引き続き確認したい
■請求アラーム
AWS の予想請求額をモニタリングする請求アラームの作成 - Amazon CloudWatch https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_... AWS BudgetsでAWSの想定外コストを監視する | 株式会社スタイルズ https://www.stylez.co.jp/columns/monitor_aws_unexpected_costs_with_aws_budget/ 各AWSアカウントのルートユーザでコンソールにログイン 「(画面右上のアカウント名)→ Billing and Cost Management」(もしくは検索から「Budgets」にアクセス) 「予算の作成」から設定を行う「月次コスト予算」でアカウントごとに金額を設定するのがいいか 以下の内容で入力 予算名には、AWSアカウントを判別できる文字列を含めておくと良さそう
予算の設定: テンプレートを使用 (シンプル) テンプレート: 月次コスト予算 予算名: refirio-dev Monthly Cost Budget 予算額: $500.00 Eメールの受信者: (通知したいメールアドレス)
「予算を作成」をクリックして「予算 月次コスト予算 が正常に作成されました。」と表示されたので、完了できたみたい なお予算の作成画面で、「スコープ」として
1) 実際の支出が 85% に達したとき、2) 実際の支出が 100% に達したとき、3) 予測される支出が 100% に達すると想定されるときに通知されます。
と表示されている 予算を作成した直後から、リロードすると「予算と計画 → 予算」の画面に請求アラームの現状が表示されるようになっている 予算を超えると「超過 (1)」のように表示され、 「AWS Budgets: refirio-dev Monthly Cost Budget has exceeded your alert threshold」 のようなメールも送られてくる 予算の85%時点で警告メールが送られてくるので、普段の費用の1.5倍くらいを予算額にしておくのがいいか
■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 ■カスタムメトリクスで監視1 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 ■カスタムメトリクスで監視2 AWS提供のスクリプトを使用せずに、任意の項目を監視する方法 AWS CloudWatchにカスタムメトリックスを登録する - Siguniang's Blog https://siguniang.wordpress.com/2014/12/19/publish-custom-metrics-to-cloudwatch-with-awscli/ EC2インスタンス内から情報を取得する方法 #AWS - Qiita https://qiita.com/akikinyan/items/c6be02e1d48de46fca53 【AWS】CloudWatchカスタムメトリクスを知る|SAYJOY blog https://sayjoyblog.com/aws-cli-cloudwatch-custommetrics-handson/ 公開は、lsyncdに異常があれば通知させるものとする lsyncdは、成功時は以下の内容が返される
# service lsyncd status Redirecting to /bin/systemctl status lsyncd.service ● lsyncd.service - Live Syncing (Mirror) Daemon Loaded: loaded (/usr/lib/systemd/system/lsyncd.service; enabled; vendor preset: disabled) Active: active (running) since 木 2023-11-30 14:29:40 JST; 1h 59min ago Main PID: 25966 (lsyncd) CGroup: /system.slice/lsyncd.service └─25966 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf
失敗時は以下の内容が返される
# service lsyncd status Redirecting to /bin/systemctl status lsyncd.service ● lsyncd.service - Live Syncing (Mirror) Daemon Loaded: loaded (/usr/lib/systemd/system/lsyncd.service; enabled; vendor preset: disabled) Active: failed (Result: exit-code) since 水 2023-11-29 15:48:19 JST; 22h ago Process: 3862 ExecStart=/usr/bin/lsyncd -nodaemon $LSYNCD_OPTIONS (code=exited, status=255) Main PID: 3862 (code=exited, status=255)
今回は「running」という文字があれば正常とみなす…とする 使用するアクセスキーに対して、あらかじめ CloudWatchFullAccessV2 の権限を与えておく また今回は、以下のようにawsコマンドを使ってEC2にアクセスキーを登録した
# aws configure AWS Access Key ID [None]: (アクセスキーを入力) AWS Secret Access Key [None]: (シークレットアクセスキーを入力) Default region name [None]: ap-northeast-1 Default output format [None]: text
lsyncdの状態を確認して、CloudWatchにデータを送信するシェルスクリプトを作成する
# vi lsyncd_status_check_failed.sh
#!/bin/bash REGION="ap-northeast-1" INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id` TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%S.000Z) NAMESPACE="Middleware/Rsync" METRIC_NAME="StatusCheckFailed" result=`systemctl status lsyncd | grep -c "Active: active (running)"` if [ $result -eq 1 ]; then value=0 else value=1 fi #echo $REGION; #echo $INSTANCE_ID; #echo $TIMESTAMP; #echo $NAMESPACE; #echo $METRIC_NAME; #echo $value; /usr/bin/aws cloudwatch --region $REGION put-metric-data --dimensions InstanceId=$INSTANCE_ID --timestamp $TIMESTAMP --namespace $NAMESPACE --metric-name $METRIC_NAME --value $value --unit Count
Cronで5分ごとに実行させる
# chmod 0744 lsyncd_status_check_failed.sh # ./lsyncd_status_check_failed.sh # vi /etc/crontab
*/5 * * * * root /usr/bin/sh /root/lsyncd_status_check_failed.sh > /dev/null 2>&1
CloudWatch → メトリクス → すべてのメトリクス 「カスタム名前空間」に「Middleware/Rsync」が追加される クリックすると「InstanceId」があり、 さらにクリックするとメトリクス名「StatusCheckFailed」を確認できる (値を確認できるようになるには、5分程度のタイムラグがあるみたい) 最後に、「StatusCheckFailed >= 1」をトリガーに、CloudWatchのアラームを設定する ■アラーム状態からの復旧を通知 「アクションの設定」で「通知」を登録する際、デフォルトでは「アラーム状態」になったときの通知設定になっている ここで「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の併用がいいかも ■アクセスキーの発行 CloudWatchAgentServerPolicyの権限を持ったアクセスキーを発行する もしくは、以下の手順のように「EC2にCloudWatchAgentServerPolicyの権限を持たせる」とすることで、アクセスキーの管理が不要になる IAM → アクセス管理 → ロール → ロールを作成 信頼されたエンティティタイプ: AWSのサービス 一般的なユースケース: EC2 「次へ」ボタンをクリック 「許可を追加」画面で「CloudWatchAgentServerPolicy」を選択して「次へ」ボタンをクリック ロール名: CloudWatchAgentServerRole 説明: Allows EC2 instances to call AWS services on your behalf. (変更せず) 「ロールを作成」ボタンをクリック 続いて、作成したIAMロールをEC2に紐づける EC2 → インスタンス 対象のEC2にチェックを入れ、「アクション → セキュリティ → IAMロールを変更」を選択 「IAMロールを変更」画面になるので、上で作成した「CloudWatchAgentServerRole」を選択して「IAMロールの更新」ボタンをクリック ■awslogsをインストール&設定
# 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 … アクセスキーを発行した場合に設定(EC2に権限を持たせた場合は不要) 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の自動起動を設定 # systemctl status awslogsd … awslogsの実行状況を確認 # vi /var/log/awslogs.log … awslogsのログを確認
Amazon Linux 2 以前の場合、以下で起動できる
# service awslogs start # chkconfig awslogs on
■転送されたログを確認 しばらく待つと、「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.
ログをもとに何らかの通知を行う場合、念のため「[TRUNCATED MESSAGE] という文字があれば警告」としておくべきか 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/ AWS Cloud9で共有環境を用意する手順 - Qiita https://qiita.com/predora005/items/b43a0d60163179fa7557 Cloud9の使い方と便利機能!最強プログラミング開発環境(IDE) | 侍エンジニアブログ https://www.sejuku.net/blog/385 ★2022年最新★入門!AWS Cloud9でLaravel環境を構築する方法 - 3流なSEのメモ帳 https://www.3ryu-engineer.work/cloud9-laravel/ ■作成 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
AWSのLambdaってなんやねん https://zenn.dev/mi_01_24fu/books/d91d10985a5a1a ※あらかじめ登録したコードを実行できる ※コードはイベントに応じて呼び出したり、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でDockerを使うなら、イメージのリポジトリには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
CLIを「WSL2 + Ubuntu 20.04」環境へインストールしたときのメモは、 このファイル内の「AWS CLI(WSL2 + Ubuntu 20.04 で使用する場合)」を参照 ■イメージを作成 ※WSL2環境でイメージを作成 「php:8.1-apache」をもとに、追加でファイルを作成するだけのイメージを作成する docker\ecr_test\Dockerfile … Dockerfileを作成
FROM php:8.1-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 … テストファイルを確認する # exit
また 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 build -t ecr_test . docker tag ecr_test:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:latest docker 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 3.584kB Step 1/2 : FROM php:8.1-apache ---> 76fa555fcac9 Step 2/2 : RUN touch /root/test1.txt ---> Using cache ---> e8332eb2f5c2 Successfully built e8332eb2f5c2 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] 16788635e2ad: Pushed 839aba438279: Pushed 5fa1fe860d6d: Pushed fbc5f9f798a9: Pushed 0247316d71c0: Pushed d83d11719d7e: Pushed a7618c479297: Pushed fd73f51dc648: Pushed d40a2cacf223: Pushed 5eea57558f06: Pushed e1937617ab94: Pushed 3f0d95c332b4: Pushed ffa1dde3d394: Pushed 43b3c4e3001c: Pushed 1.0.0: digest: sha256:88bc7b7d5c6966a4ca2f043a821d64d36d573c47ac3d877d466fa4d8d4d5486f 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
■イメージの脆弱性スキャン リポジトリ内のイメージ一覧で、任意のイメージにチェックを入れて「スキャン」を押すと、イメージの脆弱性スキャンを利用できる 上記イメージに対して実行すると、441件の警告が表示された。詳細は以下のとおり Critical ... 1 High ... 5 Medium ... 26 Low ... 17 Informational ... 207 Undefined ... 186 Criticalの内容は以下のとおり 名前: CVE-2019-19814 パッケージ: linux:5.10.127-1 重要度: 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/ 対応については、また確認しておきたい 脆弱性スキャンについては、後述の「ベースイメージのセキュリティチェックについて考察」も参照 ■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:8.1-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\index.php
<?php phpinfo() ?>
docker\ecr_test\Dockerfile
FROM php:8.1-apache COPY code /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 # exit
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:8.1-apache」を使ってみる Elastic Container Registry → Public gallery ページ上部の検索フォームから「php:8.1-apache」と入力して検索すると、以下のページにたどり着くことができる 「Mirror of dockerhub php:8.1-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 ■FargateとEC2 EC2のセキュリティ対策は利用者自身が行う必要がある 一方Fargateはマネージドサービスのため、セキュリティ対策はAWSの責任になる Fargateだと、ベストエフォートでAZ間のバランスを調整しながらタスクが配置される つまり利用者は、AZ配置に関して考える必要が無い Fargateの料金はEC2の1.4倍ほど 月額1万円が1万4000円になるような案件はFargateでいいと思うが、月額100万円が140万円になるような案件だと考慮が必要そう 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 AWS FargateではなくECS on EC2を選ぶメリット〜コスト編〜 - Uzabase for Engineers https://tech.uzabase.com/entry/2022/12/01/175423 ■Fargateのプラットフォームのバージョン 「プラットフォームのバージョン: LATEST」は特定のバージョン(その時点での最新版)を指定すべきか 2023年5月時点で、選択できるバージョンは「LATEST」「1.4.0」「1.3.0」となっている プラットフォームに問題が発覚した場合、恐らく「1.4.1」と「1.3.1」がリリースされるのだと思われる それなら、マイナーバージョンを最新に保っておけばいいのだと思われる プラットフォームバージョンが古いものは、徐々に廃止されていく 強制更新日になると、強制デプロイにより自動的に更新される また、普段の更新でもLATESTがデプロイされることになるので、それによっても更新されることになる AWS Fargate プラットフォームバージョンの廃止 - Amazon ECS https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/platform-versions-retired.html 1.4.0のときは、以下のような変更がされている Fargateプラットフォーム1.4.0の変更点 - Qiita https://qiita.com/ryo0301/items/8929761f5df7e1e2e7a0 そのままでも動作するかもしれないが、RDSのアップデートなどと同様に考えるなら、意図しない変更での問題は防ぎたい よってバージョンは固定したうえで、検収環境などで問題無いことが確認できてから、プラットフォームのバージョンを手動で調整する方が安全そう バージョンを固定する場合、CodePipelineやSDKの考慮が必要かどうかは確認しておく AWS Fargateのプラットフォームバージョンを1.3.0に固定したつもりが失敗したお話 - Qiita https://qiita.com/imai_amazia/items/df139425df350be439a8 ■Fargateのスペック ECSにおけるタスクとコンテナについて、前提として ・タスクはECSで管理する最小単位 タスクには1つ以上のコンテナが含まれる 単一のタスクは同一のホストOS上で稼働する。1つのタスクを2台以上のホストOSにまたいで稼働させることはできない ・コンテナはDockerのコンテナのこと ECSのタスクに内包される 単一のコンテナを起動するには、1つのタスク内に1つのコンテナのみを内包する となっているが、それを踏まえてFargateのスペックについて インスタンスタイプは「タスクサイズ」により決定される これは ・「サービスの設定 → デプロイ設定 → 必要なタスク」はデフォルト「1」だが、この場合はマルチAZでは無い 「2」以上にしてはじめてマルチAZになるので、本番環境では原則「2」以上にしておく ・「タスク定義 → 環境 → タスクサイズ」の「CPU」「メモリ」は、1つのタスクが使用するCPUとメモリを決定するもの つまりデフォルトのCPU「1 VCPU」メモリ「3 GB」は、EC2の1台の性能に相当するものと考える またnginxコンテナとphpコンテナを立ち上げるタスクの場合、その2つのコンテナにより1つのEC2(に相当するもの)が使われる ・例えば「必要なタスク」を「2」にした場合、全体でCPU「2 VCPU」メモリ「6 GB」の環境が用意されることになる という理解でいいと思われる 例えば 「検収環境ではt3.micro(2vCPU / 1GB)で1台構成、本番環境ではt3.small(2vCPU / 2GB)で2台構成」 に相当する性能で稼働させたい場合、メモリベースで考えるなら ・検収環境での必要なタスクは「1」とする。タスクサイズは、CPU「0.5vCPU」、メモリ「1GB」とする ・本番環境での必要なタスクは「2」とする。タスクサイズは、CPU「1vCPU」、メモリ「2GB」とする 程度とするのがいいか ただしそもそも、EC2とFargateの性能を単純に比較するのは難しそうなので、稼働させるプログラムに応じて考える また上記の場合、検収環境はCPUが普段(EC2)よりも弱いので、動作が遅いなどの可能性はありそう 本稼働前に、負荷をかけてベンチマークを取るなどをしておくといい Fargate タスクサイズの選択 - Amazon Elastic Container Service https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/fargate-task-size.html ECS on Fargateの良いところ ~性能・拡張性~ | BTC Cloud https://cloud.bigtreetc.com/column/merit-of-ecs-on-fargate-spec-scalability/ Amazon ECS タスク定義の"タスクサイズのCPU"と”コンテナのCPUユニット”の違いを調べてみた - のぴぴのメモ https://nopipi.hatenablog.com/entry/2020/12/13/223713 FargateのvCPU性能と価格感等雑感 https://gist.github.com/nabeken/97a54cc98ae6892910df4b4b265b4fdd ■作業の流れ おおまかに、以下のような作業の流れとなる 削除する場合、逆順に作業する 1. VPCの作成 ... ネットワークを作成する(クラスターと一緒に作成できるが、あらかじめ作成しておく方が良さそう) 2. ロードバランサーの作成 ... クラスターの上位に配置するロードバランサーを作成する 3. タスクの定義 ... クラスター上で動かすコンテナの情報を定義する(イメージ、CPUやメモリの制限、アプリケーションの環境変数など) 4. クラスターの作成 ... クラスターを動かすためのFargateやEC2の設定を行う(ネットワークなど。EC2の場合はインスタンスタイプ、インスタンス数も) 5. サービスの作成 ... VPC、ロードバランサー、タスク、クラスターを結びつける(一つのクラスターに複数のサービスを登録することもできる) ※イメージは「Amazon Elastic Container Registry(Amazon ECR)」で作成した「ecr_test」を使用するものとする ■VPCの作成 クラスター作成時、VPCを作成する指定を行なえばCloudFormationで一緒に作成される が、ここではCloudFormationであらかじめ作成しておく(管理しやすいそうなので) VPCの名前は、ここでは「Container」とする ※VPCやセキュリティグループは、CloudFormationであらかじめ作成しておく方が良さそう 手順中に新規に作った場合、名前が無しで作られるようなので、名前の設定はしておくと良さそう 手順中に作ると、ECSクラスターと一緒に削除してくれるメリットはあるが、VPCを削除することはそう無いか ■ロードバランサーの作成 EC2 → ターゲットグループ → ターゲットグループの作成 ターゲットタイプの選択: IP addresses ターゲットグループ名: Container-Test-TargetGroup VPC: Container(あらかじめ作成しておいたもの) プロトコルバージョン: HTTP1 非正常のしきい値: 2(デプロイ高速化のため変更するといい) 間隔: 30(ヘルスチェックの間隔はデフォルトで30秒だが、短くすればデプロイも早くなる。ただし間隔が短すぎるのも考えものか。要検討) 「Next」をクリック 「Register targets」の画面になる 特に何も変更せず「Create target group」をクリック これでターゲットの無いターゲットグループができる EC2 → ロードバランサー → ロードバランサーの作成 ロードバランサータイプの比較と選択: Application Load Balancer ロードバランサー名: Container-Test-LoadBalancer VPC: Container(あらかじめ作成しておいたもの) マッピング: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの) セキュリティグループ: default, Container-WebSecurityGroup(あらかじめ作成しておいたもの / 80番ポートを通すためのセキュリティグループを選択) リスナーとルーティング Protocol: HTTP Port: 80 Default action: Container-Test-TargetGroup 「ロードバランサーの作成」をクリック ロードバランサーが作成されるので、「View load balancer」で確認する ターゲットタイプについては以下を参照 Blue/Greenデプロイを使うなら、「Instance」ではなく「IP addresses」にしておく必要があるらしい (古いプログラムと新しいプログラムを混在することが短時間でも許容できない場合、Blue/Greenデプロイを採用するといい) [新機能] ALBのターゲットにIPアドレスを指定可能になりました | DevelopersIO https://dev.classmethod.jp/articles/ip-target-for-alb/ ALBのターゲットにIPアドレスを指定できる機能は、2017年からの機能らしい 外部のサーバを指定したりではなく、ローカルのIPを指定する前提みたい 到達可能なIPアドレスであれば、VPCをまたいで指定できるメリットはあるみたい ターゲットグループ作成時の「Healthy threshold」と「Interval」の設定によるデプロイ高速化については、以下の記事が参考になる Amazon ECS でのコンテナデプロイの高速化 | トリの部屋 https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments/ CodePipelineの環境を作って、Gitへのプッシュからデプロイ完了までの時間を確認すると、以下のような変化があった 3分ほど早くなったので、確かに効果はありそう(設定次第では、さらに早くできそう) 20:22 にプッシュ Sourceはすぐに完了した Buildは20:26に完了した(4分かかった) Deployは20:33に完了した(7分かかった) 合計11分ほどかかった ターゲットグループの「Healthy threshold」の設定を「5」から「2」に変更 20:36 にプッシュ Sourceはすぐに完了した Buildは20:40に完了した(4分かかった) Deployは20:44に完了した(4分かかった) 合計8分ほどかかった ■タスクの定義 ※イメージは「Amazon Elastic Container Registry(Amazon ECR)」で作成した「ecr_test」を使用するものとする ※本番運用するなら、「コンテナの追加」の際に「ストレージとログ」の「ログ設定」にチェックを入れておくか 再作成する場合、CloudWatchのロググループが作成済みなら、あらかじめ削除しておく必要があるか Elastic Container Service → Amazon ECS → タスク定義 → 新しいタスク定義の作成 → 新しいタスク定義の作成 タスク定義とコンテナの設定 タスク定義ファミリー: Container-Test-Task コンテナの詳細 名前: ecr_test イメージURI: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.0 プライベートレジストリ認証: (チェックしない / ECR以外でプライベートリポジトリを利用する場合に必要みたい) ポートマッピング: コンテナポート: 80 プロトコル: tcp ポート名: ecr_test-80-tcp(初めから入力されていた) アプリケーションプロトコル: HTTP 「次へ」をクリック 環境、ストレージ、モニタリング、タグの設定 アプリケーション環境: AWS Fargate (変更せず) ★「Amazon EC2 インスタンス」も検証したい オペレーティングシステム/アーキテクチャ: Linux/X86_64 (変更せず) タスクサイズ CPU: 1 vCPU (変更せず / 詳細は「Fargateのスペック」を参照) メモリ: 3 GB (変更せず / 詳細は「Fargateのスペック」を参照) タスクロール: (未選択のまま) タスク実行ロール: ecsTaskExecutionRole (変更せず) ネットワークモード: awsvpc(Fargateの場合、awsvpc以外に変更できない) モニタリングとログ記録: (デフォルトで「ログ収集の使用」にチェックされている。本番運用でなければチェックを外しておくか) 「次へ」をクリック 確認して作成 「作成」をクリック 「正常に作成されたタスク定義」のようなメッセージが表示されれば完了 「作成」ボタン押して以下のエラーが作成された場合、作業しているユーザの権限を確認する
User: arn:aws:sts::123456789012:assumed-role/AWSReservedSSO_PowerUserAccess_1db0a2445f639f21/refirio is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/ecsTaskExecutionRole because no identity-based policy allows the iam:PassRole action
Fargate タスクサイズの選択 - Amazon Elastic Container Service https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/fargate-task-size.html Fargateの場合、インスタンスタイプは上記設定の「タスクサイズ」により決定される ECSのタスクロールとタスク実行ロールの違い - karakaram-blog https://www.karakaram.com/difference-between-ecs-task-role-and-task-execution-role/ ネットワークモードについては以下を参考 Blue/Greenデプロイを使うなら、「<default>」ではなく「awsvpc」にする必要があるみたい 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 「EC2」の場合は「bridge」を選択すれば良さそうだが、以前は「<default>」を選択していた とは言え、ネットワークモードは「<default> = bridge」みたい? 【Amazon ECS】Amazon Elastic Container Service (EC2 Linux + ネットワーキング)を構築してみた - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/ecs-ec2-linux-networking ■クラスターの作成 Elastic Container Service → Amazon ECS → クラスター → クラスターの作成 クラスターの作成 クラスター名: Container-Test-Cluster ネットワーキング VPC: Container(あらかじめ作成しておいたもの) サブネット: Container-Public-A, Container-Public-C(あらかじめ作成しておいたもの) デフォルトの名前空間: Container-Test-Cluster(初めから入力されていた) インフラストラクチャ: AWS Fargate(はじめからチェックされていて、チェックを外せないようになっている) モニタリング: (チェックしない / 後から変更できないかも?本番環境用ならチェックを入れておくと良さそう) 「作成」をクリック ※はじめてクラスターを作成する際、「Unable to assume the service linked role. Please verify that the ECS service linked role exists.」と表示されて中断された もう一度同じ操作をすると、「ECSクラスターContainer-Test-Clusterが正常に作成されました」と表示されて完了した クラスター作成時に必要なロールが作成されるが、そのロールが使えるようになるには若干のタイムラグがあるため…らしい ただしエラーが発生したのはEC2のとき。Fargateの場合も発生するかは不明だし、そもそも改善されているかもしれない 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 → サービス → 作成 サービスの設定 環境 コンピューティングオプション: キャパシティープロバイダー戦略 ★「起動タイプ」についても検証したい キャパシティープロバイダー戦略: カスタムを使用(変更できず) キャパシティープロバイダ: FARGATE(変更せず) ベース: 0(変更せず) ウェイト: 1(変更せず) プラットフォームのバージョン: LATEST ※実案件では「1.4.0」などその時点での最新を選択する方が良さそう デプロイ設定 アプリケーションタイプ: サービス リビジョンの手動指定: (デフォルトのままチェックを入れず) ★意味については確認したい ファミリー: Container-Test-Task リビジョン: 1(最新) サービス名: Container-Test-Service サービスタイプ: レプリカ(変更できず) 必要なタスク: 2(デフォルトは1だが、2以上でマルチAZとなる) ネットワーキング VPC: Container サブネット: Container-Public-A, Container-Public-C セキュリティグループ: default, Container-WebSecurityGroup(あらかじめ作成しておいたもの / 80番ポートを通すためのセキュリティグループを選択) ロードバランシング ロードバランサーの種類: Application Load Balancer Application Load Balancer: 既存のロードバランサーを使用 ロードバランサー: Container-Test-LoadBalancer ロードバランス用のコンテナの選択: ecr_test 80:80 (変更せず) リスナー: 既存のリスナーを使用 リスナー: 80:HTTP ターゲットグループ: 既存のターゲットグループを使用 ターゲットグループ名: Container-Test-TargetGroup ヘルスチェックパス: /(変更せず) ヘルスチェックプロトコル: HTTP(変更せず) ヘルスチェックの猶予期間: 120 ★適切な値は確認したい(FargateではなくEC2のときだが「0だとコンテナサイズによってはうまく起動しないことがある」と聞いた) 「作成」をクリック 2〜3分ほど待つと、サービスの「前回のデプロイ」列が「完了」になった 「サービスタイプ」については引き続き調査したい 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つのインスタンスがぶら下がっている それぞれ、ローカルのIPアドレスを持っている インスタンスIDや名前は付けられていない(表示用の列自体が無い) EC2のインスタンス一覧には表示されていない ■イメージの変更 変更したイメージを作成し、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」にチェックを入れて「新しいリビジョンの作成」をクリック (以下、前回タスクを作成した時の内容をベースに入力する) 「イメージ URI」のみ以下に変更した(末尾のバージョンを変更) 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_test:1.0.1 Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → サービスを更新 デプロイ設定で以下2箇所を調整する 「新しいデプロイの強制」にチェックを入れる 「リビジョン」を最新のものに変更する 「更新」をクリック 2〜3分ほど待つと更新される ■コンテナへのSSH接続 ※未検証 ※後からAmazon ECS Execがリリースされ、SSHキーなどを使わずに直接コンテナに接続できるようになった 「Windows+WSL2+AWS CLI+Session Manager」で、ローカルPCから直接コマンドラインで操作できるようになる 詳細は、このファイル内の「Amazon ECS Exec」を参照 EC2とは違い、Fargateに直接SSHで接続したりはできない どうしても接続したい場合、AWS Systems Managerを使えば接続できるらしい ECS FargateにSSMを利用してSSH接続する(チュートリアル) - Qiita https://qiita.com/kouji0705/items/005ea6d7c21ddd24ebb3 FargateのコンテナでOSコマンドやsshで入りたい!! それssm-agentで解決できます https://zenn.dev/ryurock/articles/qiita-20191203-fa18b25b1b38c9a0f113 [AWS ECS]Fargateのcontainerにシェルで入りたい(sshd無しで!) - Qiita https://qiita.com/pocari/items/3f3d77c80893f9f1e132 AWS Fargateで動いているコンテナにログインしたくて Systems Manager の Session Manager を使ってみた話 - SMARTCAMP Engineer Blog https://tech.smartcamp.co.jp/entry/fargate-with-session-manager ■環境の削除 ※見かけ上の削除処理がすぐに完了したとしても、裏側ではCloudFormationなどが実行中で完了はしていないことがある よって環境を削除してすぐに同じ名前で環境を作ると、「すでに存在している」などのエラーになることがある また、何らかの理由でCloudFormationが正常に完了できない可能性もある 削除後に再作成する場合、30分ほど時間を空けたり、CloudFormationに未完了の処理が無いか確認するなどするのが無難 上の手順で作成した場合、以下の順番で削除できる 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を別途手動で作成した場合、必要に応じて別途削除する また、不要になったセキュリティ認証情報(ロールやポリシー)を削除しておく なお、タスク定義は「登録解除」しかできなかったが、これはタスクの一覧で「非アクティブなタスク定義」を選択することで表示できる状態だった が、2023年3月ごろに「非アクティブなタスク定義」一覧から削除できるようになった (とは言え、タスク定義が残っていても料金はかからないらしい) Amazon ECSのタスク定義のリビジョンが削除できるようになった - Qiita https://qiita.com/t_tsuchida/items/8f62aa8a218d5b9121fb ■ECS+EC2の構築メモ 「インフラストラクチャの作成」という手順が必要? 何か変更されたか、以前と違う操作をしてしまっているだけか Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → インフラストラクチャ → コンテナインスタンス → 外部インスタンスを登録 アクティベーションキーの有効期間 (日数): 1(変更せず) インスタンス数: 4(デフォルトは1000。「このアクティベーションで登録する外部インスタンスの最大数です。」とあるので、これは1000台のEC2インスタンスが作られるのではなく、上限値を設定するだけ?) インスタンスロール: 新規作成 「登録コマンドの生成」ボタンをクリック 以下のようなコマンドが表示されたが、よく解らず
curl --proto "https" -o "/tmp/ecs-anywhere-install.sh" "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh" && bash /tmp/ecs-anywhere-install.sh --region "ap-northeast-1" --cluster "Container-Test-Cluster" --activation-id "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" --activation-code "XXXXXXXXXXXXXXXXXXXX"
■ECS+EC2の動作確認メモ FargateではなくEC2を採用したときの動作確認メモ ターゲットグループを確認すると、以下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とも直接アクセスできている ■ECS+EC2の動作確認メモ: イメージの変更準備(動的ポートマッピングの設定) 動的ポートマッピングを利用するため、 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 ■ECS+EC2の動作確認メモ: イメージの変更準備(イメージの準備) 変更したイメージを作成し、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
■ECS+EC2の動作確認メモ: イメージの変更 タスク定義に新しいリビジョンを作成する 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分程度かかる) ■ECS+EC2の動作確認メモ: 補足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 ■ECS+EC2の動作確認メモ: 補足2 「新しいデプロイの強制」にチェックを入れなかった場合、以下のようにしてタスクを入れ替えることができる 1. タスクを1つ選択し、「停止」ボタンで停止させる 2. サービスの設定に従って、「Container-Test-Task:1」ではなく「Container-Test-Task:2」が起動される この場合、動的ポートマッピングの設定は不要だが、起動させるべきタスクの数が多いと単純に手間がかかる また、どうしてもダウンタイムが発生してしまうと思われる ※タスクを停止した直後は、タスクが終了された方のインスタンスにアクセスされてエラーが表示されることがある 数秒で解消するようだが、本番運用するとなると気になる CodePipelineでの自動デプロイなら、「新しいタスクが起動されてから、古いタスクへのアクセスが遮断される」となっているようなので問題無いか ■ECS+EC2の動作確認メモ: 補足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 で起動し、ロードバランサーからのアクセスもこのポートに合わせる これを動的ポートマッピングと呼ぶ ■ECS+EC2の動作確認メモ: クラスターのインスタンスタイプを変更する クラスターを作成する際に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
■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/
■Amazon ECS Exec
「Windows+WSL2+AWS CLI+Session Manager」で、ローカルPCから直接コマンドラインで操作できるようになるみたい Fargateなど外部から直接SSHアクセスできないものにも、アクセスできるようになるみたい [アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました | DevelopersIO https://dev.classmethod.jp/articles/ecs-exec/ Amazon ECS Execを使ってみる - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/ecs-exec ECS Execを使って Fargateのコンテナにアクセスする - Qiita https://qiita.com/okubot55/items/b1fb07b2de08c354275b Session ManagerプラグインをインストールしてローカルWindows PCからEC2へSession Managerで接続してみた | DevelopersIO https://dev.classmethod.jp/articles/installed-session-manager-plugin-and-connected-from-local-window... [ECS/Fargate]SSHログインせずにECS Execでログインする - ADACHIN SERVER LABO https://blog.adachin.me/archives/47413 Amazon ECS Exec(aws ecs execute-command)を便利にするツール「sssh」 | DevelopersIO https://dev.classmethod.jp/articles/sssh-ecs-exec-tool/ ■接続ユーザ用IAMの作成 ※要検証 接続する側のIAMには、最低でも以下の権限が必要 ecs:ExecuteCommand ssm:StartSession ecs:DescribeTasks Amazon ECS Execを使ってみる - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/ecs-exec ■ツールのインストール AWS CLIが使える環境に、追加で「session-manager-plugin」をインストールする必要がある 以下はWSL2にインストールを試したときの内容 【Windows WSL2】UbuntuにAWS CLIとSession Managerをインストール https://zenn.dev/yukiko_bass/articles/6b2c47357e83e1
$ 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 $ session-manager-plugin session-manager-plugin: command not found $ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 3292k 100 3292k 0 0 1119k 0 0:00:02 0:00:02 --:--:-- 1119k $ sudo dpkg -i session-manager-plugin.deb [sudo] password for refirio: Selecting previously unselected package session-manager-plugin. (Reading database ... 32566 files and directories currently installed.) Preparing to unpack session-manager-plugin.deb ... Preparing for install Unpacking session-manager-plugin (1.2.463.0-1) ... Setting up session-manager-plugin (1.2.463.0-1) ... Creating symbolic link for session-manager-plugin $ session-manager-plugin The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.
インストールには成功した ■ECS Execでの接続の流れ ECS Execを使って Fargateのコンテナにアクセスする - Qiita https://qiita.com/okubot55/items/b1fb07b2de08c354275b [アップデート] 実行中のコンテナに乗り込んでコマンドを実行できる「ECS Exec」が公開されました | DevelopersIO https://dev.classmethod.jp/articles/ecs-exec/ Amazon ECS Execを使ってみる - サーバーワークスエンジニアブログ https://blog.serverworks.co.jp/ecs-exec 構築したECSでは、各ロールは以下のようになっている タスクロール: (未選択のまま) タスク実行ロール: ecsTaskExecutionRole よって「ecsTaskRole」というロールを作り、それをタスクロールに割り当てるのが良さそう 具体的には、 ポリシー「ECSTaskRolePolicy」を作成し、JSONで内容を定義する ロール「ecsTaskRole」を作成し、上で作成したポリシーを割り当てる タスク定義で「タスクロール」に、上で作成したロールを割り当てる サービスを更新(デプロイ)する という流れで作業する 以降は具体的な内容 ■ポリシーの作成 セキュリティ認証情報 → ポリシー → ポリシーの作成 「JSON」タブに以下を入力する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel", "ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel" ], "Resource": "*" } ] }
「次のステップ:タグ」をクリック そのまま「次のステップ:確認」をクリック ポリシーの作成画面になるので以下を入力 名前: ECSTaskRolePolicy 説明: Policy for ECS Task 「ポリシーの作成」をクリック ■タスクロールの作成 IAM → アクセス管理 → ロール → ロールを作成 信頼されたエンティティを選択 信頼されたエンティティタイプ: AWSのサービス AWSアカウント 他のAWSのサービスのユースケース: Elastic Container Service → Elastic Container Service Task を選択 「次へ」ボタンをクリック 許可を追加 上の手順で作成した「ECSTaskRolePolicy」を検索してチェックを入れる 「次へ」ボタンをクリック 名前、確認、および作成 ロール名: ecsTaskRole 「ロールを作成」ボタンをクリック ■タスク定義の更新 Elastic Container Service → Amazon ECS → タスク定義 「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック (以下、前回タスクを作成した時の内容をベースに入力する) 「タスクロール」が空欄になっているはずなので、上の手順で作成した「ecsTaskRole」を選択 これでタスクを作成する ■サービスの更新(デプロイ) Elastic Container Service → Amazon ECS → クラスター → Container-Test-Cluster → サービス → Container-Test-Service → サービスを更新 デプロイ設定で以下2箇所を調整する 「新しいデプロイの強制」にチェックを入れる 「リビジョン」を最新のものに変更する 「更新」をクリック ■ECSの情報を確認 awscli ECS 関連コマンドメモ - Qiita https://qiita.com/notakaos/items/eda64c3c38b17f181698 ECSクラスターの一覧を表示
$ aws ecs list-clusters
ECSクラスター「Container-Test-Cluster」の詳細を表示
$ aws ecs describe-clusters --cluster Container-Test-Cluster
ECSサービスの一覧を表示
$ aws ecs list-services --cluster Container-Test-Cluster
ECSサービス「Container-Test-Service」の詳細を表示
$ aws ecs describe-services --cluster Container-Test-Cluster --services Container-Test-Service
ECSタスクの一覧を表示
$ aws ecs list-tasks --cluster Container-Test-Cluster --service-name Container-Test-Service
ECSタスクの詳細を表示
$ aws ecs describe-tasks --cluster Container-Test-Cluster --tasks 581cb32055144824ad8e314ea3e9a0d5
■ECS Execを有効化 サービスの「enableExecuteCommand」の設定を確認
$ aws ecs describe-services --cluster Container-Test-Cluster --services Container-Test-Service | grep enableExecuteCommand
サービスの「enableExecuteCommand」の設定を有効化
$ aws ecs update-service --cluster Container-Test-Cluster --service Container-Test-Service --enable-execute-command
サービスの「enableExecuteCommand」の設定を無効化する場合
$ aws ecs update-service --cluster Container-Test-Cluster --service Container-Test-Service --disable-execute-command
■サービスの更新(デプロイ) 上記の設定は、タスクに対してではなくサービスに対して行われている つまりECS Execは「enableExecuteCommand」を有効にした後に起動したタスクでのみ利用可能なので、再度「サービスの更新(デプロイ)」を行う必要がある リビジョンはそのままに、「新しいデプロイの強制」にチェックを入れて「更新」をクリックする ■接続 ECSタスクの一覧を表示
$ aws ecs list-tasks --cluster Container-Test-Cluster --service-name Container-Test-Service
タスクを指定して命令を実行
$ aws ecs execute-command --cluster Container-Test-Cluster --task 581cb32055144824ad8e314ea3e9a0d5 --container ecr_php81_apache --interactive --command "ps aux" $ aws ecs execute-command --cluster Container-Test-Cluster --task 59ede1ca54a743dfa9952370a7a2e073 --container ecr_php81_apache --interactive --command "ps aux"
タスクを指定して命令を実行(実際の実行結果例)
$ aws ecs execute-command --cluster Container-Test-Cluster --task 581cb32055144824ad8e314ea3e9a0d5 --container ecr_php81_apache --interactive --command "ps aux" The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. Starting session with SessionId: ecs-execute-command-0d8440147a6931247 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.7 86192 29400 ? Ss 09:53 0:00 apache2 -DFOREG root 17 0.0 0.3 1322756 15032 ? Ssl 09:53 0:00 /managed-agents www-data 22 0.0 0.3 86296 13692 ? S 09:53 0:00 apache2 -DFOREG www-data 23 0.0 0.3 86296 13692 ? S 09:53 0:00 apache2 -DFOREG www-data 24 0.0 0.3 86296 13692 ? S 09:53 0:00 apache2 -DFOREG www-data 25 0.0 0.3 86296 13704 ? S 09:53 0:00 apache2 -DFOREG www-data 26 0.0 0.3 86296 13700 ? S 09:53 0:00 apache2 -DFOREG root 35 0.0 0.6 1408580 25216 ? Sl 09:53 0:00 /managed-agents www-data 48 0.0 0.3 86296 13692 ? S 09:57 0:00 apache2 -DFOREG root 143 0.0 0.5 1250848 21428 ? Sl 10:11 0:00 /managed-agents root 152 0.0 0.0 8592 3248 pts/0 Rs+ 10:11 0:00 ps aux Exiting session with sessionId: ecs-execute-command-0d8440147a6931247.
タスクを指定してコンテナに接続
$ aws ecs execute-command --cluster Container-Test-Cluster --task 581cb32055144824ad8e314ea3e9a0d5 --container ecr_php81_apache --interactive --command "/bin/bash" # pwd /var/www/html # ls -l total 20 -rw-rw-r-- 1 root root 266 May 17 03:05 env.php -rw-rw-r-- 1 root root 237 May 17 03:05 index.php -rw-rw-r-- 1 root root 394 May 17 03:05 mysql.php -rw-rw-r-- 1 root root 391 May 17 03:05 mysql2.php -rw-rw-r-- 1 root root 19 May 17 03:05 phpinfo.php # exit Exiting session with sessionId: ecs-execute-command-04be407417812e929.
■viの利用 以下のとおり、Dockerfileで「vim」をインストールする
RUN apt-get update RUN apt-get install -y \ ↓ RUN apt-get update RUN apt-get install -y \ vim \
■llの利用 以下のとおり、Dockerfileでエイリアスを設定する
RUN echo 'alias ll="ls -al"' >> ~/.bashrc
■RDSへの接続 ※mysqlコマンドを使えるようになることは検証できたが、実際にRDSへ接続するところまでは検証できていない ECS Execからphpコンテナ経由でRDSに接続しようとしたが、mysqlの命令は使えなかった これは「default-mysql-client」をインストールすることで対応できる 調査のために常にインストールしておくといいか。もしくは余計なものは省いて、Cloud9など他の方法で接続するべきか Docker WordPress コンテナから MySQL コマンドが使いたい - かもメモ https://chaika.hatenablog.com/entry/2022/07/25/083000 PHPのコンテナ内からmysqlの命令は使えない
# mysql bash: mysql: command not found
以下のとおり、Dockerfileで「default-mysql-client」をインストールする
RUN apt-get update RUN apt-get install -y \ ↓ RUN apt-get update RUN apt-get install -y \ default-mysql-client \
PHPのコンテナ内からmysqlの命令が使えるようになった
# mysql --version mysql Ver 15.1 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper
■トラブル1 以下のようなエラーが表示されたら、接続に失敗している サービスの「enableExecuteCommand」の設定を有効にしているか、 有効にした後でサービスの更新(デプロイ)を行っているかを確認する また、サービスの更新を行うとタスクのIDが変更されるので、古いIDで接続しようとしていないかも確認する
$ aws ecs execute-command --cluster Container-Test-Cluster --task 2095d9a520f74a6ea003ff117c261cd4 --container ecr_php81_apache --interactive --command "ps aux" The Session Manager plugin was installed successfully. Use the AWS CLI to start a session. An error occurred (InvalidParameterException) when calling the ExecuteCommand operation: The execute command failed because execute command was not enabled when the task was run or the execute command agent isn’t running. Wait and try again or run a new task with execute command enabled and try again.
■トラブル2 「ECS Execを有効化したECSサービスでAuto Scaling グループキャパシティープロバイダーを利用するとタスクが起動できなくなるようです。」とのこと 実際に遭遇したわけでは無いが、今後のためにメモ もし「オートスケーリングによって起動されたタスクに接続できない」ということだとしたら、スケーリングに難ありということで少々厄介のような ECS Execの有効化が原因でECSタスクがPROVISIONING状態から遷移しなくなった話 | DevelopersIO https://dev.classmethod.jp/articles/ecs-exec-cant-use-with-asg-capacity-provider/
■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で管理する ※CodeBuildでのビルド時間を短くするために、PHPのインストールなどを終えた状態のものをベースイメージとして管理する方がいいかもしれない ただしそれだと、PHPのextensionなどを追加インストールする場合に対応が面倒そうではある(プログラマによる対応が難しそう) もしくは「ベースイメージ」「PHPのインストールなどを終えたイメージ」「プログラムも含めたイメージ」を作成し、 以降は原則「プログラムも含めたイメージ」のみを更新していくか ■ベースイメージの作成 Elastic Container Registry → リポジトリを作成 以下の内容でリポジトリを作成 可視性設定: プライベート リポジトリ名: base_php81_apache タグのイミュータビリティ: 有効 「リポジトリを作成」ボタンを押すとリポジトリが作成される 引き続き、リポジトリにプッシュするイメージを作成する docker\base_php81_apache\html\index.php
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>base_php81_apache</title> </head> <body> <h1>base_php81_apache</h1> <p>php:8.1-apache</p> </body> </html>
docker\base_php81_apache\Dockerfile
FROM php:8.1-apache COPY html /var/www/html
以下でビルドする
$ docker image build -t php:base_php81_apache docker/base_php81_apache $ docker image ls
以下で起動する
$ docker container run --name base_php81_apache -p 80:80 -d php:base_php81_apache $ docker container exec -it base_php81_apache bash # ls /var/www/html # exit
http://localhost/ にアクセスし、index.php の内容が表示されることを確認する
$ docker container ls $ docker container rm -f 2c62835f105b
タグ「1.0.0」を付けてプッシュする
$ cd docker/base_php81_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_php81_apache . $ docker image tag base_php81_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php81_apache:1.0.0 $ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php81_apache:1.0.0
ECRでリポジトリ名 base_php81_apache をクリックし、イメージタグとして「1.0.0」が現れていることを確認する ■ベースイメージの利用確認 Docker Composeでの起動を試す docker\ecr_php81_apache\docker-compose.yml
version: '3' networks: compose_network: driver: bridge services: php: container_name: php volumes: - ./docker/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: ./docker/php
docker\ecr_php81_apache\docker\php\Dockerfile
FROM 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php81_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_php81_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_php81_apache\html\index.php
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>base_php81_apache</title> </head> <body> <h1>ecr_php81_apache</h1> <p>123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/base_php81_apache:1.0.0</p> </body> </html>
ファイルを用意できたら以下で起動する
$ cd docker/ecr_php81_apache $ docker-compose build $ docker-compose up -d
http://localhost/ にアクセスし、index.php の内容が表示されることを確認する
$ docker-compose down
■ECR+ECS+Codeシリーズで自動デプロイ: デプロイ用イメージを登録
■プログラムをイメージに含める ※Dockerfileの内容は、本当にこれでいいのかは、改めて確認したい Dockerfileでコピーしたうえで、docker-compose.ymlでファイル同期する…という仕組みにしているが、二重に共有しているのは微妙な気はする プログラムをイメージに含めるようにDockerfileを修正する また、Dockerfile内から上階層のファイルを参照できるように、docker-compose.ymlでbuildの設定を調整する ローカルでの開発に難が出ないように、ボリュームの同期は無くさずに置いておく docker\ecr_php81_apache\docker\php\Dockerfile の最後に以下を追加
COPY docker/php/php.ini /usr/local/etc/php/conf.d/php.ini COPY . /var/www
docker\ecr_php81_apache\docker-compose.yml のbuild部分を調整
build: ./docker/php ↓ build: context: . dockerfile: ./docker/php/Dockerfile
起動を確認しておく
$ cd docker/ecr_php81_apache $ docker-compose build $ docker-compose up -d
http://localhost/ にアクセスし、index.php の内容が表示されることを確認する
$ docker-compose down
■リポジトリの作成 ※AWSコンソールで作業 Elastic Container Registry → リポジトリを作成 ※初めてアクセスした場合、まずは「使用方法」をクリックすると「リポジトリを作成」と同じ画面が表示される 以下の内容でリポジトリを作成(いったん、リポジトリ名を入力する以外は初期値で作成してみる) なお、「可視性設定」と「リポジトリ名」は後から変更できない 可視性設定: プライベート リポジトリ名: ecr_php81_apache タグのイミュータビリティ: 有効 「リポジトリを作成」ボタンを押すとリポジトリが作成される 作成したリポジトリに、タグ「1.0.0」を付けてプッシュする ■イメージをプッシュ
$ cd docker/ecr_php81_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_php81_apache -f docker/php/Dockerfile . $ docker image tag ecr_php81_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php81_apache:1.0.0 $ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php81_apache:1.0.0
ECRでリポジトリ名 ecr_php81_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_php81_apache ports: - 80:80 networks: - compose_network image: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php81_apache:1.0.0
ファイルを用意できたら以下で起動する
$ cd docker/ecr_compose_test $ docker-compose build $ docker-compose up -d
http://localhost/ にアクセスし、index.php の内容が表示されることを確認する
$ docker-compose down
■ECSで手動構築 「Amazon Elastic Container Service(Amazon ECS)」の内容をもとに、以下の指定でECS環境を作ることはできた コンテナ名: ecr_php81_apache イメージ: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php81_apache:1.0.0 なお今回、参照するコンテナ名が ecr_test から ecr_php81_apache に変わるので、サービス自体を作り直した サービスを作り直すとき、すべてのタスクを止めてからでないと以下のエラーになるようなので注意
サービスの作成: Container-Test-Service サービスの作成に失敗しました サービス 作成に失敗: Unable to Start a service that is still Draining.
■ECR+ECS+Codeシリーズで自動デプロイ: CodeBuildでデプロイ用イメージを自動ビルド
上にある「ECR+ECS+Codeシリーズで自動デプロイ: ベースイメージを登録」からの続き ローカルにDockerをビルドする環境が無くても、リポジトリの内容をもとにAWS上でビルド&ECRへのイメージプッシュを行える 主に以下の書籍を参考に検証中 CodeシリーズはP.335から 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_php81_apache:1.0.0 そのイメージをもとに、先の手順でプログラムも含めたApache+PHPの環境を作成した ecr_php81_apache 以下で起動&終了でき、http://localhost/ にアクセスできることを確認した
$ cd docker/ecr_php81_apache $ docker-compose build $ docker-compose up -d $ docker-compose down
■準備: Bitbucketアプリパスワードの作成 今回はBitbucketからデプロイするので、以下を参考にアプリパスワードを発行しておく アプリ パスワード | Bitbucket Cloud | アトラシアン サポート https://support.atlassian.com/ja/bitbucket-cloud/docs/app-passwords/ 個人設定 → アクセス管理 → アプリパスワード 以下のページに遷移できる https://bitbucket.org/account/settings/app-passwords/ Label: Example-ECS 権限: 「リポジトリ」の「読み取り」のみ 「作成」をクリックするとアプリパスワードが表示されるので控えておく ■準備: IAMポリシーの作成 セキュリティ認証情報 → ポリシー → ポリシーの作成 「JSON」タブに以下を入力する AWSアカウントID(123456789012)とイメージ名(base_php81_apache と ecr_php81_apache)は、環境に合わせて調整する イメージ名は、 ベースイメージを参照するためのリポジトリ(base_php81_apache)と、 ビルド済みイメージを保存するためのリポジトリ(ecr_php81_apache)を、 それぞれ2箇所で指定する
{ "Version": "2012-10-17", "Statement": [ { "Sid": "ListImagesInRepository", "Effect": "Allow", "Action": [ "ecr:ListImages" ], "Resource": [ "arn:aws:ecr:ap-northeast-1:123456789012:repository/base_php81_apache", "arn:aws:ecr:ap-northeast-1:123456789012:repository/ecr_php81_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_php81_apache", "arn:aws:ecr:ap-northeast-1:123456789012:repository/ecr_php81_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\ecr_php81_apache\buildspec.yml
version: 0.2 env: variables: AWS_REGION_NAME: ap-northeast-1 ECR_REPOSITORY_NAME: ecr_php81_apache DOCKER_BUILDKIT: "1" phases: install: runtime-versions: docker: 20 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やCodePipelineに渡すためのもの ファイル名は ・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_php81_apache.git(Bitbucketに接続すると入力欄が表示される) ソースバージョン: master 環境 環境イメージ: マネージド型イメージ オペレーティングシステム: Amazon Linux 2 ランタイム: Standard イメージ: aws/codebuild/amazonlinux2-x86_64-standard:4.0 イメージのバージョン: このランタイムバージョンには常に最新のイメージを使用してください 特権付与: (「Docker イメージを構築するか、ビルドで昇格されたアクセス権限を取得するには、このフラグを有効にします」にチェックを入れる) サービスロール: 新しいサービスロール(以前作成したものがあれば「既存のサービスロール」を選択する) ロール名: Container-Test-CodeBuild-Role(以前作成したものがあれば選択する) Buildspec ビルド仕様: buildspecファイルを使用する アーティファクト タイプ: アーティファクトなし キャッシュタイプ: ローカル 少なくとも 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_php81_apache. Reason: exit status 1 「準備: IAMポリシーの作成」で作成したポリシーを紐づける セキュリティ認証情報 → ロール 先の手順中で作成した Container-Test-CodeBuild-Role を選択 「アクセス許可を追加 → ポリシーをアタッチ」をクリック 上の手順中で作成した Container-Test-AccessingECRRepositoryPolicy にチェックを入れ、「ポリシーのアタッチ」ボタンをクリック ■CodeBuild実行 CodeBuild → ビルドプロジェクト → Container-Test 画面上部にある「ビルド開始」ボタンをクリック しばらく待つと最後に以下のようなログが表示され、ビルドが完了した
[Container] 2023/05/12 03:50:00 Phase complete: POST_BUILD State: SUCCEEDED [Container] 2023/05/12 03:50:00 Phase context status code: Message: [Container] 2023/05/12 03:50:00 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED [Container] 2023/05/12 03:50:00 Phase context status code: Message:
ビルドする内容によると思われるが、今回は4〜5分程度で完了した ECRのリポジトリ ecr_php81_apache を確認すると、a322b3d というタグが指定されたイメージを確認できる (buildspec.yml の内容に従って、Bitbucketのコミットしたときに発行されたハッシュの先頭7桁がタグ名に使われる) 作成された以下のイメージを使用して、新しいタスクとしてECSに反映できることを確認する 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecr_php81_apache:a322b3d ※タグの上書き禁止設定(タグのイミュータビリティ)を有効にしている場合、 後の手順でエラーにならないように、この時点でリポジトリに何かしらの変更を加えておくといい ※デプロイできるかの確認のために、この時点でトップページの表示に何かしらの変更を加えておくといい ■ビルドエラー 以下などが参考になりそう 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_php81_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_php81_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_php81_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:
タグの上書き禁止設定(タグのイミュータビリティ)を有効にしていて、すでにビルド済みのイメージが存在するためだった リポジトリに変更を加えてから再度ビルドするか、ビルド済みのイメージを削除してから再度ビルドする ■ビルドエラー: 具体例5 「ビルド開始」をクリックする しばらく待つと、以下のエラーで止まった
[Container] 2023/05/12 03:25:38 Waiting for agent ping [Container] 2023/05/12 03:25:39 Waiting for DOWNLOAD_SOURCE [Container] 2023/05/12 03:25:42 Phase is DOWNLOAD_SOURCE [Container] 2023/05/12 03:25:42 CODEBUILD_SRC_DIR=/codebuild/output/src317942003/src/bitbucket.org/refirio/ecr_php81_apache [Container] 2023/05/12 03:25:44 Phase complete: DOWNLOAD_SOURCE State: FAILED [Container] 2023/05/12 03:25:44 Phase context status code: YAML_FILE_ERROR Message: YAML file does not exist
buildspec.ymlをコミット&プッシュしていなかったので対応 ■ビルドエラー: 具体例6 「ビルド開始」をクリックする しばらく待つと、以下のエラーで止まった
[Container] 2023/05/12 03:30:08 Waiting for agent ping [Container] 2023/05/12 03:30:09 Waiting for DOWNLOAD_SOURCE [Container] 2023/05/12 03:30:12 Phase is DOWNLOAD_SOURCE [Container] 2023/05/12 03:30:12 CODEBUILD_SRC_DIR=/codebuild/output/src787575457/src/bitbucket.org/refirio/ecr_php81_apache [Container] 2023/05/12 03:30:12 YAML location is /codebuild/output/src787575457/src/bitbucket.org/refirio/ecr_php81_apache/buildspec.yml [Container] 2023/05/12 03:30:12 No commands found for phase name: install [Container] 2023/05/12 03:30:12 Processing environment variables [Container] 2023/05/12 03:30:12 Selecting 'docker' runtime version '19' based on manual selections... [Container] 2023/05/12 03:30:14 Phase complete: DOWNLOAD_SOURCE State: FAILED [Container] 2023/05/12 03:30:14 Phase context status code: YAML_FILE_ERROR Message: Unknown runtime version named '19' of docker. This build image has the following versions: 20
buildspec.ymlで「runtime-versions」を「docker: 19」から「docker: 20」に修正
■ECR+ECS+Codeシリーズで自動デプロイ: CodePipelineでイメージを自動デプロイ
■タスク定義ファイル作成 ※この「タスク定義ファイル作成」という手順自体、丸ごと不要だったりするか アプリケーションのリポジトリに taskdef.json を含めても、参照されている気配が無い そもそもこの内容は、プログラムからでは無くAWSコンソールから設定すべき(アプリケーション開発者に触らせるべきものではない)もののような 環境変数の値も、リポジトリ内のコードに含めると変数化している意味が無いような アプリケーションのリポジトリに含めることができたとして、緊急でAWSコンソールから編集した場合のことを考える必要がある ※以下によると「AWSコンソールから管理できるが、必要ならコードでも管理できる。それぞれ一長一短」みたい。ひとまず、タスク定義ファイルは作成しない方針でいいような ECSタスク定義をコンソールから作って後悔した後、コード管理するため最速でJSON登録可能にする超愚直な方法 | DevelopersIO https://dev.classmethod.jp/articles/ecs-task-definition-to-json/ ※引き続き要検証 ★Fargateで再検証するにあたって、ひとまずこの「タスク定義ファイル作成」という手順を丸ごと飛ばして以降の検証を進めている Elastic Container Service → Amazon ECS → タスク定義 → Container-Test-Task 最新のリビジョンのページ内で「JSON」タブに表示される内容をもとに、taskdef.json というファイルを作る その際、イメージの指定部分を「"image": "<IMAGE1_NAME>",」に調整し、さらに以下の項目を削除する ・taskDefinitionArn ・revision ・status ・requiresAttributes ・compatibilities FargateではなくEC2の場合、動的ポートマッピングのために、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_php81_apache\taskdef.json
{ "containerDefinitions": [ { "name": "ecr_php81_apache", "image": "<IMAGE1_NAME>", "cpu": 0, "portMappings": [ { "name": "ecr_php81_apache-80-tcp", "containerPort": 80, "hostPort": 80, "protocol": "tcp", "appProtocol": "http" } ], "essential": true, "environment": [], "environmentFiles": [], "mountPoints": [], "volumesFrom": [], "ulimits": [], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/Container-Test-Task", "awslogs-create-group": "true", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } } } ], "family": "Container-Test-Task", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "networkMode": "awsvpc", "volumes": [], "placementConstraints": [], "requiresCompatibilities": [ "FARGATE" ], "cpu": "1024", "memory": "3072", "runtimePlatform": { "cpuArchitecture": "X86_64", "operatingSystemFamily": "LINUX" }, "registeredAt": "2023-05-12T05:05:28.498Z", "registeredBy": "arn:aws:iam::123456789012:user/refirio-user", "tags": [] }
■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_php81_apache ブランチ名: master 検出オプションを変更する: 「ソースコードの変更時にパイプラインを開始する」にチェックを入れる 出力アーティファクト形式: CodePipeline のデフォルト 「次に」ボタンをクリック ビルドステージを追加する プロバイダーを構築する: AWSCodeBuild リージョン: アジアパシフィック(東京) プロジェクト名: Container-Test(選択対象に表示されるので選択する) ビルドタイプ: 単一ビルド 「次に」ボタンをクリック デプロイステージを追加する デプロイプロバイダー: Amazon ECS リージョン: アジアパシフィック(東京) クラスター名: Container-Test-Cluster サービス名: Container-Test-Service イメージ定義ファイル: imagedefinitions.json 「次に」ボタンをクリック レビュー 「パイプラインを作成する」ボタンをクリック 「成功」と表示されるのを確認する 引き続き、各処理がそれぞれ実行されていくのを確認する 「Source」はすぐに「成功しました」となった その2〜3分後くらいに、「Build」が「成功しました」となった その4〜5分後くらいに、「Deploy」が「成功しました」となった 合計10分ほどでデプロイが完了したが、本番反映自体は3〜4分ほどでされていた(以降は不要なタスクやターゲットグループの削除) どんなにイメージのビルド時間を短くしても、デプロイ完了までは5〜6分程度かかるかもしれない(デプロイ時間については、後述の「デプロイ時間の短縮」も参照) 以降は、プログラムの修正をmasterブランチにコミット&プッシュするだけで、処理が開始されデプロイされる (developブランチの内容をmasterにマージ&プッシュとしても、同様に処理される) プッシュすると、すぐにCodePipelineの「Source」処理が始まる なお、本番反映時に30秒程度、新旧が混在する状態が続く これは恐らく標準デプロイ(ローリングアップデート)の仕様で、避けるためにはBlue/Greenデプロイにする必要があると思われる ■問題の修正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コンソール上で動的ポートマッピングに対応させてデプロイを行っておいてから再度試す (デプロイ前の時点で動的ポートマッピングに対応している必要があるのかもしれない。そもそも今回は taskdef.json が参照されていないようにも思う)
■ECR+ECS+Codeシリーズで自動デプロイ: 環境変数を渡す
■機密情報以外の環境変数を渡す Elastic Container Service → Amazon ECS → タスク定義 「Container-Test-Task」にチェックを入れて「新しいリビジョンの作成」をクリック (以下、前回タスクを作成した時の内容をベースに入力する) もともと追加されている「ecr_php81_apache」に対し、必要な箇所を調整 今回は「環境変数」にある「環境変数を追加」をクリックし、以下のように入力する キー 値のタイプ 値 TEST_VALUE1 値 TEST TEST_VALUE2 値 テストメッセージ! TEST_VALUE3 値 This is a test message! 上記で更新してデプロイすると、各値がコンテナに渡されるようになる 各値は環境変数に格納されるので、例えばPHPの場合は以下のようにすると参照できる
echo $_ENV['TEST_VALUE1'];
■機密情報を渡す RDSへの接続情報などを渡したい場合など、機密情報を扱う場合は Secrets Managerを使用するといい 詳細は後述の「ECR+ECS+Codeシリーズで自動デプロイ: RDSに接続する」を参照 AWSのParameter StoreとSecrets Manager、結局どちらを使えばいいのか?比較 - Qiita https://qiita.com/tomoya_oka/items/a3dd44879eea0d1e3ef5 もしくは後述の「環境変数をファイルから読み込む」なら、アクセス制限下のファイルから読み込むので、機密情報を直接記載しても問題無さそう
■ECR+ECS+Codeシリーズで自動デプロイ: 環境変数をファイルから読み込む
ECS(Fargate)でLaravelの環境変数の設定方法 - Qiita https://qiita.com/urushibata/items/84e6701e7fbf453d2fe7 プログラムの設定(.env)はタスク定義の環境変数が本筋か …と思ったが、変数が多いとメンテナンスがツラくなる .envをS3に置いて参照させることができるようになっているので、この「環境ファイルを追加」を使うのが良さそう RDSの情報をSecrets Managerで扱うべきかどうかは確認しておきたい (.envを非公開バケットに置くのなら、値を直接書いても問題無さそうな) [アップデート]ECS on EC2で環境変数の設定がS3から参照できるようになりました | DevelopersIO https://dev.classmethod.jp/articles/ecs_ec2_env_s3/ Fargateの環境変数をs3においたenvファイルから取得する方法 - Qiita https://qiita.com/GoogIeSensei/items/2b16b06c59ac202639e5 ■S3にバケットを作成 S3 → バケットを作成 バケット名: ecs-example-env AWSリージョン: アジアパシフィック(東京) このバケットのブロックパブリックアクセス設定: パブリックアクセスをすべて ブロック ※ファイルアップロード先のバケットとは別に作成するべきか ※バケット名は「案件名」+「-env」にするか ■S3に.envファイルを作成 production.env
S3_VALUE1=S3 S3_VALUE2=S3メッセージ! S3_VALUE3=This is a S3 message!
作成したバケットの直下に配置した https://ecs-example-env.s3.ap-northeast-1.amazonaws.com/production.env ■ポリシーの作成 ポリシーの作成で「JSON」タブに以下を入力する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::ecs-example-env/production.env" ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketLocation" ], "Resource": [ "arn:aws:s3:::ecs-example-env" ] } ] }
以下の内容でポリシーを作成する 名前: Example-GettingEnvironmentForECS 説明: Policy to get Environment for ECS ■タスク実行ロールの作成 ※ロール ecsTaskExecutionRole を作成済みの場合、この手順は飛ばす 以下の内容でロールを作成する 信頼されたエンティティを選択 信頼されたエンティティタイプ: AWSのサービス ユースケース 他のAWSのサービスのユースケース: Elastic Container Service → Elastic Container Service Task を選択 「次へ」ボタンをクリック 許可を追加 「AmazonECSTaskExecutionRolePolicy」を検索してチェックを入れる 「次へ」ボタンをクリック 名前、確認、および作成 ロール名: ecsTaskExecutionRole 「ロールを作成」ボタンをクリック ■タスク実行ロールにアクセス権限を付与 上の手順で作成した ecsTaskExecutionRole を選択 「許可を追加 → ポリシーをアタッチ」をクリック 上の手順中で作成した Example-GettingEnvironmentForECS にチェックを入れ、「ポリシーのアタッチ」ボタンをクリック ■ファイルの情報を読み込ませるためにタスクを更新 タスク定義に新しいリビジョンを作成する 「Example」にチェックを入れて「新しいリビジョンの作成」をクリック (以下、前回タスクを作成した時の内容をベースに入力する) 「php」コンテナの「環境変数」にある「環境ファイルを追加」をクリックし、一例だが以下のように入力する ロケーション: arn:aws:s3:::ecs-example-env/production.env 上記で更新してデプロイすると、各値がコンテナに渡されるようになる 各値は環境変数に格納されるので、例えばPHPの場合は以下のようにすると参照できる
echo $_ENV['S3_VALUE1'];
■ファイルを更新する場合 S3バケットの production.env を上書きで更新するだけでは反映されない 改めてタスクを更新してデプロイする
■ECR+ECS+Codeシリーズで自動デプロイ: RDSに接続する
■Cloud9を作成 RDSにユーザやテーブルを作成するため、Cloud9を作成しておく (運用はコンテナなので、作業用にFargateやEC2を作成する…が、一時的に必要になるだけなのでCloud9を使う) Name: Test Description: (空欄のまま) Environment type: New EC2 instance 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な)サブネットを選択 Cloud9のEC2には、以下のセキュリティグループが自動で割り当てられていた (EC2インスタンスの一覧から確認できる。このセキュリティグループは後から使用する) sg-04b8e304c2064b14d Environments一覧の「Cloud9 IDE」列の「Open」から接続できる 「Welcome」タブなどが開くが、「bash」タブからコマンドを入力できることを確認する ■パラメータグループの作成 パラメータグループファミリー: mariadb10.6 グループ名: container-test 説明: for Container-Test 以下のとおりパラメータを設定する 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.6.10 テンプレート: 開発/テスト DBインスタンス識別子: container-test マスターユーザー名: admin マスターパスワード: qazwsxedc DBインスタンスクラス: バースト可能クラス(t クラスを含む) db.t3.micro ストレージタイプ: 汎用(SSD) ストレージ割り当て: 20GiB ストレージの自動スケーリング: (チェックを外す) マルチAZ配置: なし コンピューティングリソース: EC2コンピューティングリソースに接続 ※「EC2コンピューティングリソースに接続しない」だと、後からセキュリティグループを調整してもCloud9から接続できなかった。また検証したい EC2インスタンス: (上の手順で作成してCloud9のEC2インスタンスを選択する) Virtual Private Cloud: (初めから選択済みになっている)※「EC2コンピューティングリソースに接続」にすると、VPCを選択できない?選択したEC2に合わせて適切に設定される? DBサブネットグループ: 自動セットアップ(初めから選択済みになっている) 既存のVPCセキュリティグループ:(変更せずだが、「rds-ec2-1」が自動的に追加される) 最初のデータベース名: container DBパラメータグループ: container-test オプショングループ: default:mariadb-10-6 以下のセキュリティグループが作成&割り当てられていた ec2-rds-1 ... Cloud9に割り当てられていた rds-ec2-1 ... RDSに割り当てられていた ■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.xxxxx.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 8 Server version: 10.6.10-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.6.10-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.xxxxx.ap-northeast-1.rds.amazonaws.com -u webmaster -p Enter password: > CREATE TABLE test_table( > id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID', > text VARCHAR(255) NOT NULL COMMENT 'テキスト', > PRIMARY KEY(id) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT 'テスト'; > INSERT INTO test_table(text) VALUES('Test1'); > INSERT INTO test_table(text) VALUES('Test2'); > SELECT * FROM test_table; +----+-------+ | 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」を選択するといい) データベース: (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がタスクを実行するときのロールを作成する ※ロール ecsTaskExecutionRole を作成済みの場合、この手順は飛ばす セキュリティ認証情報 → ロール → ロールを作成 信頼されたエンティティを選択 信頼されたエンティティタイプ: 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」にチェックを入れて「新しいリビジョンの作成」をクリック (以下、前回タスクを作成した時の内容をベースに入力する) もともと追加されている「ecr_php81_apache」に対し、必要な箇所を調整 今回は「環境変数」にある「環境変数を追加」をクリックし、以下のように入力する キー 値のタイプ 値 RDS_HOST ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:host:: RDS_DBNAME ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:dbname:: RDS_USERNAME ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:username:: RDS_PASSWORD ValueFrom arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:dev/container-test/Mysql-bcmXxP:password:: 上記で更新すると、各値がコンテナに渡されるようになる デプロイすると、phpinfo() の「Environment」に以下が現れた RDS_HOST: container-test.xxxxx.ap-northeast-1.rds.amazonaws.com RDS_DBNAME: container RDS_USERNAME: (RDS上に作成したユーザー) RDS_PASSWORD: (RDS上に作成したパスワード) 環境変数にはarnの値が表示されて、実際のパスワードを得るにはSDKなどで独自に処理が必要なのかと思いきや、普通に環境変数へ展開された これだと環境変数に普通に接続情報を書くのと変わらないような …と思ったが、taskdef.json に直接接続情報を書くと「リポジトリ内に機密情報を含めている」状態になるので、それを避けるための措置か phpinfo() の内容は絶対に流出させてはならない(もともと流出させるべきでは無い内容だが) 以下などを参考に、本番環境では phpinfo() を使用できないようにするなどしておくべきか php.iniで危険な関数を無効化する | 晴耕雨読 https://tex2e.github.io/blog/php/set-disable-functions ■PHPプログラムからの接続確認 Dockerfileを調整し、PHPからMySQLへ接続するための命令を追加インストールする 具体的には、ecr_php81_apache\docker\php\Dockerfile を以下のように修正する(「pdo_mysql」と「mysqli」を追加している)
RUN docker-php-ext-install gd mbstring intl zip ↓ RUN docker-php-ext-install gd pdo_mysql mysqli mbstring intl zip
デプロイして、PHPからMySQLへ接続する命令を書いたページへアクセスすると、データベースに接続できた 具体的なコードは以下のとおり
<?php try { $pdo = new PDO( 'mysql:dbname=' . $_ENV['RDS_DBNAME'] . ';host=' . $_ENV['RDS_HOST'], $_ENV['RDS_USERNAME'], $_ENV['RDS_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シリーズで自動デプロイ: ベースイメージのセキュリティチェックについて考察
イメージの脆弱性スキャンを行うと、Criticalの「CVE-2019-19814」が現れた 何とかしようとして何とかならなかったときのメモ ■試したこと 「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... ■調査 軽量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_php81_apache タグのイミュータビリティ: 有効 「リポジトリを作成」ボタンを押すとリポジトリが作成される 引き続き、リポジトリにプッシュするイメージを作成する ■イメージ作成1 docker\debian_php81_apache\Dockerfile
FROM debian:bullseye
以下でビルドする
$ docker image build -t php:debian_php81_apache docker/debian_php81_apache $ docker image ls
タグ「1.0.0」を付けてプッシュする
$ cd docker/debian_php81_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_php81_apache . $ docker image tag debian_php81_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.0.0 $ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.0.0
ECRでリポジトリ名 debian_php81_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_php81_apache\Dockerfile
FROM debian:bullseye-slim
以下でビルドする
$ docker image build -t php:debian_php81_apache docker/debian_php81_apache $ docker image ls
タグ「1.1.0」を付けてプッシュする
$ cd docker/debian_php81_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_php81_apache . $ docker image tag debian_php81_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.1.0 $ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.1.0
ECRでリポジトリ名 debian_php81_apache をクリックし、イメージタグとして「1.1.0」が現れていることを確認する 上記イメージに対してスキャンを実行すると、44件の警告が表示された つまり変化せず ■イメージ作成3 以下をもとに Dockerfile とその関連ファイルを調整 https://github.com/docker-library/php/tree/master/8.1/bullseye/apache
$ docker image build -t php:debian_php81_apache docker/debian_php81_apache $ docker image ls
タグ「1.2.0」を付けてプッシュする
$ cd docker/debian_php81_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_php81_apache . $ docker image tag debian_php81_apache:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.2.0 $ docker image push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/debian_php81_apache:1.2.0
ECRでリポジトリ名 debian_php81_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シリーズで自動デプロイ: 環境を削除
Secrets Manager → dev/Container-Test-RDS/Mysql → アクション → シークレットを削除する からシークレットを削除(即座に削除は完了しない。最低7日間は情報が残されている) RDS → データベース から「container-test」を削除 RDS → パラメータグループ から「container-test」を削除 CodePipeline → パイプライン → パイプライン から「Container-Test」を削除 CodeBuild → ビルドプロジェクト → ビルドプロジェクト から「Container-Test」を削除 Elastic Container Registry → リポジトリ から、不要になったリポジトリがあれば削除しておく Cloud9 → Your environments から、不要になったCloud9を削除 CloudWatch → ログ → ロググループ から「/ecs/Container-Test-Task」を削除 以降は「Amazon Elastic Container Service(Amazon ECS)」の「環境の削除」の手順で削除 (ターゲットグループはいくつも作成しているので、ECS用に作ったものはすべて削除する)
■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 Simple Email Service https://docs.aws.amazon.com/ja_jp/ses/latest/dg/tips-and-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 Eメール送信のベストプラクティス(PDF) https://media.amazonwebservices.com/jp/wp/AWS_Amazon_SES_Best_Practices.pdf 以下、実際に試した内容のメモ ■ドメインの登録 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レコードが表示されている このレコードを登録する必要がある…かと思ったが、Route53を確認すると登録済みになっていた(Route53にドメインが存在する場合、自動で設定されるのかもしれない) SESの画面を再読み込みすると、どちらも「検証済み」になっていた また数分待つと「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 時間かかることがあります。
翌日に以下のメールが届き、送信制限は解除された
平素は Amazon Web Services をご利用いただき、誠にありがとうございます。 このたびは、送信制限の引き上げ申請をご送信いただき、ありがとうございます。 新たな送信クォータは、1 日あたり 50,000 メッセージとなります。 新たな最大送信レートは、毎秒 14 メッセージです。 また、お客様のアカウントを Amazon SES サンドボックスから移動いたしました。 この引き上げは、アジアパシフィック (東京)リージョンにおいて、直ちに有効になります。 Amazon SES コンソールの送信統計情報のページで、または GetSendQuota API を使って、お客様のアカウントの現在の送信レートと送信クォータを確認することができます。 Amazon SES をご利用いただくうえで、下記の点にご留意ください。 - Amazon Web Services の規約( http://aws.amazon.com/aup/ )に準拠し、Amazon SES Service のサービス条件 セクション 22 ( http://aws.amazon.com/service-terms/ )をご確認ください。 - メール送信の明示的なリクエストがあった受信者に、質の高いコンテンツを送信してください。 詳細に関しては、下記のリンクをご参照ください。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/tips-and-best-practices.html - バウンスと苦情に対応するプロセスを設定してください。 詳細に関しては、下記のリンクをご参照ください。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/monitor-sending-activity.html - 複数のアカウントがある場合、新しいアカウントからは、既存のアカウントとは異なるタイプの E メールを送信してください。 詳細に関しては、下記のリンクをご参照ください。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/Welcome.html - Amazon SES のメールボックスシミュレーターを使用することで、テスト送信中にアカウントへ悪影響を及ぼすことなく、システム機能をテストできます。 詳細に関しては、下記のリンクをご参照ください。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html - 必要となる前に、送信制限の引き上げを申請してください。 詳細については、下記のリンクをご参照ください。 https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/manage-sending-limits.html - Amazon SES では、実際に使用した分についてのみ料金が発生します。 サブスクリプションや契約交渉、最低料金はありません。 詳細については、下記のリンクをご参照ください。 https://aws.amazon.com/jp/ses/pricing/ Amazon Web Servicesをご利用いただき、誠にありがとうございます。
再度PHPMailerからメール送信テストを行うと、無事にメールが送信できた またGmailからメールのヘッダを確認すると、以下のとおりSPF&DKIMともに「PASS」になっていた
SPF: PASS(IP: 23.251.234.10) DKIM: 'PASS'(ドメイン: refirio.net)詳細
■送信制限の解除(トラブル事例) 当初は上に記載の内容で申請が通っていたが、2023年ごろから以下の返信が来るようになった より詳細な情報を提出する必要があるとのこと
このたびは、送信制限の申請をいただきありがとうございます。 残念ながら現時点ではお客様のユースケースについて十分な情報がないため、この申請を承認することはできません。 Amazon SES の使用計画について詳しい情報をご提供いただければ、申請が承認される可能性があります。 返信の際に、お客様のメール送信プロセスや手順について、可能な限り詳しい情報を記載してください。 たとえば、メールを送信する頻度、受信者リストのメンテナンス方法、バウンス、申し立て、解除申請の管理方法についてご説明ください。 送信する予定のメールのサンプルをご提供いただければ、お客様が高品質のコンテンツを送信していることを確認するために役立ちます. この情報を受け取り次第、お客様の申請を審査させていただきます。 24時間以内にご連絡をいたします。 必要な情報をすべてご提示いただいた場合は、24時間以内に申請を承認いたします。 追加で情報が必要な場合は、申請の実装に長くかかる可能性がございますことをご了承ください。
以下を返信して申請が通ったことはある
現在他社のサーバで運用しているサービスについて、AWSへの移行をしております。 それに当たり、メール送信周りはすべてSESを利用したいと考えております。 メールの利用用途は、以下のとおりです。 ・会員登録時における、システムからユーザへの自動返信 ・ユーザへのお知らせ ・システムエラー発生時、運営への通知 ・運営へのサーバ稼働レポート 送信セキュリティについては、SPFレコードおよびDKIMを利用します。 なお、存在しない等不正なメールアドレスへの対処については、次回以降送信しない等の措置が実施されます。
■送信制限の解除(昔の手順) 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日経っても変化がないのでクローズされたケースを再開し、以下の問い合わせをした 一応日本語と英語を併記した
お世話になります。 > アカウントはサンドボックス環境から移動しましたので、今後受信者のメールアドレスを承認する必要はありません。 対応ありがとうございます。 しかしながら、以下の画面には「Your Amazon SES account has "sandbox" access in region US East (N. Virginia).」と表示されたままです。 https://console.aws.amazon.com/ses/home?region=us-east-1#dashboard: また、以下の画面から送信テストを行う場合も、受信者のメールアドレス承認が必要なままです。 https://console.aws.amazon.com/ses/home?region=us-east-1#verified-senders-email: こちらで他にも何らかの手続が必要でしょうか? それとも、反映までにはまだ時間がかかるのでしょうか? よろしくお願いいたします。 - - - - - Dear Amazon Web Services, > アカウントはサンドボックス環境から移動しましたので、今後受信者のメールアドレスを承認する必要はありません。 Thank you for support. However, 'Your Amazon SES account has "sandbox" access in region US East (N. Virginia).' is still displayed on the following page. https://console.aws.amazon.com/ses/home?region=us-east-1#dashboard: And, When I try out the transmission test from the page below, the recipient's email address approval is still required. https://console.aws.amazon.com/ses/home?region=us-east-1#verified-senders-email: Do I need to do some other steps? Or, Does it take to be reflected time? Thanks.
半日程度で以下の返信があり、制限は解除された 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でメールを送信 ※PHPMailerでのメール送信については、Etcetera.txt の「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/ ■サブドメインでのメール送信 例えば refirio.net のドメインからメールを送信できるようにした場合、 自動的に stg.refirio.net などサブドメインからも送信できるようになる SESで承認したドメインのサブドメインを送信元アドレスとしてメールを送信してみる | DevelopersIO https://dev.classmethod.jp/articles/send-email-with-subdomain-of-verified-domain-in-ses-as-source-ad... 「上位ドメインを一つSESで承認しておけば、環境や用途ごとに異なるサブドメインをメール送信に使えるのは便利ですね。」 ■メールの一括送信 Amazon SESでメールを一括送信したい時の留意点 | DevelopersIO https://dev.classmethod.jp/articles/points-to-keep-in-mind-when-you-want-to-send-emails-in-bulk-with... Laravel + Amazon SES でクリック率が分かるメルマガを一斉送信する - console dot log https://blog.capilano-fw.com/?p=9186 SDK経由で、メールの一括送信ができる ただし「1回のAPI実行でのメッセージ送信可能数は最大50通」という制限があるので注意 APIを複数回に分けて叩く必要があるようなので、それなら独自にキューで送信する仕組みを作成する方が自由度が高いか また一括送信する場合、メールを見たユーザが一斉にアクセスが来るとサーバ負荷が上がるので、徐々に送信することも考えたい ■Return-Pathの設定 何もしなければ、以下のようなReturn-Pathになっていた (SPFのために、Amazon所有のドメインが使用されるらしい) Return-Path: <012345678901cee8-57b4ef59-99a0-4548-b220-f14c687d28f2-000000@ap-northeast-1.amazonses.com> 以下は参考になるかもしれないが、現状未検証 AWS SES で検証済のドメインとメールアドレスが競合しているときのカスタム MAIL FROM での書き換え #AWS - Qiita https://qiita.com/ngyuki/items/63e0e57cab2cba266eef Amazon SES でメール送信するときのベストプラクティスまとめ(2020年10月) | DevelopersIO https://dev.classmethod.jp/articles/ses-send-mail-best-practices-summary/ Amazon SESのE メール形式 - Amazon Simple Email Service https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-concepts-email-format.html 到達率に影響すると思われるので、それとは関係なく設定しておくべきか…と思うが、設定するとバウンスメールの受け取りに悪影響があるか そもそも、後述の「バウンスメールの設定」を行うなら不要か 以下の公式解説では「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/ 以下は実際の設定例 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 対象 名前 条件 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SES refirio.net SES Reputation.BounceRate 1時間内の1データポイントのReputation.BounceRate > 4 SES refirio.net SES Reputation.ComplaintRate 1時間内の1データポイントのReputation.ComplaintRate > 0.08 SES refirio.net SES Send 1時間内の1データポイントのReputation.Send > 500 SES refirio.net SES Reject 1時間内の1データポイントのReputation.Reject > 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ■SPFレコードの確認 SPFレコードは存在しないようだが、これについては以下に解説がある Amazon SES でメールを送る場合、DNS に SPF 設定は不要だという話 #AWS - Qiita https://qiita.com/koseki/items/4f291579cf4ceb9f9e47 今回受信したメールを確認すると、Return-Pathは以下のような値になっていた Amazonのドメインから送信しているので、別途設定しなくても問題無いのだと思われる。なおGmailで確認すると、上に記載したとおりメールヘッダには「SPF: PASS」とある Return-Path: <0106018bdb917059-9eff61c1-675b-43a5-be62-8c6e05824c49-000000@ap-northeast-1.amazonses.com> SPFレコードについては、以下のページではSPFは不要と書かれているが、 Amazon SES でメールを送る場合、DNS に SPF 設定は不要だという話 - Qiita https://qiita.com/koseki/items/4f291579cf4ceb9f9e47 AWS SESで信頼性の高いメール送信(SPF, DKIM, DMARC) with Terraform - 電気ひつじ牧場 https://cha-shu00.hatenablog.com/entry/2022/03/06/175823 以下のページではSPFは必要と書かれている (古い記事なので現状とは異なるかもしれないが) AWS SESでのメール送信時にSPFの設定は必要だよ! - Qiita https://qiita.com/seiketkm/items/a4ddef03b7852353f554 ■DMARCを設定 以下のページを参考に、DMARCを設定してみる Amazon SES にSPF、DKIM、DMARC設定と、サンドボックスを解除してメール送信してみた | DevelopersIO https://dev.classmethod.jp/articles/amazon-ses-set-up-spf-dkim-dmarc-and-unlocked-sandbox/ 解説によると、TXTレコードを1個追加するだけらしい Complying with DMARC authentication protocol in Amazon SES - Amazon Simple Email Service https://docs.aws.amazon.com/ses/latest/dg/send-email-authentication-dmarc.html 上記公式ページによると、以下のレコードを追加すればいいらしい Name: _dmarc.example.com Type: TXT Value: "v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@example.com" ただしドメイン名は修正する必要があるので、実際は以下のレコードとなる Name: _dmarc.refirio.net Type: TXT Value: "v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@refirio.net" DNS設定後、少し時間をおいて以下のとおり反映されていることを確認する
$ dig _dmarc.refirio.net any ;; ANSWER SECTION: _dmarc.refirio.net. 300 IN TXT "v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@refirio.net"
PHPMailerからメールを送信してテスト メールヘッダにDMARCの項目が現れた(反映までは5分ほどかかると思われる) SPF: PASS(IP: 23.251.234.3) DKIM: 'PASS'(ドメイン: refirio.net) DMARC: 'PASS' AmazonSESでのDMARC設定は容易なので、SESの初期設定時についでに対応しておくと良さそう またこの場合、dmarcreports@refirio.net でメールを受信できるようにしておく必要があるので注意 このアドレスを refirio.net 以外のドメインにしたい場合、つまり認証を設けたいドメインと通知先のドメインが異なる場合、追加のDNSレコードが必要となる DMARC 詳細仕様-2 | なりすまし対策ポータル ナリタイ https://www.naritai.jp/guidance_record.html > DMARC レポートの受信を外部に委託する場合、すなわち DMARC レコードを設定したドメインと関係の無いドメインを rua や ruf に指定する場合には、相互の関連性を示す必要があります。具体的には、レポートの委譲先のドメインに、委譲元のドメインの情報を示す必要があります。例えば、example.jp ドメインの DMARC レコードで、rua (集約レポート) の宛先として example.com を指定する場合、委譲先の example.com ドメイン側で以下の TXT 資源レコードの設定が必要になります。 > example.jp._report._dmarc.example.com IN TXT "v=DMARC1" > sp パラメータは、全てのサブドメインに対する DMARC ポリシーを指定します(オプションです)。設定する値は、p パラメータと同じです。 > v パラメータは、バージョン番号を示しますが現状では v=DMARC1 という固定文字列になります。DNS の TXT レコードは、DMARC レコード以外の用途にも利用されますので、他のレコード (SPF レコードなど) と区別するために、このバージョン番号を DMARC レコードの先頭に記述する必要があります。 例えば example.com のドメインで通知を受け取りたい場合、example.com のDNS側で以下のように登録する (これが無いから通知が一切届かない…ということは無いようだが)
refirio.net._report._dmarc.example.com IN TXT "v=DMARC1"
■ChatGPTによるDKIMの解説1 digコマンドを使用してDNSの登録内容を調査した結果を解説します あなたが実行したコマンドは以下の通りです: $ dig 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6._domainkey.refirio.net any このコマンドの実行結果は以下の通りです: ;; ANSWER SECTION: 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6._domainkey.refirio.net. 300 IN CNAME 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6.dkim.amazonses.com. 解説 ・ドメイン名: 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6._domainkey.refirio.net これはDKIM (DomainKeys Identified Mail) のための特定のレコードを表します。 DKIMは、電子メールメッセージが特定のドメインから実際に送信されたことを確認するための方法です。 ・TTL (Time to Live): 300 この数字は、DNSレコードがDNSサーバーのキャッシュに保持される秒数を表します。 この場合、300秒(5分)後にキャッシュが更新されることを意味します。 ・レコードタイプ: IN CNAME INはインターネットを意味し、CNAMEはCanonical Name(別名)レコードを示します。 CNAMEレコードは、一つのドメイン名を別のドメイン名に関連付けるために使用されます。 ・ターゲットドメイン名: 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6.dkim.amazonses.com このCNAMEレコードは、refirio.netドメインのDKIMレコードをAmazon SES(Amazon Simple Email Service)のDKIMレコードに関連付けています。 これにより、refirio.netから送信される電子メールがAmazon SESを介してDKIMで署名されることを示しています。 結論 このDNSの登録内容は、refirio.netドメインの電子メールがAmazon SESを使用してDKIM署名されるように設定されていることを示しています。 これにより、メールの認証と信頼性が向上し、スパムやフィッシングから保護される効果があります。 ■ChatGPTによるDKIMの解説2 digコマンドを使ってDNSの登録内容を調査した結果を解説します。 あなたが実行したコマンドは以下の通りです: $ dig 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6.dkim.amazonses.com any このコマンドの実行結果は以下の通りです: ;; ANSWER SECTION: 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6.dkim.amazonses.com. 300 IN TXT "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxJC52Rh2Ei+2l18sK9ocryAgMob/VnSnYvQhS6tiJ4Ij1MNRHjmdtTjIVwfQkKhA0ahVi5rjaEYpvn1SG8yaOU7yOxchEkfelp2xVKM/Oym/PJC3dEVovDlOT0vJN6XzLH80EVvE2CW96MQn8KJVIb8n8jnCB2sdukguT2rsHR/XGkGMFoj0ZFBxAXKwf3fETDK/TSWNHy/SjvqzR" "gOSr/VCJm3ijQxD0i/VET1r/oufplbDtdgpySvjTWn+7yE9A9Di8c/QP/6lm3PHvWwv4qKrvAZaXyHYU+OZWdRCMUTPkq9LUajS1tZdCSQ9e86ALxtBsOjNVx+Th5L5GxixFwIDAQAB" 解説 ・ドメイン名: 6xtcynuykbn5xmx2o2o2mkxf2fjsblk6.dkim.amazonses.com これはAmazon SES (Amazon Simple Email Service) のDKIM (DomainKeys Identified Mail) 設定の一部です。 DKIMは、電子メールの送信者がメールを署名して、受信者がそのメールが改ざんされていないことを確認できるようにする技術です。 ・TTL (Time to Live): 300 この数字は、DNSレコードがDNSサーバーのキャッシュに保持される秒数を表します。 この場合、300秒(5分)後にキャッシュが更新されることを意味します。 ・レコードタイプ: IN TXT INはインターネットを意味し、TXTはテキストレコードを示します。 TXTレコードは、ドメインに関する任意のテキスト情報を提供するために使用されます。 ・DKIM公開鍵: 表示されている長い文字列(p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...)は、DKIMの公開鍵を表します。 この公開鍵は、送信者がメールに付けたデジタル署名を検証するために使用されます。 署名は、メールの送信者がそのドメインの所有者であること、およびメールが途中で改ざんされていないことを保証します。 結論 このDNSの登録内容は、Amazon SESを使用して電子メールを送信する際にDKIM署名を利用する設定を示しています。 この設定は、メールの認証と信頼性を向上させ、スパムやフィッシングから保護するために重要です。 公開鍵は、受信したメールの署名が有効かどうかを確認するために使われます。 ■ChatGPTによるDKIMの解説3 メールヘッダに含まれるDKIM-Signatureフィールドについて解説します。 DKIM (DomainKeys Identified Mail) は、電子メールの送信者が自分のドメインからメールが送信されたことを確認するための技術です。 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=6xtcynuykbn5xmx2o2o2mkxf2fjsblk6; d=refirio.net; t=1700195823; h=Date:To:From:Subject:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding; bh=41h2rsirndfR9S9Ure3fglQqn/D8jDSeJVCfSP2ctkQ=; b=eta1GRUx9yJJX8ZWMFF0EzmZI4/DKljgOAOiNvnZCu8qMAxRXaHWK8Qf5vMOSLqV dkkKgjmV94cbAg9bk0k7Z0b2EV90PedMNICGYpcARTAYCKGmSZY+iQ0oCS6Hd0oWtZd 2JUF2jctKoAa/Um979Iq3wjAjzQ6wlpa2pScmLNrop4BxHH/jzu3OvLUptDRUbheWRl wdZeJ3JtCqf4eim6Ejdy/fotwLCpIRaILGUsgY9PsvzgInDStRlzqR/Iea1vwqy747X RGsX6z994HpalvlhDY2eHRVvQrcEK0tcI6TV+ZOe61cThf48xlfVs+Ujqx6HEjVUQDN GeZRdcnrzg== DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=zh4gjftm6etwoq6afzugpky45synznly; d=amazonses.com; t=1700195823; h=Date:To:From:Subject:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:Feedback-ID; bh=41h2rsirndfR9S9Ure3fglQqn/D8jDSeJVCfSP2ctkQ=; b=OCOTofp7OCpiwU4PEFrH4cyRewFIaTJOzn0JwVXjpVI7yDN5zF3+bIudfV80Tx3I 8nrORzEU9IJrkzCaZjp2uBriHnVgdAhyAqNbK6FD287yapojW4Y6pspVDU/KpTQqUQ5 3toxL2WodaoX7nTmTnQEZYkw+aIccO7ub7Q5EM2w= このメールには2つのDKIM署名が含まれています。 DKIM署名の構成要素 ・バージョン (v): v=1は、DKIMのバージョンを示します。 ・署名アルゴリズム (a): a=rsa-sha256は、署名の生成にRSA-SHA256アルゴリズムが使用されたことを意味します。 ・クエリメソッド (q): q=dns/txtは、公開鍵をDNSのTXTレコードから取得することを示します。 ・キャノニカライゼーション (c): c=relaxed/simpleは、メッセージのヘッダと本文の処理方法を示します。relaxedは、ヘッダーの余分な空白や改行を無視することを意味し、simpleは本文をそのままの形で使用することを意味します。 ・セレクタ (s): 例えばs=6xtcynuykbn5xmx2o2o2mkxf2fjsblk6は、使用する特定のDKIMキーを識別します。 ・ドメイン名 (d): d=refirio.netやd=amazonses.comは、署名の所有者のドメインを示します。 ・タイムスタンプ (t): t=1700195823は、メールが署名されたUNIXタイムスタンプです。 ・署名されたヘッダフィールド (h): これは、署名の一部として取り込まれるヘッダフィールドを示します。 ・本文ハッシュ (bh): bh=41h2rsirndfR9S9Ure3fglQqn/D8jDSeJVCfSP2ctkQ=などは、メール本文のハッシュ値です。 ・署名 (b): この長いエンコードされた文字列は、上記のすべての要素を含む実際のデジタル署名です。 結論 これらのDKIM署名は、メールがrefirio.netとamazonses.comのドメインから正当に送信され、途中で改ざんされていないことを証明します。 メールが配信されると、受信者のメールサーバーは、これらのドメインのDNSレコードを参照して公開鍵を取得し、署名を検証します。 このプロセスは、メールの真正性と完整性を保証するのに役立ちます。 ■ChatGPTによるDMARCの解説 digコマンドを使ってDMARCの設定内容を調査した結果を解説します。 あなたが実行したコマンドは以下の通りです: $ dig _dmarc.refirio.net any このコマンドの実行結果は以下の通りです: ;; ANSWER SECTION: _dmarc.refirio.net. 300 IN TXT "v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@refirio.net" 解説 ・ドメイン名: _dmarc.refirio.net これはDMARC(Domain-based Message Authentication, Reporting, and Conformance)ポリシーの設定を示す特別なサブドメインです。 ・TTL (Time to Live): 300 この数字は、DNSレコードがDNSサーバーのキャッシュに保持される秒数を示します。 この場合は、300秒(5分)です。 ・レコードタイプ: IN TXT INはインターネットを意味し、TXTはテキストレコードを示します。 DMARCポリシーはTXTレコードとして設定されます。 ・DMARCポリシー内容: ・v=DMARC1: バージョンを指定します。 DMARC1はDMARCの標準バージョンを示します。 ・p=quarantine: DMARCポリシーの動作を指定します。 quarantineは、DMARCの検証に失敗したメールを隔離(例えばスパムフォルダに移動)することを示します。 ・pct=25: DMARCポリシーが適用されるメールの割合を指定します。 この場合、全メールの25%にポリシーが適用されます。 ・rua=mailto:dmarcreports@refirio.net: DMARC集計レポートを送信するアドレスを指定します。 ここでは、dmarcreports@refirio.netにレポートが送信されることを示しています。 結論 このDNSの登録内容は、refirio.netドメインのDMARCポリシーを設定しています。 このポリシーは、DMARC検証に失敗したメールを隔離し、その適用は全メールの25%に限定されています。 また、DMARCのレポートは特定のメールアドレスに送信されるように設定されています。 これにより、ドメイン所有者は、ドメイン名を使用して送信されるメールの認証状況を追跡し、改善することができます。 ■専用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 [アップデート] Amazon SES の専用 IP を標準からマネージドへ移行できるようになったので、標準とマネージドの違いを整理してみた | DevelopersIO https://dev.classmethod.jp/articles/dedicated-ips-managed-feature/ ■メモ キャリアメールに届かないという記事を見かけるが、問題無く送信できるみたい? 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/ 2023年9月に、東京リージョンに対応したみたい [アップデート] Amazon SES のメール受信機能がついに東京リージョンでも使えるようになりました | DevelopersIO https://dev.classmethod.jp/articles/ses-email-receive-tokyo/ ■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は配信停止を行うためのリンク。クリックすると、メッセージの送信先から直ちに削除された
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=<URL略> 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
メッセージを変更したり削除したり…という機能は見当たらない ただし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(日本語は不可) メッセージ構造: すべての配信プロトコルに同一のペイロード。 エンドポイントに送信するメッセージ本文: テストメッセージ。 「メッセージの発行」をクリックするとメールが送信される 以下のメールが届く
件名: Test for Amazon SNS 送信元: AWS Notifications <no-reply@sns.amazonaws.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=xxxxxxxxxx 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
□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 Kendra
※未検証 BedrockのChatに学習させる際に使用することがあるらしい ただしKendraには「停止」の概念が無く、稼働させ続けると月1000ドルほどかかる 止めるには「終了」する必要がある Bedrockで無料チャットなどを作るとなると、ずっと課金が走るので高額になり注意が必要そう エンタープライズ検索エンジン - Amazon Kendra - AWS https://aws.amazon.com/jp/kendra/ AWSの“AI検索”で、社内の「あの資料どこ?」解消 生成AIと連携も 初心者が「Amazon Kendra」を使ってみた:「AWSを使ってみたい!」 始めの第一歩 - ITmedia NEWS https://www.itmedia.co.jp/news/articles/2308/01/news004.html aws-samples/generative-ai-use-cases-jp: Generative AI を活用したビジネスユースケースのデモンストレーション https://github.com/aws-samples/generative-ai-use-cases-jp
■Amazon Connect
※未検証 電話に対する自動対応などができるみたい Amazon Connect(クラウドベースのコンタクトセンター)| AWS https://aws.amazon.com/jp/connect/ AIチャットボットで問い合わせに対応し、回答が難しい内容に限り担当者にエスカレーション[Amazon Connect + Lex + Bedrock] | DevelopersIO https://dev.classmethod.jp/articles/amazon-connect-escalation-to-manned-response/ Amazon Connectとは? 導入前に知っておきたい機能・料金・注意点と事例 | NTTコミュニケーションズ 法人のお客さま https://www.ntt.com/business/lp/amazon-connect.html Amazon Connectの使い方[丁寧に解説してみた] #AWS - Qiita https://qiita.com/mottie/items/5d94c7d2f94beeb9c342 Amazon Connect + GPT-4 Turboで、予約内容を復唱後、顧客の色々な返答を正しくヒアリングできるか検証 - Amazon Connect アドベントカレンダー 2023 | DevelopersIO https://dev.classmethod.jp/articles/amazon-connect-gpt-confirm/
■機械学習用の環境構築について調査
■調査した環境 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/
■生成AIについて調査
※SageMakerの初期設定や、SageMaker Studio Labの登録を行った…程度で止まっている WSL2にStable Diffusion Web-UIをインストールできたので、いったんそちらで検証している ■EC2での利用 AWS EC2 GPUインスタンスでStable Diffusionを使う - Qiita https://qiita.com/nijigen_plot/items/27f8e987dda6aea5836d この解説をもとに、EC2で起動できそう 費用がどれくらいになるのかは、使う前に確認しておきたいが EC2 (Windows) で Stable Diffusion Web UI を使ってみる https://zenn.dev/kobayasd/articles/eab757ccc6bd6d この内容は試してみたい。AWSの中の人による記事らしい? 似たような記事が他にあるかもしれないので、合わせて確認したい g4dn.xlargeの性能や金額についても、自分で確認しておきたい ■Amazon Bedrockでの利用 基盤モデル API サービス - Amazon Bedrock - AWS https://aws.amazon.com/jp/bedrock/ Amazon Bedrockがリリース! Lambdaから画像を10枚生成してS3に置くまでの流れをやってみた | DevelopersIO https://dev.classmethod.jp/articles/bedrock-lambda-stable-diffusion/ AWSによる生成AIの新サービス「Amazon Bedrock」の可能性を考察する - Qiita https://qiita.com/nasuvitz/items/679674d93219cfb8320d Stable Diffusionなどの生成AIを簡単に使えるようになるらしい AmazonがジェネレーティブAIを構築するためのサービス「Bedrock」やAI用基礎モデル「Titan FM」を発表 - GIGAZINE https://gigazine.net/news/20230414-amazon-web-services-bedrock/ インフラの管理は不要らしい Amazon、ChatGPTのようなテキスト生成AI「Titan」 - PC Watch https://pc.watch.impress.co.jp/docs/news/1493983.html 「現在、限定プレビューを提供している」「テキスト生成、チャットボット、検索、テキスト要約、画像生成、パーソナライゼーションといった用途に活用できる」 専用のEC2インスタンスが裏側で起動されるみたい? 今さら聞けない!? AWSの生成AIサービス Amazon Bedrock入門! - Speaker Deck https://speakerdeck.com/minorun365/jin-sarawen-kenai-awsnosheng-cheng-aisabisu-amazon-bedrockru-men 後発の紹介記事 ■Amazon SageMakerでの利用 SageMaker → JumpStart → Foundation models 「Stable Diffusion 2.1 base」にある「表示 モデル」をクリック 新規にウインドウが開くので、画面右上の「Studio でノートブックを開く」をクリック ホームにある「SageMaker ドメインを作成」ボタンは何か クリックしてみると、「SageMaker Domain をセットアップ」画面が表示される
高速セットアップ (1 分) Amazon SageMaker でアカウントを設定し、SageMaker Domain の許可をセットアップします。 ・パブリックインターネットアクセスと標準暗号化 ・SageMaker Studio の統合 ・共有可能な SageMaker Studio Notebook ・SageMaker Canvas ・IAM 認証 シングルユーザードメインと、SageMaker の使用を開始しようとしている初回ユーザーに最適です。
とあるので、そのままにしておく 「ドメイン名」を決める必要があるようなので、ひとまず「study」としてみる 「ユーザープロファイル」の「実行ロール」は「新しいロールの作成」としてみる 「IAMロールを作成する」ダイアログが開くが、「指定するS3バケット」はひとまず「任意のS3バケット」としてみる(※本番運用では好ましくない設定かもしれない) 「ロールを作成」ボタンをクリック もとの画面に戻るので、「送信」ボタンをクリック 「VPCを選択」ダイアログが表示されたので、すでに作成してあるVPC「Study」を、サブネットは「Trust-A」を選択してみる(※本番運用では用途を理解して選択したい) 「保存して実行」ボタンをクリック 10分ほどしてから確認すると、ステータスが「Pending」から「InService」になっていた 作成したドメインは「SageMaker → Domains」から確認できる 話題のLlama 2という大規模言語モデルをAmazon SageMaker JumpStartで動かしてみた | DevelopersIO https://dev.classmethod.jp/articles/sagemaker-jumpstart-llama2/ Stable Diffusion を AWS でサクッと動かすために Sagemaker JumpStart を使ってみる https://zenn.dev/kobayasd/articles/8d2b3a1e1b5a2a 【無料】Amazon SageMaker Studio Labの始め方 https://zenn.dev/en2enzo2/articles/a1988487d5614b AWS SageMaker Studio 費用(ノートブックとインスタンスもシャットダウンしないと課金される) - Qiita https://qiita.com/Blahrmy/items/9cdeefe881299e9ca38c AWSで学習済み機械学習モデルを爆速でデプロイする方法 - NIFTY engineering https://engineering.nifty.co.jp/blog/17721 UIが一新されたAmazon SageMaker Studioの歩き方 | DevelopersIO https://dev.classmethod.jp/articles/how-to-walk-around-amazon-sagemaker-studio-new-ui/ Stable Diffusion Web-UI を SageMaker Studio で動かしてみる https://zenn.dev/kobayasd/articles/0371c7418b874e ※最初、ドメイン名「develop」で、VPC「Develop」上に作成しようとしたら、以下のエラーが表示された 上記のとおり「study」に作り直すと進んだが、どういうエラーなのかよく解らず
ValidationException 2 validation errors detected Value '' at 'defaultSpaceSettings.executionRole' failed to satisfy constraint: Member must have length greater than or equal to 20 Value '' at 'defaultSpaceSettings.executionRole' failed to satisfy constraint: Member must satisfy regular expression pattern: ^arn:aws[a-z\-]*:iam::\d{12}:role/?[a-zA-Z_0-9+=,.@\-_/]+$
Amazon SageMaker Studio ドメインを作成する際に 「Missing required key ‘VpcId’ in params」 エラーが発生した時の対処方法 | DevelopersIO https://dev.classmethod.jp/articles/tsnote-sagemaker-stuido-domain-missing-vpc/ Amazon SageMaker ドメイン作成時に設定が必要な各パラメータを解説 | DevelopersIO https://dev.classmethod.jp/articles/amazon-sagemaker-domain-setup-parameter/ ■Amazon SageMaker Studio Lab 【AWS グラレコ解説】データサイエンスの学びを支援する Amazon SageMaker Studio Lab をグラレコで解説 - builders.flash☆ - 変化を求めるデベロッパーを応援するウェブマガジン | AWS https://aws.amazon.com/jp/builders-flash/202205/awsgeek-sagemaker-studio-lab/?awsf.filter-name=*all > AWSはAmazon SageMakerをすでに提供していますが、SageMakerとStudio Labは大きく3つの点で異なります。 > 1点目はAWSアカウントが不要であること、2点目は無料であること、3点目は利用可能な機能です。 > Studio Labは機械学習の学びや検証を行うため、SageMakerは検証した後の本格的な機械学習モデルの開発と運用のため、と役割が異なります。 > Studio Labにはもちろん SageMakerほど豊富な機能はありませんが、学習に十分な機能とスペックを備えています。 【無料】Amazon SageMaker Studio Labの始め方 https://zenn.dev/en2enzo2/articles/a1988487d5614b Amazon SageMaker Studio Lab 使ってみた! | リウコムTechブログ https://www.ryucom.co.jp/blog/aws/3787 ※Jupyter Notebookをベースにした開発環境 Google Colaboratoryでも同じような環境が提供される 「Request free account」をクリック 以下のとおり入力して「Submit request」をクリック Enter your email: refirio@example.com Enter your first name: Taro Enter your last name: Yamada Select your country: Japan Enter your company or organization name: example Select your occupation: Programmer Why are you interested in Amazon SageMaker Studio Lab?: Work Enter referral code: (空欄) 以下のように表示された
Request submitted Your request was submitted successfully. Please check your email for further registration steps.
少し待つと、no-reply@studiolab.sagemaker.aws から「Verify your email」というメールが届く 本文にある「Verify your email」ボタンをクリックすると、以下のように表示された
Email verification Your email was verified. We've added you to the waitlist. Once your request is approved, we'll send you an email with a link to create your account. In the meantime, check out the FAQ to learn more about the Amazon SageMaker Studio Lab.
ウェイトリストに登録されたとのことなので、いったん待つ 3〜4日ほどで、「Account request approved」というメールが届いた メールの案内に従って、アカウント登録を行う Enter your email: refirio@example.com Create a password: ******** Confirm the password: ******** Enter a username: example 登録すると「Verify your email」の画面が表示される 同じタイトルでメールが届いているので、メールの案内に従って認証する SageMaker Studio Lab https://studiolab.sagemaker.aws/login 手順中で作成したアカウントでログインできた 「Start runtime」をクリック
Mobile phone number required Add a mobile number to associate with your SageMaker Studio Lab account so we can identify you. To verify your number, we will send you a text message with a temporary code. Message and data rates may apply.
と表示された 会社電話番号の 070-1254-9201 を入力(「+81 07012549201」とした。「+81 7012549201」だとエラーになった) 確認コードが送られてくるので入力する 起動が完了すると、「Open Project」の丸ボタンに色が付くのでクリック JupyterLab(データ分析ツール)が起動する 画面右側に、以下のコードが入力されている箇所がある
a = 10 b = 20 c = a + b print(a, b, c)
コードが記述されている部分をクリックして、Shift+Enterで実行できることを確認する 新規にファイルを作成してみる 画面左上の「+」をクリックし、「default:Python」を選択する
1 + 2 + 3
と入力して、Shift+Enterで実行できることを確認する 作業が終わったら、「Stop runtime」をクリックして終了させておく (終了を忘れると課金が始まって…ということではなく、時間を過ぎると自動でセッションが切断されるらしい)
■動画配信サーバについて簡単に調査
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
■ブロックチェーン
※未検証 Amazon Managed Blockchain(ブロックチェーンネットワークを簡単に作成、管理)| AWS https://aws.amazon.com/jp/managed-blockchain/ AWSではじめるブロックチェーン Amazon Managed Blockchain | DevelopersIO https://dev.classmethod.jp/articles/amb-tutorial/
■マルチ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調整後、以下の内容を返信した
Thank you for support. Email Address: example@refirio.net Use Case Description: Removal of E-mail sending limit width rDNS registration web1.refirio.net http://203.0.113.1/ web2.refirio.net http://203.0.113.2/ web3.refirio.net http://203.0.113.3/ Below is the official site. https://refirio.net/ Email is used by Contact form. https://refirio.net/contact/ And below is the privacy policy. https://refirio.net/privacy-policy/ I use email to receive inquiries. It does not transmit to the unspecified number of people.
さらに改めて以下の問い合わせを送った
Request to Remove Email Sending Limitations Email Address: example@refirio.net Use Case Description: Removal of E-mail sending limit width rDNS registration web1.refirio.net http://203.0.113.1/ web2.refirio.net http://203.0.113.2/ web3.refirio.net http://203.0.113.3/ Below is the official site. https://refirio.net/ Email is used by Contact form. https://refirio.net/contact/ And below is the privacy policy. https://refirio.net/privacy-policy/ I use email to receive inquiries. It does not transmit to the unspecified number of people. Elastic IP Address 1: 203.0.113.1 Elastic IP Address 2: 203.0.113.2 Reverse DNS Record for EIP 1: web1.refirio.net Reverse DNS Record for EIP 2: web2.refirio.net
以下の返信が来て制限が解除された
Hello, We have configured the reverse DNS record(s) you requested. Your request was mapped for 203.0.113.1:web1.refirio.net and 203.0.113.2:web2.refirio.net. Please note that propagation of this update to DNSBL services that Amazon works with may take up to a week. Email sending limitations have also been removed for any resources for the region your EIP is located in. Please let us know if you have any questions. Thank you for your inquiry. Did I solve your problem? If yes, please click here: http://www.amazon.com/gp/help/survey?p=ABCDEFGHIJKLMN&k=hy If no, please click here: http://www.amazon.com/gp/help/survey?p=ABCDEFGHIJKLMN&k=hn Best regards, http://aws.amazon.com
■やりとり参考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通程度 -- この国用のメッセージテンプレート: 検証用のため、定型文はありません。 以上、よろしくお願いいたします。
半日ほどで以下の返信が来た。制限が緩和された
平素は Amazon Web Services をご利用いただき、誠にありがとうございます。 新しい SMS の月額使用限度額 $10 USD が適用されました。 この処理がコンソールに反映されるまでに最大 1 時間かかる場合があります。 メッセージを送信する前に、Amazon SNS コンソール ( http://docs.aws.amazon.com/sns/latest/dg/sms_preferences.html ) または API を使用してアカウントの使用限度額を更新する必要があります。 これらの手順を完了すると、デフォルトの限度額が 1.00 USD であると記載されたメッセージが表示されることがあります。 このメッセージは無視できます。 CloudWatch ( https://docs.aws.amazon.com/sns/latest/dg/MonitorSNSwithCloudWatch.html ) を使用して Amazon SNS のメトリクスをモニタリングすることをお勧めします。 Amazon SES の使用を開始する際は、以下のことをお勧めします。 -- 必要となる前に、使用限度額の引き上げを申し込みます。 -- 必要に応じて、AWS サポートセンターでケースを作成し、他の SMS オプションをリクエストします。 -- ベストプラクティスについては、SMS メッセージの送信に関する追加情報をご覧ください。
■逆引き(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日以内ならアカウントを再開できるとのこと 組織アカウントに参加させている場合、完全に閉鎖されたら組織からも除外しておく シングルサインオンの設定を行っている場合、こちらも紐づけを解除しておく …と思ったが、それぞれ自動的に削除されていた

Advertisement