目的
これまで業務上で使用してきたAWSのサービスについて、それぞれのサービスについての再理解と個人的な使用感についてまとめました。
1. 開発・CI/CD
コードの管理からビルド、本番・検証環境への自動デプロイを支えるパイプラインの構築に使用したサービス群について。
CodeCommit
AWSが提供するフルマネージドなソースコード管理(Git)サービス
役割・使われ方
GitHubと同じように、多数のメンバーとアジャイル開発を進めるために使用される。
「Git」はコードの変更履歴を記録するローカルの技術(仕組み)であり、それをクラウド上で共有・管理する高機能なサービスが「GitHub」等が挙げられる。
そのうち、AWSが提供しているものがCodeCommitにあたる。
GitHubではなく、CodeCommitを利用する利点としては、後述するAWSのサービスとの連携がしやすい事である(CodePipelineなど)。
自分なりの使用感
基本機能はGitそのものであるため、使用するコマンドはGitHubで使用していたものと同じものになる。
普段通りコマンドラインから操作する分には全く迷うことなく導入できた。
IAM権限を使ってリポジトリへのアクセスをAWS内で厳密に制御できるなど、セキュリティ面の高さについてはGitHubより高いと感じる。
一方トレードオフとして、自身に割り当てられたIAMの権限を開発マシンに設定する手順など、今までやらなくても動かせていた部分を追加で設定しなければ使えないという煩わしさを感じる。
いくらかAWSを触ったことのある人であれば、エラーを見れば何が起きているのか理解し、管理者に相談することが出来る。
しかし、初めてAWSを使用する人は何が起こっているか分からずエラーを解決できないケースもしばしばあるのではないかと感じた。
現代においては、エラー内容についてAIを利用して解決する事もできるだろう。
CodeBuild
ソースコードをコンパイルし、テストを実行して、デプロイ可能な成果物(Dockerイメージなど)を作成するフルマネージドなビルドサービス
役割・使われ方
buildspec.ymlという設定ファイルにビルドの手順を記述し、実行時のみ立ち上がる使い捨てのコンテナ環境で処理を行う。
CodeCommitからコードを引き継ぎ、Lambda用のコードパッケージングなどを自動化するために使用した。
基本的には、後述するCodePipelineの一つのパーツ(Buildステージ)として組み込んで運用する。
自分なりの使用感
まず、役割としてコンテナ環境と書いたが、Docker等を利用したコンテナについての理解が必要となる。
分かりやすく言ってしまえば、どこに持っていっても環境の違いを気にせず、全く同じようにアプリを動かせる魔法の箱である。
この箱(コンテナ)の中であれば、自分のPCでもAWSの上でも、全く同じようにプログラムを動かすことができるため、実行環境について考える必要がなくなるという技術。
ビルド用のサーバー(Jenkinsなど)を自分たちで管理・維持する必要がなく、複数のビルドが同時に走ってもスケールして対応してくれるため、運用の手離れが非常に良い。
buildspec.ymlの記法を知らなくてはいけないため、見る分には理解が出来るが、個人的には自身で作成をするのは躊躇する。
しかし、記法が決まっているという事はAIに解析させることも容易であるため、分からなければAIに聞くことである程度は何をしているか把握することは出来るだろう。
ただし、前大前提として、利用しても外部に情報が流れないAI利用環境で行うこと。
CodePipeline
コードの変更から本番環境への反映までのプロセスを自動化・可視化するサービス
役割・使われ方
CodeCommitへのプッシュを検知し、CodeBuildでのビルドを経て、ECSやEC2、Lambdaへのデプロイへと繋ぐ、一連のワークフローを一本化する役割を担う。
各フェーズを「ステージ」として定義し、それらをパイプラインとして一本の線で繋ぐことで、人間の手作業を介さない安全な自動デプロイ(CI/CD)を実現する。
自分なりの使用感
ソースコードを検証環境に適用するまで、よくある操作の流れとして
- ローカルで実装したソースコードをGitHubにプッシュする
- 実行環境でソースコードをプルする
- プルしてきたソースコードをビルドする
- ビルドした成果物を使って起動する
といった流れになると思うが、これを完全に自動化したりワンボタンで実行できたりする事ができる。
これにより、リリース作業時の心理的負担や安心感が大きく変わる。
また、AWS内のサービスであるため、IAMを用いた各リソースへのアクセス権限管理が非常に強固かつシンプルに完結するのも魅力である。
実務ではLambdaにデプロイをするために使用した。
プッシュされた事を検知 ⇛ ソースをプル ⇛ ビルド(CodeBuild)
という自動化の途中に、
プッシュされた事を検知 ⇛ ソースをプル ⇛ 手動で承認 ⇛ ビルド(CodeBuild)
として、意図しないタイミングでビルドがされないように設定する事も可能。
2. 計算資源(コンピューティング)
アプリケーションのプログラムを実際に動かすための実行環境(サーバーやサーバーレス環境)として使用したサービス群について。
EC2
AWSが提供する最も標準的な仮想サーバーサービス(Elastic Compute Cloud)
役割・使われ方
クラウド上にLinuxやWindowsのサーバーを1台丸ごと立ち上げるサービスである。
OSの選択から、中に入れるミドルウェア(ApacheやNGINX、PHP、Javaなど)のインストール、設定までを全て自由に行うことができる。伝統的なWebサーバーや、24時間動かし続けるバッチサーバーなどを構築する際に使用される。
スペックについても細く設定が可能で、もちろん良いスペックであればあるほど、使用料金は高くなる。
自分なりの使用感
いわゆる「普通のレンタルサーバーや物理サーバー」と操作感が同じであるため、Linuxの基礎知識さえあれば一番馴染みやすく、何でもできる。
一方で、今までLinux等でコマンドラインでの操作をした事がない人には馴染まないかもしれない。
例えば、本番環境をEC2で立ち上げたとき、スペック不足やディスク容量の不足でサービスの提供が滞ってしまったりする事もありえる。
インフラの知識が乏しいものにとっては、1から構築する事はリスクが高い。
そのため、知識のあるものが構築をし、かつ監視を怠らない必要がある点には注意が必要。
現代においては、後述するECSやLambdaのように「サーバーを自分たちで管理しない(マネージドな)環境」が主流になりつつあるため、新規のシステムで敢えてEC2をそのまま使う理由は減ってきたと感じる。ただし、既存システムの移行が難しい場合や、どうしてもOSレベルでの特殊な設定が必要な場合には、今でも確実な選択肢となると感じる。
ECS
Dockerコンテナを効率よく管理・実行するためのコンテナオーケストレーションサービス(Elastic Container Service)
役割・使われ方
CodeBuildの章で触れた「魔法の箱(コンテナ)」を、本番環境で大量に、かつ安定して動かすための「有能な管理人」のようなサービスである。
Webアプリケーションの実行環境を安全にスケールさせるために使用し、コンテナが何らかのエラーで停止しても、自動で新しいコンテナを立ち上げて入れ替えてくれる(自己修復)役割も持つ。
自分なりの使用感
アクセスが増えれば自動でコンテナの数を増やし(オートスケーリング)、減れば縮小してくれるため、EC2に比べてインフラのキャパシティを考えなくて良い。
一方で、「タスク定義」「サービス」「クラスター」といった特有の概念を理解しなければならず、初心者にとっての「設定の難易度」はAWSの中でもトップクラスに高い。
実務では、後述するEFSにアップロードしたものをECSにデプロイをした。
既に設定されたものを利用していたため、設定さえ整っていれば使用する事は難しくない。
Lambda
サーバーの存在を意識せずにプログラムを実行できる、イベント駆動型のサーバーレスコンピューティングサービス
役割・使われ方
「サーバーを常に起動しておく」のではなく、「何かが起きた時(イベント)」だけプログラムを一瞬だけ起動して処理を行うサービスである。
ざっくりと、バッチのようなものと考えてもよい。
使っていない時間は料金が1円も発生せず、「実行された回数と時間」の完全従量課金であるため、たまにしか動かないバッチ処理などでは驚異的なコストパフォーマンスを発揮する。
自分なりの使用感
実務では、ファイルがAWS(後述するS3)にアップロードされた事を感知し、自動で実行をするようなものを実装した。
設定はserverless.tsというファイルで行い、Lambdaにサービスを登録してTypeScriptで書かれた処理が走るようにした。
この例のように、常に起動して待ち受けている必要はなく、何か起きたときにだけ自動で立ち上がり実行される。
EC2で感じた「OSの管理」や、ECSで感じた「複雑なインフラ設定」という概念がほぼ無く、「開発者はプログラム(関数)を書くだけで良い」という圧倒的な楽さを感じた。
ただし、万能ではなく明確な制約が存在し、1回の実行時間は最大15分までという制限がある。
そのため、開発前に使用メモリ量の調査と並行して、予想される実行時間や今後のスケール感についても調査が必要となった。
3. ネットワーク・配信
ユーザーからのアクセスを一番手前で受け止め、安全かつ高速にアプリケーションへ交通整理を行うサービス群について。
CloudFront
AWSが提供する、Webサイトの表示速度を高速化するためのコンテンツ配信ネットワーク(CDN)サービス
役割・使われ方
世界中に配置された「キャッシュサーバー」を利用して、ユーザーへ高速にWebサイトのデータ(画像、HTML、動画など)を届ける役割を持つ。
後述するS3やALBの手前に配置し、一度読み込んだデータをCloudFrontが一時的に保存(キャッシュ)しておくことで、元のサーバー(オリジン)に毎回データを構築しにいかせる負担を減らし、ユーザーへのレスポンス速度を爆速にする。
自分なりの使用感
一度設定してしまえば、大量のアクセスが来てもAWS側で勝手にさばいてくれる。
実務では、CORSの設定をする必要があり、この部分を触らなければCORSでエラーとなった。
キャッシュの扱いについてここで管理される場合もあるため、プロジェクトによっては細かく設定する必要がある。
ALB
ユーザーからの大量のアクセスを、後ろに控える複数のサーバーへ適切に振り分ける負荷分散機能(Application Load Balancer)
役割・使われ方
前述したEC2インスタンスや、ECSのコンテナ(タスク)の手前に立ち、文字通りアクセスを「バランスよく」均等に振り分ける(ロードバランシング)役割を持つ。
万が一、複数立ち上がっているサーバーの1台がエラーでクラッシュして停止しても、それを瞬時に検知して自動的に正常なサーバーだけにアクセスを流す(ヘルスチェック機能)ことで、サービスを止めずに運用をするために使用される。
自分なりの使用感
前述したECSやEC2を使って複数同じものを起動して本番環境を運用する場合、ほぼセットで導入することになる必須のパーツである。
ユーザーからのアクセスをまずこのALBが受け止めてくれるため、後ろにいるEC2やECSをインターネットから直接見えない「安全なプライベート空間」に隠すことができる。セキュリティの境界線として非常に優秀。
先述した「ヘルスチェック」の設定をする必要があり、アプリケーション側で「私は元気に動いています」と返すための専用のURL(例: /health など)を用意しておかなければならない。
この設定を忘れたり、パスを間違えたりすると、ALBから「このサーバーは死んでいる」とみなされ、正常に起動しているはずなのにアクセスが一切振り分けられなくなる。
4. データストア・ストレージ
アプリケーションが利用するユーザーデータや画像ファイル、データベースなどの保管先として使用したサービス群について。
S3
AWSが提供する、容量無制限で極めて高い耐久性を持つオブジェクトストレージサービス(Simple Storage Service)
役割・使われ方
ユーザーがアップロードした画像や動画、CSVファイルなどの「静的ファイル」を保存する場所として利用される。
システムの各種ログ(ALBログやアプリケーションログ)の長期保管先としても幅広く活用される。
自分なりの使用感
「どれだけ大量のファイルを保存しても容量不足にならない」かつ「データ消失の可能性が事実上ゼロに近い」という圧倒的な安心感があり、AWSを使うならほぼ確実に触ることとなる最重要サービスだと感じる。
ここにアクセスする事のできる権限を設定する事で、セキュリティについて強化することが出来る一方で、アプリ起動をつかさどるアカウントに許可が付与されていないと、アプリ側からアップロードが出来ないといった事も起こる。
設定についてはS3のプロパティから設定が出来るが、過不足無く適切な権限付与がされるように調査が必要になる事もある。
EFS
複数のEC2やECSから同時に接続して利用できる、マネージドな共有ファイルシステム(Elastic File System)
役割・使われ方
いわゆる「ネットワーク上の共有フォルダー」のようなものである。
一般的なストレージ(EBSなど)は1台のサーバーからしか接続できないが、EFSは複数のEC2インスタンスや、前述したECSの複数のコンテナ(タスク)から同時にマウントして、同じファイルを読み書きすることができる。
自分なりの使用感
前述したECSのように、コンテナが自動で増減(オートスケーリング)する環境において、「どのコンテナからアクセスしても全く同じファイルを参照・更新できる」という環境となる。
実務では、このEFSにデータをアップロードしておき、ECSコンテナがそれを読み込んで処理・デプロイを行うといった連携のために使用した。
RDS
AWSが面倒な管理を代行してくれる、リレーショナルデータベースのマネージドサービス(Relational Database Service)
役割・使われ方
MySQLやPostgreSQLといった、アプリケーションのリレーショナルデータベースをクラウド上に構築・運用するサービスである。
データの保存だけでなく、データベースのバックアップ、OSやソフトウェアのセキュリティパッチの適用などをAWS側が自動で引き受けてくれる。
自分なりの使用感
EC2の上に自分でMySQLなどをインストールするのではなく、こちらを利用することでデータベースの運用保守の手間が大きく減る。
気をつけるべき点としては、マネージドサービスであるゆえに、使用料金が他のサービス(EC2など)と比べても高めになりやすいらしい。
開発で使用する側としては、何も違和感なくリレーショナルデータベースを使っている感覚で使用できる。
5. セキュリティ・運用管理
全てのAWSサービスが安全に連携し、システムが正常に稼働し続けているかを24時間体制で見守るための土台となるサービス群について。
IAM
AWSのサービスやユーザーに対して「誰が・何をしてよいか」という権限を管理する最重要サービス(Identity and Access Management)
役割・使われ方
AWSにおける権限についての設定はここで行う。
開発者やグループごとに「リポジトリの読み書きはできるが、サーバーの削除はできない」といったアカウント権限を作ったり、サービス同士(例:LambdaからS3へファイルを保存する、ECSからEFSをマウントするなど)が安全に通信・操作できるようにするためのロールを発行したりする。
自分なりの使用感
これまでの章でも何度も登場した通り、AWSを利用する上で100%避けて通れない、かつ最もお世話になり、最も頭を悩ませるサービスである。
セキュリティを高めるための鉄則として「必要最低限の権限だけを与える(最小権限の原則)」ことが求められるが、これが非常に細かい。新しい機能を実装するたびに「Access Denied(権限がありません)」というエラーに遭遇し、その都度必要なポリシーを調べて追加する、という地道な作業が発生する。
また、その権限についても直感的に分かりにくいこともあるが、これはもう慣れである。
基本的には[サービス名]:[アクション名]のような書き方がされる。
- S3に関する権限の例
- s3:GetObject(ファイルを読み込む・ダウンロードする権限)
- s3:PutObject(ファイルを書き込む・アップロードする権限)
このように、「どのサービスの」「何をするのか」がセットになって表記される。
最初は呪文のように見えるが、エラーログに「s3:PutObject が足りない」とそのまま表示されることが多いため、慣れてくれば「あ、あの権限を足せばいいんだな」とピンとくるようになる。
設定の煩わしさはあるものの、このIAMが強固であるからこそ、外部からの不正アクセスや開発者の誤操作による大事故を未然に防げているのだと実感する。
CloudWatch
AWSのリソースやアプリケーションの稼働状況を監視し、ログを収集・記録する運用監視サービス
役割・使われ方
システム全体のログ管理や状態の監視をするような存在である。
EC2やECSのCPU使用率やメモリ残量をグラフで可視化したり、アプリケーションが出力したエラーログやアクセスログを1箇所に集約して保存したりする。また、システムに異常が発生した際(サーバーがダウンした、エラーが多発したなど)に、チャットツールへ自動でアラート通知を飛ばす司令塔としても使われる。
自分なりの使用感
開発中や本番運用時において、バグの原因調査で使用する頻度が高い必須のサービスである。
実務でも、プログラムが意図しない挙動をした際は、まずCloudWatchを開いて該当の時間帯のロググループを検索し、エラーのスタックトレースを追いかけるのが基本のワークフローになっている。
ログの量が多くなると目当ての行を探すのが難しくなるが、ログの検索機能(CloudWatch Logs Insights)を使いこなせるようになると、特定のエラーコードが含まれる行を一瞬でフィルタリングできるようになり、デバッグの速度が劇的に上がる。
インフラが正常に動いている時は意識しないが、いざトラブルが起きた時に「CloudWatchにログが正しく出力されていること」自体が、エンジニアにとって最大の命綱であり、運用の要であると感じる。
まとめ
これまで実務で触れてきた13個のAWSサービスについて、改めてその役割と自分なりの使用感を振り返ってみました。
今回、これらを整理してみて改めて実感したのは、現代のアプリケーション開発において、インフラ(AWS)の知識はもはや開発者にとっても必須のスキルであるということです。
EC2から始まった伝統的なサーバー構築から、ECSのようなコンテナ、Lambdaのようなサーバーレスへと時代が移り変わる中で、開発者が「OSのお守り」から解放され、より純粋な機能開発に集中できる環境が整ってきています。一方で、それに伴いIAMによる厳密な権限管理や、CloudFrontのキャッシュ制御、ALBのヘルスチェック設定など、アプリケーションとインフラが密接に絡み合う部分での「特有の難しさ(躓きポイント)」が増えているのも事実です。
最初は設定ファイル(YAMLやJSON、serverless.tsなど)の呪文に圧倒されるかもしれません。しかし、実務で向き合っていけば、これらは必ず「慣れ」で解決できるようになります。
AWSの最大の魅力は、豊富なサービスが揃っており、それらを組み合わせることで、どんな規模のシステムでも安全に、かつ迅速に形にできる点にあります。何でもかんでも一つのサービスで解決しようとするのではなく、各サービスのメリット・デメリット(制約)を正しく理解し、適材適所で組み合わせる目を養っていくことが、これからも重要だと感じています。
この記事が、これからAWSを触り始める方や、同じような構成で開発を進めている方のインスピレーションやトラブルシューティングの参考になれば幸いです。