toraMasa's blog

toraMasa’s blog

新真虎のテックブログ

AWSのハンズオン色々やってみる#2 Well-Architected-Framework編

背景/目的

  • AWS上でProduction Workloadを動かすためにHigh Availableなアプリケーションを動かすにはどうすればいいか」について学びたかった
  • Well-Architected Frameworkのデモの一部で、EC2, RDS, Availability Zoneそれぞれの障害に対してどのようにして立ち向かえば良いのか。ということについて概要を掴む

Well-Architected Frameworkとは?

ハンズオン 'LEVEL 300: TESTING FOR RESILIENCY OF EC2, RDS, AND AZ'

introduction

  • 'Everything fails, all the time'というアマゾンのCTOの@Wernerの言葉が面白かった

1 DEPLOY THE INFRASTRUCTURE AND APPLICATION

1.1 AWSコンソールにログインします

  • AWS EduでやろうとしたらIAM作成の権限がなくて詰んだので、個人のアカウントで進めることにした
    • コンソールへのログイン権限はオプショナルって書いてあるけど、多分必須
    • あとこれはあんま良くないかもだけど、PowerUserAccessポリシーだけだとうまくいかなかったのでAdministratorAccessポリシーつけた

1.2既存のサービスにリンクされたロールの確認

  • サービスにリンクされたロール用にCloudFormationをセットアップするってのにめっちゃ詰まった
    • よく見たらこの段階ではすでにリンクされてるロールを確認するだけで良かった

1.3「デプロイメントマシン」を作成する

  • スタック名コピーするとスペースが謎に入っててエラーでるので注意
  • なぜかRollBackされた(TOT) ✕ 5
    • LambdaCustomResourceRole-SecureSsmForRds already exists
    • The following resource(s) failed to create: [WebAppLambdaRole, StateExecutionRole, AutoScalingServiceRole, VPCLambdaRole, RDSLambdaRole, LambdaCustomResourceRole, RDSRRLambdaRole, WaitForStackLambdaRole, DMSLambdaRole]. . Rollback requested by user.
    • 単一リージョンにしたり設定いじってもだめ。。。
    • CloudFormationテンプレートをいじったらいけた。
"LambdaCustomResourceRole": {
      "Type": "AWS::IAM::Role",
      "DeletionPolicy" : "Retain",
      "Properties": {
          "RoleName": "LambdaCustomResourceRole-SecureSsmForRds",//←これを違う名前に変える
          "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Principal": {
                          "Service": [
                              "lambda.amazonaws.com"
                          ]
                      },
                      "Action": [
                          "sts:AssumeRole"
                      ]
                  }
              ]
          },

1.4インフラストラクチャをデプロイしてサービスを実行する

  • カッコいい!!
    • マルチリージョンだとインフラとサービスの展開に1時間弱かかるので注意が必要。
  • 失敗した
{
  "error": "Something failed to deploy",
  "cause": "DeploymentFailed"
}
  • いや、それじゃわからん(TOT)
  • 色々ログを見てたら次のメッセージを発見
