いつの間にかCloudFormationがIAM Roleに対応していました!

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ウィスキー、シガー、パイプをこよなく愛する大栗です。

最近はほとんどCloudFormation職人と化しておりCloudFormationのテンプレートを書いているのですが、いつの間にかCloudFormationがアップデートされてIAM Roleに対応していたので確認してみます。
どうもWhat's New at AWSRelease Notes : Amazon Web Servicesにも記載がありませんでした。。。

AWS CloudFormation Service Role

何が嬉しいの?

今までCloudFormationでStackを作成するときに、実行するIAMユーザはCloudFormationのStack作成権限の他にStackで作成するリソースに対する作成権限が必要でした。CloudFormationテンプレートで定義していないリソースも作成できる権限を与える事になるので、操作を誤ると環境を破壊してしまう可能性がありました。
IAM Roleに対応するとCloudFormationの実行ユーザはCloudFormationに対する権限さえあればテンプレートで定義しているリソースを作成できるので、既存の環境を破壊する可能性が無くなります。

CloudFormationのIAM Role対応を試してみる

前提として、【アップデート】AWS CloudFormationでYAML形式をサポートしましたで作成したCloudFormationテンプレートを使用します。

Roleでのテンプレート起動を試す

ここではバージニアリージョンで実施しています。

2016/10/1時点では、東京とカルフォルニアでIAM Roleが使用できませんでした。すぐにデプロイしてくれると思います。
2016/10/4 18:50 JST現在では全リージョンでIAM Roleが使用可能になっているようです。

CloudFormationテンプレートは、以下の内容になります。先日書いたブログエントリー【アップデート】AWS CloudFormationでYAML形式をサポートしましたで作成したテンプレートを一部修正したものです。

cfn-role.yaml

AWSTemplateFormatVersion: 2010-09-09
Description: Linux Stack
Resources:
  Server01:
    Type: AWS::EC2::Instance
    CreationPolicy:
      ResourceSignal:
        Timeout: PT30M
    Properties:
      ImageId: ami-ce7508d9
      InstanceType: c4.large
      KeyName: KeyPairName
      UserData:
        Fn::Base64: !Sub |
          <script>
          cfn-init.exe -v -c install -s ${AWS::StackId} -r Server01 -c sample --region ${AWS::Region}
 
          </script>
    Metadata:
      AWS::CloudFormation::Init:
        configSets:
          sample:
          - KB3134758
          - vscode
          - finalize
        KB3134758:
          files:
            c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu:
              source: https://download.microsoft.com/download/2/C/6/2C6E1B4A-EBE5-48A6-B225-2D2058A9CEFB/Win8.1AndW2K12R2-KB3134758-x64.msu
          commands:
            wait:
              command: wusa.exe c:\cm\Win8.1AndW2K12R2-KB3134758-x64.msu /quiet /forcerestart
              cwd: C:\cm
              waitAfterCompletion: forever
        vscode:
          commands:
            a-set-execution-policy:
              command: powershell.exe -command Set-ExecutionPolicy RemoteSigned -Force
            b-find-package-provider:
              command: powershell.exe -command Find-PackageProvider -ForceBootstrap
            c-find-package:
              command: powershell.exe -command Find-Package -ForceBootstrap -Name VisualStudioCode -Provider chocolatey
            d-install-package:
              command: powershell.exe -command Install-Package -Name VisualStudioCode -Force
 
        finalize:
          commands:
            a-write-status:
              command: !Sub |
                  cfn-signal --exit-code 0 --region "${AWS::Region}" --resource Server01 --stack "${AWS::StackName}"

権限がないIAM ユーザで実行してみる

CloudFormationは起動権限はありますが、EC2の起動権限がないユーザで実行してみます。
権限は以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1475252396000",
            "Effect": "Allow",
            "Action": [
                "cloudformation:*",
                "s3:*",
                "iam:ListRoles",
                "iam:PassRole"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

テンプレートを実行します。途中IAM Roleを選択できる項目がありますが、無視して進めます。

Create_A_New_Stack

起動してみると途中で失敗してしまいます。

CloudFormation_Management_Console

Server01で表示されているエラーメッセージをManagement Consoleの権限不足エラーをデコードするの内容を元にデコードしてみます。

$ aws sts decode-authorization-message --encoded-message file://error.txt | jq -r '.DecodedMessage' | jq .

この様にec2:RunInstancesが失敗しています。

{
  "allowed": false,
  "explicitDeny": false,
  "matchedStatements": {
    "items": []
  },
  "failures": {
    "items": []
  },
  "context": {
    "principal": {
      "id": "ABCDEFGHIJKLMNOPQRSTU",
      "name": "cfn-role-test",
      "arn": "arn:aws:iam::123456789012:user/cfn-role-test"
    },
    "action": "ec2:RunInstances",
    "resource": "arn:aws:ec2:us-east-1:123456789012:instance/*",
    "conditions": {
      "items": [
        {
          "key": "ec2:Tenancy",
          "values": {
            "items": [
              {
                "value": "default"
              }
            ]
          }
        },
        {
          "key": "ec2:AvailabilityZone",
          "values": {
            "items": [
              {
                "value": "us-east-1a"
              }
            ]
          }
        },
        {
          "key": "ec2:Region",
          "values": {
            "items": [
              {
                "value": "us-east-1"
              }
            ]
          }
        },
        {
          "key": "ec2:ebsOptimized",
          "values": {
            "items": [
              {
                "value": "false"
              }
            ]
          }
        },
        {
          "key": "ec2:InstanceType",
          "values": {
            "items": [
              {
                "value": "c4.large"
              }
            ]
          }
        },
        {
          "key": "ec2:RootDeviceType",
          "values": {
            "items": [
              {
                "value": "ebs"
              }
            ]
          }
        }
      ]
    }
  }
}

IAM Roleの権限で実行してみる

まずはCloudFormation用のRolecfn-roleを作成します。『ロールタイプの選択』の『AWS サービスロール』にAWS CloudFormation Roleが追加されているのでこちらを選択します。

IAM_Management_Console

ここではアタッチするポリシーをAdministratorAccessにします。

IAM_Management_Console

ではCloudFormationを実行します。
IAM Roleで、先ほど作成したcfn-roleを選択します。

Create_A_New_Stack

先程エラーになっていたEC2の起動が成功します!

CloudFormation_Management_Console

さいごに

今までリソースの権限がないユーザがCloudFormationのStackを起動する時にIAM Roleを使うにはService Catalogを使う必要がありました。今回のアップデートによりService Catalogを使うような大げさな事をしなくてもIAM Roleの権限でリソースを起動できるようになりました。CloudFormationの実行ユーザには不要な権限を与える必要がなくなるので、誤操作などが発生しにくくなったのではないかと思います。