AutoScalingで新規構築されたインスタンスにIAMポリシーを適用させてみた

プログラミング

概要

AutoScalingで新規インスタンスが構築したときにIAMポリシーを付与させる方法を知らなかったので調べて試してみました!

CDK使って構築は行いました。
以下コードです。

GitHub - nakajima97/aws-cdk-autoscaling-iam-policy: AutoScalingを動作してもIAMポリシーを引き継ぐ設定を試したリポジトリ
AutoScalingを動作してもIAMポリシーを引き継ぐ設定を試したリポジトリ. Contribute to nakajima97/aws-cdk-autoscaling-iam-policy development by creatin...

環境

  • ubuntu 22.04
  • cdk: 2.135.0
  • node: 18.16.1

やってみた

以下コードです。

import * as cdk from 'aws-cdk-lib';
import { Vpc } from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

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

    const vpc = new Vpc(this, 'VPC', {
      ipAddresses: cdk.aws_ec2.IpAddresses.cidr('10.0.0.0/16'),
      maxAzs: 2,
    });

    const securityGroup = new cdk.aws_ec2.SecurityGroup(this, 'SecurityGroup', {
      vpc,
      allowAllOutbound: true,
    });

    const iamRole = new cdk.aws_iam.Role(this, 'IAMRole', {
      assumedBy: new cdk.aws_iam.ServicePrincipal('ec2.amazonaws.com'),
      roleName: 'EC2Role',
      managedPolicies: [
        cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
      ],
    });

    const instanceProfile = new cdk.aws_iam.InstanceProfile(this, 'InstanceProfile', {
      role: iamRole,
      instanceProfileName: 'EC2Role'
    });

    const launchTemplate = new cdk.aws_ec2.LaunchTemplate(this, 'LaunchTemplate', {
      machineImage: cdk.aws_ec2.MachineImage.latestAmazonLinux2023(),
      instanceType: cdk.aws_ec2.InstanceType.of(cdk.aws_ec2.InstanceClass.T3, cdk.aws_ec2.InstanceSize.MICRO),
      securityGroup,
      instanceProfile,
    });

    const autoScalingGroup = new cdk.aws_autoscaling.AutoScalingGroup(this, 'ASG', {
      vpc,
      launchTemplate,
      minCapacity: 2,
    });

    const alb = new cdk.aws_elasticloadbalancingv2.ApplicationLoadBalancer(this, 'ALB', {
      vpc,
      internetFacing: true,
    });

    const listener = alb.addListener('Listener', {
      port: 80,
      open: true,
    });

    listener.addTargets('Target', {
      port: 80,
      targets: [autoScalingGroup],
    });
  }
}

肝としては以下2つです。

  1. インスタンスプロファイルを作成すること
  2. 起動テンプレートにインスタンスプロファイルを追加する

EC2に直接IAMロールを紐づけるということはできないです。
AWSマネジメントコンソールからIAMロールをEC2に付与する際には「IAMロールを変更」と書かれているのですが、内部的にはインスタンスプロファイルというものを付与しております。

AWSマネジメントコンソールからIAMロールを作成した際には同名のインスタンスプロファイルが作成され、IAMロールを削除したときにも同名のインスタンスプロファイルは削除されるという動きをするのでAWSマネジメントコンソールで普段操作する場合には意識する機会は少ないかもしれません。

上記の動きに関しては公式ドキュメントに書かれています。

インスタンスプロファイルを使用する - AWS Identity and Access Management
IAM インスタンスプロファイルを使用してインスタンスの起動時に Amazon EC2 インスタンスにロールを割り当てます。

暗黙的にインスタンスプロファイルを作成してくれるのはAWSマネジメントコンソールから作成したときの話なので、CDKで作成する際には明示的に作成する必要があります。
インスタンスプロファイルを作成するコードが以下です。

const iamRole = new cdk.aws_iam.Role(this, 'IAMRole', {
  assumedBy: new cdk.aws_iam.ServicePrincipal('ec2.amazonaws.com'),
  roleName: 'EC2Role',
  managedPolicies: [
    cdk.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'),
  ],
});

const instanceProfile = new cdk.aws_iam.InstanceProfile(this, 'InstanceProfile', {
  role: iamRole,
  instanceProfileName: 'EC2Role'
});

それで起動テンプレートにこのインスタンスプロファイルを使うようにします。

const launchTemplate = new cdk.aws_ec2.LaunchTemplate(this, 'LaunchTemplate', {
  machineImage: cdk.aws_ec2.MachineImage.latestAmazonLinux2023(),
  instanceType: cdk.aws_ec2.InstanceType.of(cdk.aws_ec2.InstanceClass.T3, cdk.aws_ec2.InstanceSize.MICRO),
  securityGroup,
  instanceProfile,
});

これでデプロイしてあげると無事IAMロールが付与された状態でインスタンスを起動することができました!

インスタンスプロファイルがAWSマネジメントコンソールで登場する箇所

AWSマネジメントコンソールのEC2の画面からIAMロールを付与する際にインスタンスプロファイルではなくIAMロールという名前で出てくるのでAWSマネジメントコンソールで普段作業することはインスタンスプロファイルを意識する機会は少ないと先ほど書きましたが、AWSマネジメントコンソールではっきりとこの単語が使われている箇所があります。

それは起動テンプレートの画面です。

EC2を使ってサーバを運用している方であればこの画面はよく触るかと思います。
実は自分がこの記事を書こうとしたきっかけもEC2にIAMロールを付与したいけど、
このまま付与したらAutoScaling動作時に消えるよな。。。
起動テンプレートにIAMロール付与する項目無さそうだけどうすりゃいいんだ!?
となったのがきっかけです。

感想

EC2にIAMポリシーを適用させたいときにはIAMロールではなくインスタンスプロファイルを使う必要があるというのは学びでした。

今後もAWSの学習頑張っていきます!

Follow me!

コメント

PAGE TOP
タイトルとURLをコピーしました