Exception=[class software.amazon.awssdk.services.kms.model.KmsException] ErrorCode=[AccessDeniedException], ErrorMessage=[An error occurred (AccessDeniedException) when calling the CreateKey operation: You don't have the kms:TagResource permission that is required to add tags during key creation.]

f:id:toraMasa:20200830184749p:plain

試したこと

  • kms:TagResourceを追記
  • RoleNameが消えてないみたいなので前のと変える
  • これでスタックに積んであるResiliencyVPCとMySQLforResiliencyTestingは通ったが、失敗には変わらず。。。
  • 失敗してそうなDeployRDS2にログがない
  • DeployFailedState2のログ
{
  "log_level": "DEBUG",
  "region_name": "us-west-2",
  "secondary_region_name": "us-east-2",
  "cfn_region": "us-east-2",
  "cfn_bucket": "aws-well-architected-labs-ohio",
  "folder": "Reliability/",
  "workshop": "300-ResiliencyofEC2RDSandS3",
  "boot_bucket": "aws-well-architected-labs-ohio",
  "boot_prefix": "Reliability/",
  "websiteimage": "https://s3.us-east-2.amazonaws.com/arc327-well-architected-for-reliability/Cirque_of_the_Towers.jpg",
  "vpc": {
    "stackname": "ResiliencyVPC",
    "status": "ROLLBACK_FAILED"
  }
}
  • わからんw
    • スタックではResiliencyVPCは成功している

単一リージョンでやり直してみる

CloudFormationテンプレートの値をいじる

  • LambdaCustomResourceRole-SecureSsmForRdsを毎回違う値にする
  • Policiesを編集
"Policies" : [ {
          "PolicyName" : "CreateVPC",
          "PolicyDocument" : {
            "Statement" : [ {
              "Effect" : "Allow",
              "Action" :  [
                (中略)
                "kms:TagResource",//これを追記
                (中略)
              ]
            }
            ]
          }
}
]

ステートマシンを作り直して再実行

  • できた!!(TOT) f:id:toraMasa:20200830184728p:plain
  • クロスリージョンの復元力のテストもしたかったけどやむなし。

  • と思ったらWebServersForResiliencyTestingが失敗してた(TOT)

    • ここまで6時間
The default Service-Linked Role for Auto Scaling could not be created.
  • CreateServiceLinkedRoleがfalseになってるから?
    • "WebAppLambdaRole" > "Policies" > "Action"に"iam:CreateServiceLinkedRole"を追加した
    • WaitForVPCStackでこけた
    • TypeError: not all arguments converted during string formatting
    • これによるとCreateServiceLinkedRoleはautoscaling policiesに関係してるっぽいのでtrueにして作り直した

1.5テストWebサービスのWebサイトを表示する

2 CONFIGURE EXECUTION ENVIRONMENT

2.1 AWS認証情報と設定をセットアップする

  • これbashだけでいいのかな?それともbash + なにかなのかな?
    • bashだけで良い。どれか一つで良い。

2.2 bash環境を設定する

  • 特になし。

2.3プログラミング言語環境をセットアップする(PythonJava、C#、またはPowerShell用)

  • skip

3 PREPARATION FOR FAILURE INJECTION

準備

  • ページを何回かリロードするとAZとinstance_idが変わることを確認。

4 TEST RESILIENCY USING EC2 FAILURE INJECTION

4.1 EC2障害の挿入

  • fail_instance.shを実行したら
You must specify a region. You can also configure your region by running "aws configure".
  • AWS CLIを使用するための初期設定をしていませんでした。
$ aws configure
AWS Access Key ID [None]: <Access Key ID>
AWS Secret Access Key [None]: <Secret Access Key>
Default region name [None]: us-east-2
Default output format [None]: json
  • もう一回実行
./fail_instance.sh <vpc-id>
  • 実行結果
{
    "TerminatingInstances": [
        {
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "InstanceId": "i-0ba4f56494209d445",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
  • なんか1個増えたけどいいのか?! f:id:toraMasa:20200830184837p:plain
    • Amazon EC2 Auto Scalingがすべてのアベイラビリティーゾーン全体のバランスを自動的に維持したっぽい
    • てかそれを確認するための作業だった笑

4.2 EC2インスタンスの失敗に対するシステムの応答

4.2.1システムの可用性

  • ウェブサイトは引き続き利用可能→OK
  • 残りの2つのEC2インスタンスは、すべてのリクエストを処理しています→3つのインスタンスが動いてるんだけど?笑

4.2.2負荷分散

  • 異常から自動で回復していることがわかります。 f:id:toraMasa:20200830184851p:plain

4.2.3自動スケーリング

4.2.4 EC2障害の挿入-結論

  • 複数のサーバーとELBをデプロイしたことによって、特定のサーバーに異常が発生したとしても、自動で正常なサーバーにトラフィックが割り振られることを確認した。
  • AWS Auto Scalingが異常なホストを削除し、正常なホストに置き換えることを確認した。
  • それによって、高い可用性が実現されていることを確認した。

5 TEST RESILIENCY USING RDS FAILURE INJECTION

5.1 RDS障害の挿入

  • 以下のコマンドを実行。
./failover_rds.sh <vpc-id>
  • 実行結果は長いので省略するが、コンソールにこれが出ればOK
Failing over md5fz4eklwy6vh

5.2 RDSインスタンス障害に対するシステムの応答

  • 上記を実行してwebページを読み込むと、応答しなくなる。
    • しばらくして(といっても数十秒)再度読み込むと、504が出る。
      • (同上)502に変化
        • ページが正常に表示されるようになる。フェイルオーバーが完了したということ。
  • フェイルオーバーが完了すると、プライマリインスタンスとスタンバイインスタンスが入れ替わる。
  • ログからも、フェイルオーバーの完了を確認
August 30th 2020, 6:34:49 am UTC
Multi-AZ instance failover started.
August 30th 2020, 6:35:09 am UTC
DB instance restarted
August 30th 2020, 6:35:43 am UTC
Multi-AZ instance failover completed

f:id:toraMasa:20200830184919p:plain

  • Target GroupとAuto Scaling Groupのコンソールでもフェイルオーバーを確認した。

5.2.4 RDS障害挿入-結論

  • RDSのDBのフェイルオーバーは1分未満で完了することを確認した。
  • Auto Scalingが異常を検知し、新しいインスタンスを立ち上げるのに??分くらいかかった。
  • つまり、RDSに障害が発生した場合、約??分サービスは利用不可状態である、ということ。
    • ハンズオンの資料には4分って書いてあるけど、1分30秒くらいで自分はできた。

5.2.5 [オプション] RDS障害挿入-回復力の向上

6 TEST RESILIENCY USING AVAILABILITY ZONE (AZ) FAILURE INJECTION

6.1 AZ失敗の挿入

シナリオ1

$./fail_az.sh us-east-2c <vpc-id>

シナリオ2

./fail_az.sh us-east-2b <vpc-id>

6.2 AZ障害に対するシステムの応答

シナリオ1

  • シナリオ1では、プライマリDBインスタンスのあるAZとは異なるAZを停止させる。
  • Webサイトは中断することなく表示される。
  • ちょっとよくわかんない

シナリオ2

  • Webサイトにアクセスできないことを確認
    • RDS障害のテストと同じ。フェイルオーバーしてAuto Scalingで新しいインスタンスが立ち上がるまで、Webサイトはアクセス不可能になる。

結論

  • 複数のAZにWebシステムのすべての層が存在するため、一つのAZが完全に(もしくはALBとWebサーバーが)機能停止しても、サービスを提供し続けることができる。

7 TEST RESILIENCY USING FAILURE INJECTION - OPTIONAL STEPS

  • S3については独自のものを使わなかったのでここはスキップした。

8 TEAR DOWN THIS LAB

  • 環境も一旦残しておくことにした。 - ちなみに、このハンズオンを通じてお金は特にかかりませんでした(無料期間中) →このワークショップで作った環境を一ヶ月放置すると無料期間中でも70ドルくらいかかるみたいです。絶対消しましょう。

トラブルシューティング

わからなかったところ調べた

学び( != 感想。技術的な学びをかく)

  • AWSのWell-Architected Frameworkにおける、EC2,RDS,AZそれぞれの障害に対する回復のテストを通じて、High Availableなアプリケーションを実現するためのアーキテクチャについての知見を得られた。

感想

  • Cloud Formationかっこいい
    • Cloud Formationに限らず、infra as codeってかっこいい
  • セットアップ済みのアカウントみたいな探してやったほうがよかったかも?
  • メンテとかされてなかったのか、辛いハンズオンだった
    • すらすら行くより勉強になったかもw
    • 費やした時間のほとんどが一章。。。笑

ネクストアクション

  • CloudFormation Templateを深堀り
  • サーバーレスについて勉強する
  • (AWSの資格の本読んで見る)
  • ALBとは読む

謝辞

  • インターン先の先輩にこのハンズオンを教えて頂きました。ありがとうございました。