AWS Fault Injection Simulatorを使ってみる

# 1 AWS Fault Injection Simulatorってなに？
 - AWS FIS
 - フォルトインジェクションテストを実行することのできるフルマネージドサービス
 - AWSにて構築した環境にて障害を意図的に発生させることができ、その時のシステムの挙動を確認することができる
 - 結果より、システムの弱い点を洗い出し、機能やサービスのパフォーマンス向上につなげることができる

# 2 早速使っていく (チュートリアル編)
AWSのドキュメントを見ながらチュートリアルを進めていく
https://docs.aws.amazon.com/fis/latest/userguide/what-is.html

## 2.1 事前準備

### 2.1.1 テスト内容の決定
 - どのようなテストを実行するか決定する
 - 1つのテストに複数アクション、複数ターゲットを設定することができるが、組み合わせる必要のないものは分けて実験テンプレートを作成する方が良い


### 2.1.2 IAMポリシー、ロールの設定
 - デフォルトではAWS FISから各サービスを実行する権限がないため、設定していく

#### ロール
IAMロールを作成する

 - ユースケースにはFISがまだ並んでいないので、
    - AWSサービス
    - EC2
        - を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/0522aabc-2ce6-572e-9a88-22e3f83e3f0e.png)
 - ポリシーは一旦skip
    - 後で作成した物をアタッチする
 - タグは必要あればつける
    - ここではskip
 - ロール名等は好きな物を入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/b52f07a9-8958-1ec6-5f44-96b82f4a302d.png)
 - 作成を実行

そうすると、AWS サービス:ec2でロールが作成される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/5b5e9e8a-dae8-3355-7f07-99baf5881bf8.png)

fisへ変更するため、選択して編集する

 - 信頼関係タブを選択
 - 信頼関係の編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/d55c4337-e26b-31b0-041d-cecf0207ed5b.png)
 - 以下に置き換える

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "fis.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}
```
ここでロールARNをコピーしておく

#### ポリシーの作成1
 - JSONタブを選択
 - 以下をコピーして貼り付け

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "FISPermissions",
            "Effect": "Allow",
            "Action": [
                "fis:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ReadOnlyActions",
            "Effect": "Allow",
            "Action": [
                "ssm:Describe*",
                "ssm:Get*",
                "ssm:List*",
                "ec2:DescribeInstances",
                "rds:DescribeDBClusters",
                "ecs:DescribeClusters",
                "ecs:ListContainerInstances",
                "eks:DescribeNodegroup",
                "cloudwatch:DescribeAlarms",
                "iam:ListRoles"
            ],
            "Resource": "*"
        },
        {
            "Sid": "IAMPassRolePermissions",
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "arn:aws:iam::111122223333:role/roleName"
        },
        {
            "Sid": "PermissionsToCreateServiceLinkedRole",
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": "fis.amazonaws.com"
                }
            }
        }
    ]
}
```

以下の行は、先ほどコピーしたARNに置換する

```
"Resource": "arn:aws:iam::111122223333:role/roleName"
```

 - タグは必要あればつける
    - 今回はskip
 - 名前と説明をつけ、作成
    - 今回はこちら : AwsFisFullAccessPolicy
