「AWSではじめるインフラ構築入門」を読む。
セミナーや業務の知識を体系的に整理したいので。
アカウントとユーザー
AWSを使うためにはアカウントを作る必要がある。アカウントを作成するとルートユーザーが作られ、
そのルートユーザーが個別の権限を持った一般ユーザー(IAMユーザー)をさらに作成することができる。
つまり、アカウントは1つの個人を表しているのではなく、複数のユーザーからなる組織を表しているイメージ。
ユーザーに何かの作業をする権限を与えたい場合は、ユーザーそのものに権限設定をしてもよいし、
ユーザーが所属するグループ(ユーザーグループ)に権限設定してもよい。後者のほうが管理の手間やミスが少なくなる場合がある。
ルートユーザーはあまりに強力な権限を持っているのでアクセスキーは発行せず、MFAを有効にして日常使いを避ける。
代わりにIAMユーザーを用途に応じて作成するようにしよう。
ポリシー
ユーザーまたはグループに付与するアクセス許可の種類は非常にたくさんある。
それらの中から、関連するアクセス許可をまとめたものをポリシーと呼ぶ。
- PowerUserAccess: AWS内の全リソースへのアクセス許可
- IAMFullAccess: IAMへのアクセス許可
VPC
AWS内に仮想的なネットワークを作る機能。
IPv4を使用する場合は最初の2オクテット(16bit)はVPCの識別番号みたいなものになり、
これ以降のオクテットをCIDRで分割することができる。
- 16bit: VPC部
- 17-28bit: サブネット部
- 18-32bit: ホスト(リソース)部
なお、各サブネットにはAWSが使用しているものも含めて5つぶんのアドレスがリザーブされている。
インターネットゲートウェイとNATゲートウェイ
インターネットゲートウェイは「VPCからインターネットへのアクセス」と「インターネットからVPCへのアクセス」を可能にするためのリソース。
つまり、静的NATである。VPC内のリソースのIPアドレスと、インターネット上のIPアドレスを1対1で変換する。
VPC内にはパブリック、プライベートのサブネットを作っていくが、
パブリックサブネットはパブリックのIPアドレスを使っているというわけではなく、
インターネットゲートウェイがデフォルトルートになっているものをいう。
一方、NATゲートウェイは「VPCからインターネットへのアクセス」のみを可能にするリソース。
つまり、動的NAT(NAPT)である。プライベートサブネット内のアドレスをインターネット上のIPアドレスに一方的に変換する。
NATゲートウェイはアドレス変換を行うだけであって、インターネットにアクセスするためにはインターネットゲートウェイが必要になる。
したがって、NATゲートウェイは通常はパブリックサブネットに配置する。
そうしないとせっかくアドレス変換してもインターネットに向けたルートが見つからない。
ルートテーブル
ルーターのルーティングテーブルと同様に通信の行き先を決定するためのテーブル。
VPC内でルーティングする場合は行き先をlocal
に指定する。サブネット間のルーティングはうまくやってくれる。
デフォルトルートは送信先が0.0.0.0/0
のルートに記述する。
セキュリティグループとネットワークACL
下の記事が非常にわかりやすい。
要はインスタンスごとに規制するのがセキュリティグループであり、
サブネット単位でまとめて規制するのがネットワークACLとのこと。
本書ではセキュリティグループを使用してEC2やELBなどへのインバウンド通信を制御している。
サーバーの構成
管理用に使用するSSH接続可能な踏み台サーバーと、利用者が実際にWEBページにアクセスするためのサーバーを用意する。
踏み台サーバーにはパブリックサブネットに置いたうえで、パブリックIPアドレスを付与し、
さらにセキュリティグループで外部からのSSH接続を許可する。
一方、WEBサーバーはプライベートサブネットに隠し、ロードバランサ経由で外部からの通信を待ち受けるようにする。
セキュリティグループはVPC内のローカルな通信のみ許可するようにする。
ロードバランサー
ロードバランサー(LB)の機能は主に以下の3つ
- 負荷分散: 複数のWEBサーバーへの通信を振り分ける。
- TLSの処理: 処理不可の大きいTLSの処理をロードバランサが受け持ち、WEBサーバーへの通信はHTTPで行う。
- 不正リクエスト対策: 不正アクセスを防止する仕組みを備えている。
LBが通信を受け取って復号した時点で内部のネットワークに入っているので、LBとWEBサーバー間は暗号化する必要はない。
また、このときWEBサーバーが待ち受けるポート番号は1024より大きい任意の番号が使われる。
1024以降は待ち受けるためにroot権限は不要であり、乗っ取られた場合も影響を低減することができる。
LBは複数のAZに対してリクエストを振り分ける。
LBの設定時に指定するAZはインターネットゲートウェイへのルーティングが可能なサブネットを指定する。
今回はパブリックゲートウェイをしている。
ロードバランサーやターゲットグループの設定時にポート番号をいくつか設定する。
特にターゲットグループにEC2インスタンスを追加するときにフォワーディング先のポート番号を上書きする部分がわかりにくい。
下の記事が非常によくまとめられていてわかりやすい。
データベース
RDSでMySQLのDBサーバを作成する際は以下のグループを設定する。デフォルトのグループが用意されているものもある。
- パラメータグループ: DBエンジン(PostgreSQLとかMySQLとか)の固有の設定。大量のチューニングすべきパラメータが含まれている。
- オプショングループ: (おそらく)DBエンジンによらないRDSの設定。パラメータグループより上位の設定というイメージ?
- サブネットグループ: RDSを配置するサブネットの設定。
RDSはEC2と違って作成するサブネットを指定できない。代わりにサブネットグループで配置したいサブネットの範囲を指定し、そのどこかにAWSがRDSを作ってくれる。
よってサブネットグループで設定するサブネットはプライベートサブネットにしないと外部からアクセスされてしまう危険性がある。
ストレージ
Elastic Block Store(EBS)とSimple Storage Service(S3)の違いは以下の記事が詳しい。
EBSはOSのローカルディスクとしてマウントされるが、S3はHTTPなどのエンドポイントが提供されるのみである。
単純にデータを低コストで置いておきたい。高速に読み書き不要ということであればS3で問題ない。
S3は特定のサブネットなどに置かれるものではなく、VPCの外側に存在する。
EC2などがS3にアクセスする場合はS3へのアクセスを許可したIAMロールをEC2に設定する。
本書の設定ではプライベートサブネットのEC2からNATゲートウェイを通してS3にアクセスしてしまう気がする。
下の記事にあるようにEC2がプライベートサブネットにある場合はVPC Endpoint(Gatewayタイプ)を利用するのがよいとのこと。
NATゲートウェイにお金を巻き上げられるのも嫌なのでVPCエンドポイントを使って構成してみた。
本書ではaws s3 cp
コマンドでファイルをS3に転送しているが、
下記の記事によるとEC2からVPCエンドポイントを通してS3に通信したい場合は、明示的にリージョン名を指定する必要があるらしい。
aws s3 cp test_web01.txt s3://sample-aws-intro-bucket --region ap-northeast-1
ドメインとDNS
Route 53を使うと独自ドメインの取得からサーバー証明書の発行まで全部やってくれる。お金をかけたくないのでここは読むだけ。
VPC内部の名前解決にはプライベートDNSを使うとよい。
プライベートIPとか意味不明なエンドポイント名ではなく、わかりやすい名前で参照できるようになる。
これをするためにはVPCの「DNS解決」と「DNSホスト名」を有効にする必要がある。
さらにRoute 53のホストゾーンにプライベートのゾーンを追加し、名前解決したいプライベートIPアドレスに対するAレコードを記述する。
メール
AWSにおけるメール送受信にはAmazon SESを使用する。
EC2などのアプリケーションからメールの送信をする場合は特別なIAMユーザーを作成してその権限を使う。
受信する場合はPOP3やIMAPを使うのではなく、SESが受信したことをトリガとしてアクションが実行される。
アクションを使用することでスマホに通知を送ったり、Lambdaで処理を走らせたりすることができる。
POP3やIMAPを使えないということは人間が目視でメールを確認して対応するということは不可能ということになる。
このような特性を踏まえてSESを使用する必要がある。
SESのSMTPインターフェイスを使用してEC2からメールを送信する場合、
SMTPのエンドポイントはインターネット上にあるからNATゲートウェイ経由で通信するか、
VPCエンドポイント(Interfaceタイプ)を作るしかないようだ。
VPCエンドポイントの種類
VPCエンドポイントを使うとVPCとVPC外のサービス(S3、SESなど)間の通信をプライベートに行うことができる。
VPCエンドポイントにはGatewayタイプとInterfaceタイプがある。
Gatewayタイプはルートテーブルのインターネット向けのルートを細工して、ゲートウェイ経由で外部のサービスと通信する。
たとえば、S3のエンドポイントを名前解決するとグローバルのIPアドレスで解決される。
InterfaceタイプではVPC内にプライベートIPが付与されたENIが作成される(VPC内に謎のホストが出現する)。
このENI対して通信をすると外部のサービスへと中継してくれる。
Interfaceタイプ作成時に「DNS名を有効化」を選択した場合、
外部のサービスのエンドポイントの名前解決した際にENIのプライベートIPアドレスに解決される。
つまり、本来はグローバルIPアドレスが付与されているはずの外部サービスを名前解決すると、
同一ネットワーク内のENIのプライベートIPアドレスが得られるというわけだ。
ためしにSESのSMTPエンドポイントを名前解決してみる。
VPCエンドポイント(Interfaceタイプ)が無効な場合はグローバルIPアドレスで解決される。
$ nslookup email-smtp.ap-northeast-1.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: email-smtp.ap-northeast-1.amazonaws.com
Address: 35.74.177.255
Name: email-smtp.ap-northeast-1.amazonaws.com
Address: 54.150.96.139
Name: email-smtp.ap-northeast-1.amazonaws.com
Address: 18.176.73.83
一方で有効にした場合はプライベートIPアドレスで解決される。
$ nslookup email-smtp.ap-northeast-1.amazonaws.com
Server: 10.0.0.2
Address: 10.0.0.2#53
Non-authoritative answer:
Name: email-smtp.ap-northeast-1.amazonaws.com
Address: 10.0.66.157
Name: email-smtp.ap-northeast-1.amazonaws.com
Address: 10.0.82.193
キャッシュサーバー
RedisやMemcachedなどのキャッシュ用DBのマネージドサービスがElastiCacheである。
ElastiCacheはキーバリュー型のNoSQLデータベースである。
サンプルアプリを動かして…みなかった
独自ドメインは使いたくないから、ロードバランサのエンドポイントにアクセスしてなんとか試せないかと思ったが…
徒労だったら嫌なので読むだけにした。どなたか独自ドメインなしで動かす方法知っていれば教えてください。
監視
監視項目はリソースの種類に応じて決定する。マネージドサービスのほうが比較的監視すべき項目は少ない。
CloudWatchを使用すると稼働情報のダッシュボード化やアラームの設定などを行うことができる。
アラームの閾値は静的か異常検出を選択できる。静的は定数の閾値を引いてメトリクスの値が上回るか/下回るかで異常判定する。
異常検出は(おそらく)過去のデータの標準偏差からアブノーマルな変動を検出するような気がする。
アラーム状態になったり、アラーム状態から正常に戻った場合にSNSを使ってメールを送信したりできる。
お金の話
AWS Pricing Calculatorでは各リソースの使用状況などを予測し、費用の概算を行うことができる。
Cost ManagementのBudgetsでは予算を設定したうえで実績や予測値が予算を超過するかしないかを判定したりアラーム通知したりできる。
Cost Explorerでは過去に支払った料金の可視化ができる。
IaC
やはり手動でコンソールをポチポチ操作する方法は限界がある。
CloudFormationとAWS CLIを使用したリソース管理の自動化(コード化)を実施する。
CloudFormationのyaml版の文法は下の記事を参照。
CloudFormationでプロビジョニングしたリソースをまとめてスタックと呼ぶ。
スタックはまとめて管理することができ、一度に生成・破棄することが可能である。
小ネタ
- 当初、大阪リージョンを選択してシステム構築していたが、無料枠対象のt2.microがap-northeast-3aのAZでしか使用できないことが判明。今後も余計なところでハマりそうなので本の設定例のとおりに作り直すことにした。
- configファイルを使ってSSH接続するときに
Bad owner or permissions on <configファイルのパス>
というエラーが表示された。これを解決するにはファイルの権限設定変更(P.117)をすればよさそう。