0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[小ネタ]AWS CDKで外部のjsonファイル内文字列の変換方法 in TypeScript

Posted at

001samune.png

結論:JSONオブジェクトの静的メソッド(JSON.parse())とString オブジェクトのインスタンスメソッド(replace())を使用します。

概要

IaCでコード化する際、IAMポリシーをjsonファイルとして外だしする記述方法があると思います。
そういった記述方式の際、流用性を高めるにはアカウントIDやリージョン名などはハードコーディングしないのが望ましいです。
Terraformだとtemplatefile関数を使って動的に対応することが可能です。同じようなことをCDK(TypeScript)でもやりたいと思って調べたところ、私の調査力ではCDK APIに見つけられず、たどり着いたのがJavaScriptの標準オブジェクトとメソッドの組み合わせでした。
本記事ではその手法を備忘録として残します。

実践

簡単ですが、IAMポリシーを作成してみます。

IAMポリシー用jsonファイル

作成するIAMポリシー用jsonファイルを以下のように記述しました。
変換したい個所を{任意の文字列}で記述しています。

test-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "TestPolicy",
      "Effect": "Allow",
      "Action": ["ec2:StartInstances"],
      "Resource": ["arn:{Partition}:ec2:{Region}:{Account}:instance/*"]
    }
  ]
}

stackファイル

デプロイするstackファイルを以下のように記述しました。

cdk-app-stack.ts
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as iam from "aws-cdk-lib/aws-iam";
import * as path from "path";
import * as fs from "fs";

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

    // 擬似パラメータインスタンス作成
    const pseudo = new cdk.ScopedAws(this);

    // JSONファイルパス
    const filePath = path.join(`${__dirname}`, "./json/test-policy.json");

    // JSONファイルをJSON文字列として読み込み
    const jsonData = fs.readFileSync(filePath, "utf8");

    // 文字列置換&JSONパース(JavaScriptオブジェクトに変換)
    const jsonPolicy = JSON.parse(
      jsonData
        .replace(/{Partition}/g, pseudo.partition)
        .replace(/{Region}/g, pseudo.region)
        .replace(/{Account}/g, pseudo.accountId)
    );

    // IAMポリシー作成
    new iam.ManagedPolicy(this, "policy", {
      managedPolicyName: "iam-policy",
      document: iam.PolicyDocument.fromJson(jsonPolicy),
    });
  }
}

処理フロー

JSONファイルをJSON文字列として読み込み

初めに、指定のjsonファイルをreadFileSync()でjson文字列として読み込みます。

    const jsonData = fs.readFileSync(filePath, "utf8");

文字列置換し、JavaScriptオブジェクトに変換

replace()を使用して、jsonData内の文字列を変換します。/gをつけることで、一括置換が可能です。

    const jsonPolicy = JSON.parse(
      jsonData
        .replace(/{Partition}/g, pseudo.partition)
        .replace(/{Region}/g, pseudo.region)
        .replace(/{Account}/g, pseudo.accountId)
    );

CFnテンプレート確認

cdk synth --no-version-reporting --no-path-metadataで出力されるCFnテンプレートがこちら。
AWS CloudFormationで使用できる擬似パラメータに変換されていることが確認できます。

Resources:
  policyE16B4B70:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      Description: ""
      ManagedPolicyName: iam-policy
      Path: /
      PolicyDocument:
        Statement:
          - Action: ec2:StartInstances
            Effect: Allow
            Resource:
              Fn::Join:
                - ""
                - - "arn:"
                  - Ref: AWS::Partition
                  - ":ec2:"
                  - Ref: AWS::Region
                  - ":"
                  - Ref: AWS::AccountId
                  - :instance/*
            Sid: TestPolicy
        Version: "2012-10-17"

デプロイして確認

cdk deployで作成されたIAMポリシーがこちら。問題なく擬似パラメータが変換されているのが確認できます。
画像1.png

まとめ

今回は、CDK(TypeScript)で外部のjsonファイル内の文字列を変換する方法を記事にしました。
もっとスマートなやり方があるかもしれませんが、もしご存じの方がいらっしゃいましたらアドバイスいただけると幸いです。

参考資料

リファレンス

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?