#### ポリシーの作成2
 - 以下の設定でポリシーを作成

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowFISExperimentRoleReadOnly",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ecs:DescribeClusters",
                "ecs:ListContainerInstances",
                "eks:DescribeNodegroup",
                "iam:ListRoles",
                "rds:DescribeDBInstances",
                "rds:DescribeDbClusters",
                "ssm:ListCommands"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowFISExperimentRoleEC2Actions",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:StopInstances",
                "ec2:StartInstances",
                "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "AllowFISExperimentRoleECSActions",
            "Effect": "Allow",
            "Action": [
                "ecs:UpdateContainerInstancesState",
                "ecs:ListContainerInstances"
            ],
            "Resource": "arn:aws:ecs:*:*:cluster/*"
        },
        {
            "Sid": "AllowFISExperimentRoleEKSActions",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*"
        },
        {
            "Sid": "AllowFISExperimentRoleFISActions",
            "Effect": "Allow",
            "Action": [
                "fis:InjectApiInternalError",
                "fis:InjectApiThrottleError",
                "fis:InjectApiUnavailableError"
            ],
            "Resource": "arn:*:fis:*:*:experiment/*"
        },
        {
            "Sid": "AllowFISExperimentRoleRDSReboot",
            "Effect": "Allow",
            "Action": [
                "rds:RebootDBInstance"
            ],
            "Resource": "arn:aws:rds:*:*:db:*"
        },
        {
            "Sid": "AllowFISExperimentRoleRDSFailOver",
            "Effect": "Allow",
            "Action": [
                "rds:FailoverDBCluster"
            ],
            "Resource": "arn:aws:rds:*:*:cluster:*"
        },
        {
            "Sid": "AllowFISExperimentRoleSSMSendCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:SendCommand"
            ],
            "Resource": [
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ssm:*:*:document/*"
            ]
        },
        {
            "Sid": "AllowFISExperimentRoleSSMCancelCommand",
            "Effect": "Allow",
            "Action": [
                "ssm:CancelCommand"
            ],
            "Resource": "*"
        }
    ]
}
```
 - 今回はこちらで名前を決定 : AwsFisAllowService

#### ロールにポリシーをアタッチ
 - 作成したロールに上記2つのポリシーをアタッチする
    - AwsFisFullAccessPolicy
    - AwsFisAllowService
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/0f3e296a-c6c7-a618-8ad5-a2113ea576d0.png)

これで権限の準備は完了

### 2.1.3 EC2インスタンスの作成
 - テスト用にEC2インスタンスを2つ立ち上げる
    - 特に何か指定があるわけではないので以下で作成する
        - インスタンスタイプ : t2.micro
        - AMI : Amazon Linux 2
        - タグ : 
            - (1台目) Name / FIStest01 
            - (2台目) Name / FIStest02
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/d3e08c66-52be-41a3-8922-f831528424a6.png)

これで検証用環境の準備は完了

### 2.1.4 CloudWatchの設定(任意)
後々CPU負荷テストを設定するため、CloudWatchにてアラームの設定をしておく (stopさせる)

作成したインスタンスに対して、とりあえずCPUUtilization(CPU使用率)で設定する(通知は設定するか、削除するかは好きな方でok)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/754f558c-e331-59e8-e098-5c8afb649de3.png)

アクションはEC2インスタンスの停止
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/f0947fa1-46ba-399d-9fa1-9bb0d85ce02c.png)

これでやっとFIS以外の事前準備は完了

## 2.2 実験テンプレート作成

今回、シンプルな実験を定義する
内容としては
1. EC2インスタンス1台停止
2. 1.の後にEC2インスタンス全停止
というフォルトインジェクション

 - 説明は適当な物を入力
    - IAM ロールは先ほど作成した物を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/34eacd91-f7eb-5a09-bfec-c9e2ff703591.png)
 - アクションを作成
    - ターゲットは後ほど変えるので、デフォルトのまま
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/4decd65d-f64c-c1ca-1b94-a0196c778d20.png)
 - デフォルトに設定されていたターゲットの編集
    - リソースIDは事前準備で作成したEC2インスタンスIDを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/96375ac3-0f75-8438-75ec-3b3064d71540.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/50a2167e-b62e-5029-4454-7cfe61748f44.png)
 - 新たなターゲットの追加
    - リソースIDは事前準備で作成したEC2インスタンスIDを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/71a39795-038b-8044-bf6d-3458513c1426.png)
 - 再度アクションの追加を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/33627be5-55e8-0591-a9aa-abb0d8c86f05.png)
 - 停止条件に先ほどCloudWatchで設定したアラームを設定する (任意)
    - これを設定しておくことで、アラームがなった時に実験を停止してくれる
    - 実験は実行時間で費用が発生するので思わぬ費用の発生を防ぐことができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/d9ae1cf6-c62b-1466-e782-65159571affe.png)

## 2.3 実験の開始

実験のテンプレートを選択し、実験の開始を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/f0f5ea49-03da-652a-bd7e-b7f9b6722262.png)

## 2.4 実験の確認
完了後、completedにステータスが変化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/5573360f-c706-75dd-9acc-c8147459262b.png)

今回EC2インスタンスをstopする実験だったが、実験完了後に自動的に起動するため、EC2を確認すると起動している
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/dfdcb10a-e4b5-3646-a0e1-19e0b95daee0.png)

メトリクスを確認すると途中にstopしていたことがわかる
(わかりづらいが、途中stopしていた)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115125/317c6a2f-d7cd-178d-f7b5-90510bde970a.png)


## 2.5 実験の後片付け
実験が完了完了したら不要なものは削除する

 - EC2インスタンス
 - IAMロール、ポリシー
 - 実験テンプレート
 - CloudWatchアラーム

# 3 Next
 - 今回、AWS FISにいついてチュートリアルを実行
 - Nextとしてはより実用的に使うためのアクションの設定方法を詳しくみていく
    - EC2インスタンスのstopだけでは実験としては十分な設計はできないため