Skip to Content

CloudFormationでIAMロール作成と、インスタンスプロファイルを学ぶ

概要

CloudFormationで作成したIAMロールがEC2のIAMロール設定画面に表示されない
その対応と原因からIAMロールについて学ぶ

結論

IAMロール、IAMポリシーの他にインスタンスプロファイルの作成が必要
インスタンスプロファイルについては下記のブログポストが参考になる
EC2にIAMRole情報を渡すインスタンスプロファイルを知っていますか? | Developers.IO

状況

CloudFormationでIAMロールを作成をはじめて試みた
作成したリソースは下記の2点

  • Route53の一部権限を与えたIAMポリシーを作成
  • 上記ポリシーをアタッチしたEC2用のロールを作成

Resourcesの部分を抜粋

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Resources:
  # Create IAM Role
  IamRole1:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref IamRoleName1
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Tags:
        - Key: Project
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment
  # Create IAM Policy
  IamPolicy1:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: !Ref IamPolicyName1
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - route53:GetChange
              - route53:ChangeResourceRecordSets
              - route53:ListResourceRecordSets
            Resource:
              - arn:aws:route53:::hostedzone/*
              - arn:aws:route53:::change/*
          - Effect: Allow
            Action: route53:ListHostedZonesByName
            Resource: arn:aws:route53:::hostedzone/ZZZZZZZZZZZZZZZZ
      Roles:
        - !Ref IamRole1

IAMのコンソールからロールが作成されていることは確認済み
EC2インスタンスにロールを設定しようとしたところリストに表示されない
手動でロール作ったときはこんなことなかったのに…

IAMロールと、インスタンスプロファイル

EC2インスタンスとIAMロールの関係について勉強からはじめる
原因はIAMロールの知識不足でインスタンスプロファイルの作成が必要だった

EC2にIAMRole情報を渡すインスタンスプロファイルを知っていますか? | Developers.IO

想像していたロールのイメージ

EC2に直接IAMロールをアタッチしているだけだと思っていた

実際のロールのイメージ

EC2とIAMロールの間にインスタンスプロファイルがあり、それが両者を結ぶ

  • IAMロールはインスタンスプロファイルに格納(関連付けされる)
  • EC2はインスタンスプロファイルを通してIAMロールの情報をもらう

インスタンスプロファイルの使用 - AWS Identity and Access Management

インスタンスプロファイル新規作成を追加

ドキュメント参考に最低限必要なリソースを追加したテンプレートを作成

AWS::IAM::InstanceProfile - AWS CloudFormation

さきほどのテンプレートに下記を追加

1
2
3
4
5
6
7
  # Create Instance Profile
  InstanceProfile1:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref IamRole1

実行結果

EC2インスタンスのIAMロール設定画面に項目が追加された
しかし、なぞのロール名になっている
lego-roleの部分は自分で決めたIAMロールの名前ではあるがInstanceProfileなんたらとは一体

なぞのロール名

コンソール画面から手動でIAMロール作成時はIAMロールと同じ名前の名前を付けて、
インスタンスプロファイルが自動作成されており、普段意識しない部分だった

インスタンスプロファイル新規作成修正版

プロファイル名を付けるプロパティ(InstanceProfileName)を1行追加
さきほどは必須要素ではなかったため省略していた
インスタンスプロファイルの名前はIAMロールと同じにしたいので変数で同じ名前を使う

1
2
3
4
5
6
7
8
  # Create Instance Profile
  InstanceProfile1:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: !Ref IamRoleName1
      Path: /
      Roles:
        - !Ref IamRole1

実行結果

IAMロールと同じ名前のインスタンスプロファイルが作成され、
EC2インスタンスのIAMロール設定画面に項目が追加された
よくみるとProfile Nameと書いてあり、もともとインスタンスプロファイル名が表示されていたことに気づいた

最終的なIAMロール作成テンプレート例

Create IAM Policy以下のポリシーを変更すれば、EC2インスタンスに設定するIAMロールの作成に応用ができます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Create IAM Policy *1, Instance Profile *1, IAM Role *1

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: Common Settings
        Parameters:
          - ProjectName
          - Environment

Parameters:
  ProjectName:
    Description: Project name needs to be changed
    Type: String
    Default: Untitled Project
  Environment:
    Description: Project Environment
    Type: String
    Default: Development
    AllowedValues:
      - Production
      - Staging
      - Development
  IamPolicyName1:
    Type: String
    Default: Route53EditPolicy
  IamRoleName1:
    Type: String
    Default: Route53EditRole

Resources:
  # Create IAM Role
  IamRole1:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref IamRoleName1
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Tags:
        - Key: Project
          Value: !Ref ProjectName
        - Key: Environment
          Value: !Ref Environment
  # Create Instance Profile
  InstanceProfile1:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: !Ref IamRoleName1
      Path: /
      Roles:
        - !Ref IamRole1
  # Create IAM Policy
  IamPolicy1:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: !Ref IamPolicyName1
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - route53:GetChange
              - route53:ChangeResourceRecordSets
              - route53:ListResourceRecordSets
            Resource:
              - arn:aws:route53:::hostedzone/ZZZZZZZZZZZZZZZZ
              - arn:aws:route53:::change/*
          - Effect: Allow
            Action: route53:ListHostedZonesByName
            Resource: arn:aws:route53:::hostedzone/*
      Roles:
        - !Ref IamRole1

感想

コンソールでの手動操作をCloudFormationでコードに起こせばいいだけだと思っていた
裏でよしなにやってくれたことを知り、これを機にインスタンスプロファイルを学ぶことができた
発端としてはLEGOで必要なIAMロールを作っていた際の出来事である

Welcome :: Let’s Encrypt client and ACME library written in Go.

参考

記事内でリンク済み