[社内勉強会資料] CloudFormationで構築する自動デプロイ環境 ～ 4/6

# 第4回 CloudFormationテンプレートの実行（IAM）
さて第4回の今回は、本記事に記載のCFnテンプレートを用いて、自動デプロイの実行に必要な権限（IAMロール）を構築していきます。

前回：[[社内勉強会資料] CloudFormationで構築する自動デプロイ環境 ～ 3/6](https://qiita.com/toru-yamagishi/items/c9a2d877a5de553a4c4f)

## CloudFormationで作成するリソース
* CloudFormationテンプレートを使って、以下のAWSリソースを作成します
    * IAM
        * ManagedPolicy
    * S3
        * Bucket

## CloudFormationテンプレート
### policy.yaml
```yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: "Policy for pipeline works"

Parameters:
  ProjectName:
    Default: usecase-auto-deploy
    Type: String

Resources:

  IAMManagedPolicy:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "CodePipelineServicePolicy-${AWS::Region}-${ProjectName}"
      Path: "/service-role/"
      PolicyDocument: |
          {
              "Statement": [
                  {
                      "Action": [
                          "iam:PassRole"
                      ],
                      "Resource": "*",
                      "Effect": "Allow",
                      "Condition": {
                          "StringEqualsIfExists": {
                              "iam:PassedToService": [
                                  "cloudformation.amazonaws.com",
                                  "elasticbeanstalk.amazonaws.com",
                                  "ec2.amazonaws.com",
                                  "ecs-tasks.amazonaws.com"
                              ]
                          }
                      }
                  },
                  {
                      "Action": [
                          "codecommit:CancelUploadArchive",
                          "codecommit:GetBranch",
                          "codecommit:GetCommit",
                          "codecommit:GetUploadArchiveStatus",
                          "codecommit:UploadArchive"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "codedeploy:CreateDeployment",
                          "codedeploy:GetApplication",
                          "codedeploy:GetApplicationRevision",
                          "codedeploy:GetDeployment",
                          "codedeploy:GetDeploymentConfig",
                          "codedeploy:RegisterApplicationRevision"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "codestar-connections:UseConnection"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "elasticbeanstalk:*",
                          "ec2:*",
                          "elasticloadbalancing:*",
                          "autoscaling:*",
                          "cloudwatch:*",
                          "s3:*",
                          "sns:*",
                          "cloudformation:*",
                          "rds:*",
                          "sqs:*",
                          "ecs:*"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "lambda:InvokeFunction",
                          "lambda:ListFunctions"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "opsworks:CreateDeployment",
                          "opsworks:DescribeApps",
                          "opsworks:DescribeCommands",
                          "opsworks:DescribeDeployments",
                          "opsworks:DescribeInstances",
                          "opsworks:DescribeStacks",
                          "opsworks:UpdateApp",
                          "opsworks:UpdateStack"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "cloudformation:CreateStack",
                          "cloudformation:DeleteStack",
                          "cloudformation:DescribeStacks",
                          "cloudformation:UpdateStack",
                          "cloudformation:CreateChangeSet",
                          "cloudformation:DeleteChangeSet",
                          "cloudformation:DescribeChangeSet",
                          "cloudformation:ExecuteChangeSet",
                          "cloudformation:SetStackPolicy",
                          "cloudformation:ValidateTemplate"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Action": [
                          "codebuild:BatchGetBuilds",
                          "codebuild:StartBuild"
                      ],
                      "Resource": "*",
                      "Effect": "Allow"
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "devicefarm:ListProjects",
                          "devicefarm:ListDevicePools",
                          "devicefarm:GetRun",
                          "devicefarm:GetUpload",
                          "devicefarm:CreateUpload",
                          "devicefarm:ScheduleRun"
                      ],
                      "Resource": "*"
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "servicecatalog:ListProvisioningArtifacts",
                          "servicecatalog:CreateProvisioningArtifact",
                          "servicecatalog:DescribeProvisioningArtifact",
                          "servicecatalog:DeleteProvisioningArtifact",
                          "servicecatalog:UpdateProduct"
                      ],
                      "Resource": "*"
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "cloudformation:ValidateTemplate"
                      ],
                      "Resource": "*"
                  },
                  {
                      "Effect": "Allow",
                      "Action": [
                          "ecr:DescribeImages"
                      ],
                      "Resource": "*"
                  }
              ],
              "Version": "2012-10-17"
          }

  IAMManagedPolicy2:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "CodeBuildBasePolicy-${AWS::Region}-${ProjectName}"
      Path: "/service-role/"
      PolicyDocument: !Sub |
          {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Resource": [
                          "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*"
                      ],
                      "Action": [
                          "logs:CreateLogGroup",
                          "logs:CreateLogStream",
                          "logs:PutLogEvents"
                      ]
                  },
                  {
                      "Effect": "Allow",
                      "Resource": [
                          "arn:aws:s3:::codepipeline-${AWS::Region}-*"
                      ],
                      "Action": [
                          "s3:PutObject",
                          "s3:GetObject",
                          "s3:GetObjectVersion",
                          "s3:GetBucketAcl",
                          "s3:GetBucketLocation"
                      ]
                  }
              ]
          }

  IAMManagedPolicy3:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "CodeBuildCloudWatchLogsPolicy-${AWS::Region}-${ProjectName}"
      Path: "/service-role/"
      PolicyDocument: !Sub |
          {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Resource": [
                          "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:codebuild",
                          "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:codebuild:*"
                      ],
                      "Action": [
                          "logs:CreateLogGroup",
                          "logs:CreateLogStream",
                          "logs:PutLogEvents"
                      ]
                  }
              ]
          }

  IAMManagedPolicy4:
    Type: "AWS::IAM::ManagedPolicy"
    Properties:
      ManagedPolicyName: !Sub "CodeBuildManagedSecretPolicy-${AWS::Region}-${ProjectName}"
      Path: "/service-role/"
      PolicyDocument: !Sub |
          {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Effect": "Allow",
                      "Action": [
                          "ssm:GetParameters"
                      ],
                      "Resource": "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/CodeBuild/*"
                  }
              ]
          }

  S3Bucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: !Sub "codepipeline-${AWS::Region}-${ProjectName}"
```

## CFn・ステップ1
1. テンプレートの準備で「テンプレートの準備完了」を選択します。
1. テンプレートの指定で「テンプレートファイルのアップロード」を選択します。
1. テンプレートファイルのアップロードで「policy.yaml」(上記) をアップロードします。
1. [次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/4dff92ab-5df1-7f7c-8e36-1aac77bd417c.png)

## CFn・ステップ2
1. スタック名に「usecase-auto-deploy-policy」を指定します。
1. [次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/d8f6a48b-36d2-a674-a17e-a75e75089748.png)

## CFn・ステップ3
1. スタックのオプションは変更せず、画面下部のチェックを入れて「スタックの作成」へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/61ddfb5f-927b-fd6b-7b13-586aee96efd3.png)

## CFn・ステップ4
1. スタックの作成を実行すると、スタックの一覧に作成したCfnスタックの進捗状況が表示されます。
※作成するリソースの内容によって所要時間は変わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/265cee06-d000-0fae-bd63-bb4a9e7ac57e.png)

## CFn・ステップ5
スタックの作成が成功すると、「CREATE_COMPLETE」のステータスになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/16674928-b8c9-8a9a-6387-bc670c8f94a0.png)

## CFn・ステップ6
「リソース」タブからCfnで作成されたリソースの内容を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2349569/9f8fcddc-aed8-d0bf-8be7-602041b05659.png)

連載の第4回となる今回はここまで。

次回第5回は、自動デプロイ（CodePipeline）を構築していきます。

次回：[[社内勉強会資料] CloudFormationで構築する自動デプロイ環境 ～ 5/6](https://qiita.com/toru-yamagishi/items/52e1d2719edbefdcc73e)