[AWS CDK] 発行したIAMアクセスキーがスタックの再デプロイ時に変更されないのか確認してみた

2021.07.04

こんにちは、CX事業本部の若槻です。

AWS上に構築したシステムを外部サービスと連携する時はAWSでIAMユーザーのアクセスキーを発行することが多いですが、このIAMアクセスキーの作成は手動で行うと手数が多くなかなか手間が掛かり、また数が増えすぎると管理も大変になります。

そこで「IAMアクセスキーについても他のリソースと同様にAWS CDKで管理できないか?」と考えたのですが、その際にCDKスタックの再デプロイ時にアクセスキーの値が変更されてしまわないか?という懸念があり、今回実際に確認してみました。

確認してみた

スタック初回デプロイ

発行したアクセスキーのIDとシークレットをAWS System ManagerのパラメータストアにString形式で格納しています。

lib/sample-app-stack.ts

import * as cdk from "@aws-cdk/core";
import * as iam from "@aws-cdk/aws-iam";
import { StringParameter } from "@aws-cdk/aws-ssm";

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

    const operationUser = new iam.User(this, "operation_user");

    const accessKey = new iam.CfnAccessKey(this, "access_key", {
      userName: operationUser.userName,
    });

    const accessKeyId = accessKey.ref;
    const secretAccessKey = accessKey.attrSecretAccessKey;

    //アクセスキーIDをパラメータストアに格納
    new StringParameter(this, "access_key_id_string_parameter", {
      parameterName: "access-key-id",
      stringValue: accessKeyId,
    });

    //シークレットアクセスキーをパラメータストアに格納
    new StringParameter(this, "secret_access_key_string_parameter", {
      parameterName: "secret-access-key",
      stringValue: secretAccessKey,
    });

    //値の確認用に出力
    new cdk.CfnOutput(this, "access_key_id", { value: accessKeyId });
    new cdk.CfnOutput(this, "secret_access_key", {
      value: secretAccessKey,
    });
  }
}

ここで注意点として、パラメータストアへの機密情報の格納はSecureString形式での格納が推奨されていますが、CDKではStringまたはStringList形式での格納にしか対応していないようです(参考)。よって今回の確認ではStringでの格納としていますが、もし本方法をそのまま利用するのであれば権限をIAMポリシーにより必要最低限に絞るなどセキュリティ上の注意を十分に払った上で利用してください。

上記のスタックをcdk deployすると、作成されたアクセスキーのIDとシークレットが下記の通り出力されました。(値は実際のものと少し変えています。)

Outputs:
SampleAppStack.accesskeyid = AKIAUL6WVPY2FWJW125X
SampleAppStack.secretaccesskey = D1YRLyJhefH6SNo+mVX/WR/gp0O69RM0h3vXZka6

パラメータストアにもそれぞれ同じ値が格納されています。

% aws ssm get-parameter --name access-key-id
{
    "Parameter": {
        "Name": "access-key-id",
        "Type": "String",
        "Value": "AKIAUL6WVPY2FWJW125X",
        "Version": 1,
        "LastModifiedDate": "2021-07-04T22:56:57.944000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/access-key-id",
        "DataType": "text"
    }
}

% aws ssm get-parameter --name secret-access-key
{
    "Parameter": {
        "Name": "secret-access-key",
        "Type": "String",
        "Value": "D1YRLyJhefH6SNo+mVX/WR/gp0O69RM0h3vXZka6",
        "Version": 1,
        "LastModifiedDate": "2021-07-04T22:56:57.697000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/secret-access-key",
        "DataType": "text"
    }
}

スタック変更のデプロイ

アクセスキーを発行したIAMユーザーのリソースにポリシー変更の修正を加えます。

lib/sample_app-stack.ts

    const operationUser = new iam.User(this, "operation_user", {
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3FullAccess"),
      ],
    });

修正したスタックをcdk deployすると、アクセスキーのIDとシークレットが下記の通り出力されました。初回デプロイ時と値は変わっていませんね。

Outputs:
SampleAppStack.accesskeyid = AKIAUL6WVPY2FWJW125X
SampleAppStack.secretaccesskey = D1YRLyJhefH6SNo+mVX/WR/gp0O69RM0h3vXZka6

パラメータストアに格納された値も当然変わっておらず、またVersionも1のままです。

% aws ssm get-parameter --name access-key-id
{
    "Parameter": {
        "Name": "access-key-id",
        "Type": "String",
        "Value": "AKIAUL6WVPY2FWJW125X",
        "Version": 1,
        "LastModifiedDate": "2021-07-04T22:56:57.944000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/access-key-id",
        "DataType": "text"
    }
}

% aws ssm get-parameter --name secret-access-key
{
    "Parameter": {
        "Name": "secret-access-key",
        "Type": "String",
        "Value": "D1YRLyJhefH6SNo+mVX/WR/gp0O69RM0h3vXZka6",
        "Version": 1,
        "LastModifiedDate": "2021-07-04T22:56:57.697000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:XXXXXXXXXXXX:parameter/secret-access-key",
        "DataType": "text"
    }
}

結論

AWS CDKでIAMアクセスキーを作成した場合、

  • IAMユーザーリソースを変更(ポリシー修正など)してもアクセスキーのIDとシークレットは変わらない
  • パラメータストアへの再度の格納(バージョンアップ)は行われない

参考

以上