💬

AWS CDKのコードをながめながらAWS IAMの基礎を抑える

2024/08/07に公開

AWS CDKが最近めっちゃいいという噂を聞いて、CDKに入門しました。
仕事でよく使うAWSリソースのポイントをアウトプットしながら、CDK力をつける狙いです。

AWSよくわからんって方にはCDKの部分だけ飛ばして読んでもらえれば、実務で頻出のリソースについての理解が深めらると思います。

AWS CDK でIAMリソースを作成

早速ですが、IAMグループとIAMユーザーを作成したCDKのコードです。
IAMってなんやねんって方はここは読み飛ばして次の章で何者かを説明します。

export class SampleCdkStack extends cdk.Stack {
    constructor(scope: Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props);

         const iamGroup = new iam.Group(this, 'Administrators', {
            groupName: 'Administrators',
            managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess')],
        });

        const iamUser = new iam.User(this, 'MyAdminUser', {
            userName: 'MyAdminUser',
            // 環境変数を使ってパスワード取得はいけてない感じがあります
            password: cdk.SecretValue.unsafePlainText(
                process.env.ADMIN_PASSWORD ?? 'default_password',
            ),
            passwordResetRequired: true,
        });

        iamGroup.addUser(iamUser);

        const iamRole = new iam.Role(this, 'MyRole', {
            roleName: 'S3AccessRole',
            assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
        });

        iamRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess'));
    }
}

基本的に設定とかはデフォルトで使えるなら、デフォルトがいいというデフォルト厨なので
AWS CDK自体がTypescriptで開発されているということもあり、私もTypescriptでコードを書きました。

これだけのコードでIAMユーザーが用意できてしまうなら、やっぱり画面ポチポチよりも楽だなというのが今の所感です。

とはいえ、AWS CDKが手に馴染んできたらという前提がつきますね。
そしていまのところ、Constructをどの単位で切るべきかなどがわかってません。この辺は書きながら慣れていこうと思います。

AWS IAM

本題のAWS IAMの説明パートに入ります。AWSを使ううえでIAMは避けては通れません。

Identity and Access Managementの略でIAMです。名前から予想できる通り、AWSにおいて権限管理を行うためのサービスです。

ちなみに、AWSではルートユーザーという何でもできる最強の権限を持つユーザーもあります。このユーザーは実務では使わないようにしましょう。

ルートユーザーが乗っ取られてしまうと、そのAWSアカウントでのあらゆる操作ができるようになってしまいます。

そのため、個人でAWSアカウントを使う際にもルートユーザーは使わずに、IAMユーザーを作成して使うようにしましょう。

参考:AWS アカウントのルートユーザー

IAMで抑えるべき要素

IAMを使いこなしてAWSリソースの権限管理をマスターするうえで抑えておくべき要素を説明します。

  1. IAMポリシー
  2. IAMユーザー
  3. IAMグループ
  4. IAMロール

参考:IAMとは

まずは、大事な「IAMポリシー」です。

IAMポリシーは、AWSリソースに対するアクセス許可を定義するものです。
JSON形式で記述され、特定のアクションやリソースに対するアクセス許可を指定します。

以下はAdministrator権限を持つIAMポリシーです。Versionの値は固定でStatementの箇所にアクセス許可を記述します。
ポリシー内の「*」はすべてのアクション、リソースを意味します。このポリシーをもつIAMユーザーであれば、すべてのAWSリソースに対するすべてのアクションが許可されているという意味になります。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }
}

参考:IAM でのポリシーとアクセス許可

IAMポリシーの中には「AWS Managed Policy」と「Customer Managed Policy」と「Inline Policy」の3つの種類があります。

AWS Managed PolicyはAWSが提供しているポリシーです。一覧はドキュメントに記載されています。適切な権限を持っているAWS Managed Policyがあるなら、それを使うほうが楽なことが多いです。

なお、AWS Managed Policy自体は変更不可なので、過不足がありオリジナルのポリシーにしたいといった場合は別の種類のポリシーを使うことになります。

参考:AWS Managed Policy

続いて、Customer Managed PolicyはCustomer、つまり、ユーザーが作成したポリシーのことを指します。
このポリシーはユーザーが定義したものになります。例えば、AWS Managed Policyでは権限が広すぎるといった場合や不足している場合などに使うことが多いです。

AWSのセキュリティのベストプラクティスとして「最小特権アクセス許可を適用する」というものがあり、これはタスクの実行に必要な権限だけを付与しようというものです。

ベストプラクティスにそって運用をしていくというときには、Customer Managed Policyを使う場面が増えるでしょう。

