AWS Certified Developer - Associate対策用のメモ

こんにちは。
[AWS Certified Developer - Associate](https://aws.amazon.com/jp/certification/certified-developer-associate/)を勉強中の者です。

ちょうど忘れそうな設定がいくつか出てきましたので私的にまとめています。
合格するまでは追記される予定です。
【2023/12/03追記】
合格しました。
【追記ここまで】

SAA（ソリューションアーキテクト）用のメモはこちら↓もご参考ください。
[【2023年5月最新版】EC2のインスタンス購入オプションはよく改定される【幕末】](https://qiita.com/hollage0214/items/5290a37c23e86fc24916)

----

# EC2（Elastic Compute Cloud）
## 課金体系
* 問題1：EC2インスタンスを35秒利用しました。何秒分請求されますか？
    1. 0秒
    1. 30秒
    1. 35秒
    1. 60秒
    →　正解：0秒
　
* 問題2：EC2インスタンスを135秒利用しました。何秒分請求されますか？
    1. 0秒
    1. 120秒
    1. 135秒
    1. 180秒
    →　正解：135秒
　
* 解説
[Amazon EC2 料金](https://aws.amazon.com/jp/ec2/pricing/)
> __EC2 の使用は、1 秒単位で課金され、最小課金時間は 60 秒です。__


# Elastic Load Balancer
## 種類
ELBはこれらをサポートします。
* [Application Load Balancer（ALB）](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancers.html)
* [Network Load Balancer（NLB）](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/network-load-balancers.html)
* [Gateway Load Balancer（GLB）](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/gateway/gateway-load-balancers.html)
* [Classic Load Balancer（CLB）](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environments-cfg-clb.html)
※CLBは前時代のロードバランサーなので新しく使い始めるのは超レアケースです。


## クロスゾーン負荷分散
有効・無効を切り替えることができます。
AZ1にEC2が2インスタンス、AZ2に8インスタンスあるとした場合、

__有効なときはインスタンス単位でワークロードを分散__ します。
つまり各インスタンスに10%ずつ振り分けます。

__無効なときはAZ単位でワークロードを分散__ します。
つまりAZ1の各インスタンスには25%ずつ、AZ2の各インスタンスには6.25%ずつ振り分けます。

__ALBを使用するとクロスゾーンのロードバランシングが常に有効になります。__
__NLB, GLBを使用するとクロスゾーンのロードバランシングがデフォルトで無効になります。__

[Elastic Load Balancing の仕組み](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/appinsights-metrics-elb.html)
　
# CDK（Cloud Development Kit）
プログラミング言語を使ってインフラを定義できるパッケージで、IaC（Infrastructure as Code）にカテゴライズされます。
JavaScript, TypeScript, Python, Java, Go, C#, .NETなどに対応。
[AWS CDK](https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html)

これでFargateタイプのECSタスクを、CloudFormation経由でデプロイできるようになります。

<details><summary>サンプルコード</summary>

```Java:MyEcsConstructStack.java
// ソースは上記リンクから
public class MyEcsConstructStack extends Stack {

    public MyEcsConstructStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyEcsConstructStack(final Construct scope, final String id,
            StackProps props) {
        super(scope, id, props);

        Vpc vpc = Vpc.Builder.create(this, "MyVpc").maxAzs(3).build();

        Cluster cluster = Cluster.Builder.create(this, "MyCluster")
                .vpc(vpc).build();

        ApplicationLoadBalancedFargateService.Builder.create(this, "MyFargateService")
                .cluster(cluster)
                .cpu(512)
                .desiredCount(6)
                .taskImageOptions(
                       ApplicationLoadBalancedTaskImageOptions.builder()
                               .image(ContainerImage
                                       .fromRegistry("amazon/amazon-ecs-sample"))
                               .build()).memoryLimitMiB(2048)
                .publicLoadBalancer(true).build();
    }
}
```
</details>
　

# SAM（Serverless Application Model）
CloudFormationをもっと便利に使うためのもの。
yamlにアプリケーションやデプロイの方法を記述してテンプレート化します。
Lambda, API Gateway, DynamoDBをローカルで実行する際にも使われます。
yamlに __Transform: AWS::Serverless-2016-10-31__ の記述があればSAM確定。
[SAM](https://aws.amazon.com/jp/serverless/sam/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html)
　

# CodeCommit
プライベートGitリポジトリをホストするサービスで、Gitからの移行も容易。
月間5人のアクティブユーザまでは無料で利用できるが、6人以上のユーザーがいる場合は6人目から$1.00/人掛かるので、そこそこ高価。
[CodeCommit](https://aws.amazon.com/jp/codecommit/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/welcome.html)


# CodePipeline
AWS内でCI/CDを実現するためのツール。
ソースはここ、テストはここ、デプロイ先はここ、と言った情報を指定してCI/CDを実現します。
CodeDeploy, Beanstalk, CloudFormation, ECS, S3などと連携できます。
1. GitHubへソースをpushする
1. 上司による手動承認を行う
1. コードビルドとテストをJenkinsで処理して、成果物をS3にアップロードする
1. ECS上でデプロイ
と言った手段を自動化して、
1. エラーが発生したらSNSで開発チーム全体に通知する

なんてことも可能です。
[CodePipeline](https://aws.amazon.com/jp/codepipeline/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/welcome.html)


# CodeBuild
buildspec.ymlにビルド手順を記述して実行することで定型的なビルド作業を行いCI/CDを実現します。

<details><summary>buildspec.ymlのサンプルコード</summary>

```yaml:buildspec.yml
version: 0.2

run-as: Linux-user-name

env:
  shell: shell-tag
  variables:
    key: "value"
    key: "value"
  parameter-store:
    key: "value"
    key: "value"
  exported-variables:
    - variable
    - variable
  secrets-manager:
    key: secret-id:json-key:version-stage:version-id
  git-credential-helper: no | yes

proxy:
  upload-artifacts: no | yes
  logs: no | yes

batch:
  fast-fail: false | true
  # build-list:
  # build-matrix:
  # build-graph:
        
phases:
  install:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    runtime-versions:
      runtime: version
      runtime: version
    commands:
      - command
      - command
    finally:
      - command
      - command
    # steps:
  pre_build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
    # steps:
  build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
    # steps:
  post_build:
    run-as: Linux-user-name
    on-failure: ABORT | CONTINUE
    commands:
      - command
      - command
    finally:
      - command
      - command
    # steps:
reports:
  report-group-name-or-arn:
    files:
      - location
      - location
    base-directory: location
    discard-paths: no | yes
    file-format: report-format
artifacts:
  files:
    - location
    - location
  name: artifact-name
  discard-paths: no | yes
  base-directory: location
  exclude-paths: excluded paths
  enable-symlinks: no | yes
  s3-prefix: prefix
  secondary-artifacts:
    artifactIdentifier:
      files:
        - location
        - location
      name: secondary-artifact-name
      discard-paths: no | yes
      base-directory: location
    artifactIdentifier:
      files:
        - location
        - location
      discard-paths: no | yes
      base-directory: location
cache:
  paths:
    - path
    - path
```
</details>

[CodeBuild](https://aws.amazon.com/jp/codebuild/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-spec-ref.html)
　

# CodeDeploy
EC2、Lambda、ECS、オンプレサーバーなどへのソフトウェアデプロイを自動化するサービスです。
appspec.ymlと言う設定ファイルを利用できます。
特によく出題されるのは
・デプロイ方法とコストの問題
・Lambdaとエイリアスを使った問題
と思います。

1. AllAtOnce
    1. 新バージョンに直ぐに移行する
　
1. HalfAtTime
    1. 半分のインスタンスを停止してアップデートする
    1. 完了後、残り半分のインスタンスを停止してアップデートする
　
1. OneAtATime
    1. 1つのインスタンスをアップデートする
    1. 1をインスタンス数分繰り返す
　
1. Blue-Green
    1. ALBが現在のバージョンを指しているものとは別に、アップデートバージョンのインスタンスを起動する
    1. ALBが新バージョンを指すように切り替える
    1. 旧バージョンのインスタンスを停止する
　
1. Linear（リニア）
    1. Lambdaの新旧バージョンにエイリアスを設定する
    1. CodeDeployがトラフィックを __徐々に__ 新バージョンに移行させる
        * LambdaLinear10PercentEvery3Minutes
        * LambdaLinear10PercentEvery10Minutes
　
1. Canary（カナリア）
    1. Lambdaの新旧バージョンにエイリアスを設定する
    1. 少量のトラフィックを新バージョンに移行させる
    1. 問題なければ新バージョンにトラフィックを100%移行させる
        * LambdaCanary10Percent5Minutes
        * LambdaCanary10Percent30Minutes

いくつかデメリットを挙げると、
* AllAtOnceは移行した後にテストする時間がないため、デプロイに失敗した場合全てがロールバックされる
* HalfAtTimeは __一時的にインスタンス数が減少する__ ため、元々の処理能力がカツカツの場合サーバーダウンする可能性がある
* OneAtATimeはインスタンス数が多い時に時間が掛かる
* Blue-Greenは __一時的にインスタンス数が増加する__ ため、余分なコストがかかる
* Linearは完全に移行するまでに時間が掛かる（Every10Minutesの場合は100分）
* Canaryは移行後の新バージョンのテスト工程が多い場合のコストが大きい

<details><summary>appspec.ymlのサンプルコード</summary>

```yml:appspec.yml
version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/html/WordPress
hooks:
  BeforeInstall:
    - location: scripts/install_dependencies.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/change_permissions.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
    - location: scripts/create_test_db.sh
      timeout: 300
      runas: root
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 300
      runas: root
```
</details>

[デプロイ戦略の詳細 - ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/deployment-configurations.html)
[CodeDeploy](https://aws.amazon.com/jp/codedeploy/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/welcome.html)
　



# CloudFormation
Infrastructure as Code（IaC）の一つです。
インフラをコード化できるようになるためテンプレートのバージョン管理もできるようになります。
スケジュール管理できないくらいの頻度で同じ構成のインスタンスを起動したいなどと言った場合にも使えますね。
ご存じの方も多いと思いますが、後述するElastic Beanstalkは裏でCloudFormationが走っています。
忘れがちな項目はテンプレート内で動的に利用する関数達です。
* !Ref
パラメータの論理名を指定するとパラメータの値を、
リソースの論理名を指定するとリソースを参照するための物理IDを、
組み込み関数を指定するとその関数の出力を返します。

以下の例の場合、セキュリティグループを別の場所に設定していますね。
今回は [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-instance.html#aws-resource-ec2-instance-return-values) を指定しているので返り値はリソースIDを返します。

<details><summary>!Refのサンプルコード</summary>

```yml:sample.yml
AWSTemplateFormatVersion: 2010-09-09

# リソースの設定
Resources:
  SampleInstance:
    Type: AWS::EC2::Instance
    Properties:
      AvailabilityZone: ap-northeast-1
      SecurityGroups:
        - !Ref SampleSecurityGroup

# セキュリティグループの設定
SampleSecutiryGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: This is sample SG.
```
</details>
　

* GetAtt
[Fn::GetAtt](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html)
GetAttribute（属性）の略称です。
先ほどの [AWS::EC2::SecurityGroup](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-instance.html#aws-resource-ec2-instance-return-values) に対してGetAttをコールするとAvailabilityZoneやPrivateDnsNameなどなどを取得することができます。

[CloudFormation](https://aws.amazon.com/jp/cloudformation/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/Welcome.html)
　

# Elastic Beanstalk
例えばフロントにロードバランサーを置き、EC2やLambdaにトラフィックが送られ、それらが後方のプライベートVPCにあるデータベースにアクセスするといったようなアーキテクチャは多くありますが、毎回AWS Management Consoleからメンテナンスするのは非常に面倒ですし、操作ミスが起こる可能性も往々にしてあります。
それらをテンプレート化して再利用できるようにしたサービスがElastic BeansTalkです。
Beanstalk自体の利用料は無料ですが、Beanstalk経由で起動されるサービスは当然コストがかかります。

[Elastic Beanstalk](https://aws.amazon.com/jp/elasticbeanstalk/)
[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html)