[AWS初学者向け] AWSによるインフラ構築とCI/CD

## はじめに
今回初めて記事を投稿するにあたり、インプットした内容をアウトプットして学習した内容が理解できているか関連性があるかを確認するために記載しております。

## この記事の目的
今回はAWS初学者向けに基本的なソリューションアーキテクチャとCI/CD周りをAWSというサービスを用いながら説明していき、より理解を高めていこうというのが狙いです。
自分と同じようにAWSを触りながら学習してみたい方、AWSを使用したサービスを考えている方は参考にしていただけると幸いです。

## AWSを用いたインフラ構築
[AWS](https://aws.amazon.com/free/?trk=f181118c-0869-454a-84d2-63d0cf7146e3&sc_channel=ps&ef_id=Cj0KCQjwna6_BhCbARIsALId2Z3tOHodkJx87rBNcMFmt3knJ3bVEvcGsva8_0EVcF_SdLN9rKxLHyEaAohaEALw_wcB:G:s&s_kwcid=AL!4422!3!638125895456!e!!g!!aws!19068271377!141241695742&gclid=Cj0KCQjwna6_BhCbARIsALId2Z3tOHodkJx87rBNcMFmt3knJ3bVEvcGsva8_0EVcF_SdLN9rKxLHyEaAohaEALw_wcB&all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all)では数多くのサービスを提供しています。最近では生成AIやLLMの急速な人気によりクラウドサービスの需要も年々増加しています。そのため、AWSは今でも国内で最もシェアされているクラウドサービスとなっております。AWSを使用することでエンジニアとしてのキャリアアップも期待でき、今後も引き続きホットなテクノロジーとなり、急速な進化が期待できるため、早いうちにクラウドへの理解を深めておくことは自分自身のポテンシャルを底上げする大きなポイントとなってくると感じています。
そこで今回例題として、一般的なWebアプリケーションのインフラをAWSを用いて構築していき、皆さんの理解に貢献していければと思います。まず以下に図を示した上でそれぞれのサービスの特徴やベストプラクティス等を説明する形で進めていきます。

### 今回のアーキテクチャ例

<div style="text-aligh: center;">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4011715/c18e8fb2-554e-4858-be91-652e8f04456b.png" alt="aws solution architecture" />
</div>

今回はクライアント側がWebアプリにアクセスし記事の投稿や閲覧など基本的な動作ができるものを参考に作成しております。
まず初めに[Route53](https://aws.amazon.com/route53/)を使用してドメイン名を取得した後、[CloudFront](https://aws.amazon.com/cloudfront/)を用いて様々なAWSサービスと連携するような構造になっていることがわかります。ここに[Route53](https://aws.amazon.com/route53/)を用いる目的はドメイン名の登録と管理ができるサービスであり、トリフィックウェイト(weights)や地理位置情報(Geolocation)などのルーティングポリシィ(Routing Policy)を決めることができ、要件や仕様によりカスタムしやすいサービスとなっています。ここでさらに[CloudFront](https://aws.amazon.com/cloudfront/)を用いることでより高速なアクセスを期待することができ、[Route53](https://aws.amazon.com/route53/)と[CloudFront](https://aws.amazon.com/cloudfront/)のコンビは相性が良いと言えます。また[CloudFront](https://aws.amazon.com/cloudfront/)の特徴として一度アクセスしたものは[Edge Location](https://wa.aws.amazon.com/wellarchitected/2020-07-02T19-33-23/wat.concept.edge-location.en.html)の中にキャッシュとして一時的にアクセス可能となっているため、わざわざサーバを介すことなく、クライアントのリクエストに返すことができます。[Amazon S3](https://aws.amazon.com/s3/)や[AWS Lambda](https://aws.amazon.com/lambda/)、この後にも紹介する[ALB](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/)や[ECS](https://aws.amazon.com/pm/ecs/)に使用されCDN(Content Delivery Network)として使用されています。今回ここで使用されている[AWS Lambda](https://aws.amazon.com/lambda/)はOGP表示で使用されるもので、[CloudFront](https://aws.amazon.com/cloudfront/)との連携では[Lambda@Edge](https://aws.amazon.com/lambda/edge/)を使用することが推奨されており必然的に'us-east-1'のN. Virginiaリージョンでのみ使用が可能となっています。そのため図のように記載してあります。

続いて、中身の方について説明していきます！
今回は'ap-northeast-1'と呼ばれる東京リージョンの中にVPCを設けて、disaster recoveryのために2つのアベイラビリティゾーン(AZ)を用意しています。このどちらのprivate subnetに[リレーショナルデータベース(RDS)](https://aws.amazon.com/rds/)を用意することで、今稼働中のプライマリーAZに何らかの障害が起きた際には別のAZに同期していた[RDS](https://aws.amazon.com/rds/)を用意しておくことで、データ損失を防ぐことができ、可用性のあるインフラを構築することができます。
今回のアーキテクチャでは[Application Load Balancer(ALB)](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/)を用いてHTTP/HTTPSによるアクセスを可能にしています。[ALB](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/)では複数のターゲットグループを決めることができます。制約としてターゲットグループには[EC2](https://aws.amazon.com/pm/ec2/)、[ECS](https://aws.amazon.com/pm/ecs/), [AWS Lambda](https://aws.amazon.com/pm/lambda/)、IPアドレスとなっています。加えてトラフィックのため静的なドメイン名を提供する必要があるため、[Route53](https://aws.amazon.com/route53/)、[CloudFront](https://aws.amazon.com/cloudfront/)、[ALB](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/)は基本的なWebアプリケーションにおけるネットワーク構築をする上で必要最低限であることがわかります。
ここで[ECS](https://aws.amazon.com/pm/ecs/)から別のトラフィックを確認することができると思います。[ECS](https://aws.amazon.com/pm/ecs/)自体がコンテナのサービスであるため、Docker Imageが保存されている[Amazon ECR](https://aws.amazon.com/ecr/)とのトラフィックを結ぶ必要があります。しかしながらセキュリティ上の観点により、[ECS](https://aws.amazon.com/pm/ecs/)がprivate subnetに位置しているため、private subnetからインターネットへのアクセスを可能にする必要があります。そこで今回使用するのが、[Internet Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)と[NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)です。[Internet Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)自体はインターネットとのアクセスを可能にする役割を持ち、インバウンドとアウトバウンド両方のトラフィックを受け入れてくれます。そのためVPC上に位置しています。これだけではprivate subnetとのやりとりができないため、[NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)と呼ばれる、public subnetで使用されるサービスを用います。これはアウトバウンドのトラフィックのみを受け入れています。そのため、private subnetにある[ECS](https://aws.amazon.com/pm/ecs/)がインターネットに位置する[Amazon ECR](https://aws.amazon.com/ecr/)へアクセスすることができ、セキュアなインフラを構築することができます。[Internet Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Internet_Gateway.html)と[NAT Gateway](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)の間に[VPC-Router](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-route-tables.html)を使用しており、disaster recovery時にも対応することができます。

以上で今回の例に関する説明と基本的なベストプラクティスに基づくソリューションアーキテクトとなってるので、それぞれのサービスや機能を理解したい方は、それぞれのリンクに飛んでいただけるとより理解しやすいものになると感じています。

## CI/CD構築

上記のインフラ整備に加えてCI/CDの部分も押さえておこうと思います。今回の例を用いて以下に図式しておきます。

![complete_cicd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4011715/8b45c486-af45-46d4-85ce-ac67512288ee.png)

上記はデプロイ完了後の様子を表しています。大まかな構造としては、GitHubをレポジトリとして使用し、BuildとしてGitHub Actionsを使用する特徴になっています。Buildに成功した後[AWS CodeDeploy](https://aws.amazon.com/codedeploy/)で更新されたECS Taskを元にBlue/Greenによるtarget groupの更新を行なっています。これにより、新しく更新したものをリリースすることができ、CI/CDを担うことができています。
ここでBlue/Greenとは古いバージョンから新しいターゲットグループにトラフィックを変更し、デプロイ完了時には完全に新しいバージョンを使用することができるようになっています。デプロイに失敗した際には元の古いバージョンにトラフィックに対してロールバックしてくれるため、問題なく開発を進めることができます。ここでこのトラフィックを実現するにあたり[ALB](https://aws.amazon.com/elasticloadbalancing/application-load-balancer/)は必要不可欠なので、実際に仕様を決める際にはターゲットグループを決め、ECS taskの中にも記載することを忘れないようにしてください。このほかにも[In-place](https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/in-place-deployments.html)などがありますがこれは今動いているサーバーに対して直接アップーデートを行うものなのでダウンタイムが生じますがBlue/Greenと異なり、別途サーバーを用意することがないため、コスト面で優れているという特徴があります。
ここでAWSではCI/CD構築時に使用できる[AWS CodePipeline](https://aws.amazon.com/codepipeline/)やGitHub Repositoryの代わりに[AWS CodeCommit](https://aws.amazon.com/codecommit/)を使用したり、[AWS CodeBuild](https://aws.amazon.com/codebuild/)というテスト時に使用されるサービスなどこれ以外にも[AWS CodeArtifact](https://aws.amazon.com/codeartifact/)など様々なサービスが提供されているので仕様によって目的に合ったカスタマイズを変更することが可能になっています。

## さいごに
これ以外にもサーバーレスによる構築やbuild時失敗の通知などより便利で使いやすいインフラを整備することも可能なので、まだまだ奥が深いと感じました。自分は以下のコースを参考に学んで[AWS Certified Developer - Associate](https://aws.amazon.com/certification/certified-developer-associate/)と呼ばれる資格に挑戦し、合格することができたので初めにサービスを理解したいという方は勉強してみるのも良いのかもしれません。より専門的でサービスも限定されている方は、ハンズオン形式で学んでいきわからない箇所はリファレンスを読むなどして対策する手が良いかと思います。

https://www.udemy.com/course/aws-certified-developer-associate-dva-c01/?srsltid=AfmBOoqA4HBx-Fsv0OdYL6kf1hhrYSmcZRBVw9i-jmDK7k6K6TQHYmjH