では、最後にInline Policyです。Inlineってという方に向けて、メールで考えてみましょう。

お客様先への訪問予定があり、入館申請のために人数を伺われているとします。
その回答をする際に以下のようにもともとの文面を引用する形で回答したときの > の行の部分のことをInlineといいます。

お世話になっております。以下インラインで回答いたします。

> 明日は何名で訪問予定か教えていただけますか?

2名で訪問いたします。

IAMポリシーという文脈だと、もともと権限を持つIAMエンティティ(グループ/ユーザー/ロール)に対して、追加で権限を付与するときに使うというものです。

参考:Inline Policy

次に説明するのは「IAMユーザー」です。AWSアカウントを使用するうえで、1つのユーザーのことを指します。

CDKのコードでは以下の部分です。ユーザー名がMyAdminUserとなっていて、パスワードは環境変数から取得しています。初回ログイン後はパスワードリセットを必須にしています。

const iamUser = new iam.User(this, 'MyAdminUser', {
            userName: 'MyAdminUser',
            password: cdk.SecretValue.unsafePlainText(
                process.env.ADMIN_PASSWORD ?? 'default_password',
            ),
            passwordResetRequired: true,
        });

ただし、公式ドキュメントにも記載の通りIAMユーザーを使用することは非推奨となっています。
この記事では解説しませんが、IAM Identity Centerを使うことを推奨しています。

参考:IAM ユーザー
参考:IAM Identity Center とは何ですか?

それでは、3つ目の「IAMグループ」です。

CDKのコードでいうと、以下の部分でグループと名のつく通り複数のIAMユーザーが所属することができます。

const iamGroup = new iam.Group(this, 'Administrators', {
            groupName: 'Administrators',
            managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess')],
        });

グループ内に所属するIAMユーザーは、グループに設定したポリシーを持つことができます。

そのため、複数の人にIAMユーザーを発行したいとなった際に、個別にIAMユーザーを発行し、ポリシーを付与するのではなく、グループを作成し、ポリシーを付与したうえで、IAMユーザーを所属させることで、ポリシーの管理を楽にすることができます。

参考:IAMユーザーグループ

最後に「IAMロール」です。CDKでいうと以下の部分ですが、正直IAMロールが一番とっつきにくいと思います。
IAMロールはAWSリソースに対して、権限を付与するときに使用します。

const iamRole = new iam.Role(this, 'MyRole', {
            roleName: 'S3AccessRole',
            assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
        });

iamRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3FullAccess'));

上記のコードはAmazon EC2がAmazon S3にアクセスする権限を定義したものです。assumeByはIAMロールがどのようなエンティティによってアクセスされるかを定義します。

addManagedPolicyでS3のFullAccess権限を付与しているため、EC2がS3へアクセスする許可を与えるという意味になります。

参考:IAMロール
参考:IAM ロールの使用

以上がAWSを使ううえでよくでてくるIAMの中身です。他にも抑えておくべき概念はありますが、まずはこれらの使用場面を理解しておくと良いと思います。

まとめ

IAMは奥が深いサービスなので、他にも抑えておくべき概念や実務で使ううえでのハマりポイントもあったりします。

個人的にはYAML自体は好きなのですが、AWSリソースプログラミングするのと同じようにかけるCDKって楽しいですね。
CloudFormationはCDKよりも読むのにエネルギーが必要だなと感じているのでしばらくはCDK推しでAWSを使っていこうと思います。

一部抜粋していますが、CDKの実行により生成されるCloudFormationは以下になります。

Resources:
  AdministratorsA37EF73A:
    Type: AWS::IAM::Group
    Properties:
      GroupName: Administrators
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/AdministratorAccess
    Metadata:
      aws:cdk:path: IamSample/Administrators/Resource
  MyAdminUserDEDD3886:
    Type: AWS::IAM::User
    Properties:
      Groups:
        - Ref: AdministratorsA37EF73A
      LoginProfile:
        Password: asdfghjkl
        PasswordResetRequired: true
      UserName: MyAdminUser
    Metadata:
      aws:cdk:path: IamSample/MyAdminUser/Resource
  MyRoleF48FFE04:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Action: sts:AssumeRole
            Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
        Version: "2012-10-17"
      ManagedPolicyArns:
        - Fn::Join:
            - ""
            - - "arn:"
              - Ref: AWS::Partition
              - :iam::aws:policy/AmazonS3FullAccess
      RoleName: S3AccessRole

あえて、コンソール画面を一切つかわずにAWSリソースの解説記事をかいてみました。
そのうち、画面付きへ更新してもよいかもしれません(人によってはわかりにくい...)

Discussion