[アップデート]ServiceCatalogがAWS CDKのサポートを開始しました!

CDKでマルチアカウントの設定展開がやりやすくなりました!
2022.05.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

CX事業本部IoT事業部の佐藤智樹です。

今回はタイトルにあるとおりServiceCatalogがAWS CDKに対応したため、実際の動作を画面やコード上から確認してみます。従来まではServiceCatalogはCloudFormation(Cfn)にしか対応していなかったので、マルチアカウントで設定展開をしたい場合はCfnかTerraform、もしくはStackSetsなどの選択肢が有力でした。今回のアップデートによってCDKでもマルチアカウントでの設定展開がかなり実施しやすくなりました!

アップデート自体は先月なので目新しい内容は無いかもですが、動作画面やコードを載せるので導入時の参考にしていただければ幸いです。そもそもServiceCatalogがどう使われるものなのかはこちらの記事が参考になるかと思います。中央の管理部門がそれぞれのAWSアカウント内でAWSリソースを作成したい場合などに利用できます。

動作環境

項目名 バージョン
Node.js 14.15.0
CDK 2.23

実践

まず先にCDKのコードを紹介し、ServiceCatalogの画面でどのように展開され使用できるのかを解説します。CDKの実装自体は以下の公式サンプルが参考になりました。

実装内容

実装内容は本体となるスタック配下の部分のみ紹介します。適宜補足でコメントを追加しています。他の部分が気になる場合はコードを上げるのでリクエストください。

service_catalog_test-stack.ts

import { Stack, StackProps } from "aws-cdk-lib";
import { Construct } from "constructs";
import * as iam from "aws-cdk-lib/aws-iam";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as servicecatalog from "aws-cdk-lib/aws-servicecatalog";

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

    // 各アカウントで展開されるプロダクトを定義
    const product = new servicecatalog.CloudFormationProduct(this, "Product", {
      productName: "My Product",
      owner: "Product Owner",
      productVersions: [
        {
          productVersionName: "v1",
          cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(
            new S3BucketProduct(this, "S3BucketProduct")
          ),
        },
      ],
    });

    // ポートフォリオへ作成したプロダクトを設定
    const portfolio = new servicecatalog.Portfolio(this, "Portfolio", {
      displayName: "MyFirstPortfolio",
      providerName: "SCAdmin",
      description: "Portfolio for a project",
      messageLanguage: servicecatalog.MessageLanguage.JP,
    });
    portfolio.addProduct(product);
    // 製品利用を許可するユーザ/グループ/ロールの設定
    const role = iam.Role.fromRoleName(this, "Role", "hoge-role");
    portfolio.giveAccessToRole(role);
  }
}

// ProductStack配下で作りたいAWSリソースのConstructを設定
class S3BucketProduct extends servicecatalog.ProductStack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    new s3.Bucket(this, "HogeFugaBucketProduct");
  }
}

主な流れとしては通常ServiceCatalogを作成する時と同様に、ポートフォリオ作成してプロダクトを登録しプロビジョニング可能なユーザ/グループ/ロールを設定します。上記の流れをまず画面上から確認してからの方がイメージが湧きやすいかもしれないです。

コード内から見て取れるように、AWSリソースを定義するCondtructは従来のStackを継承したClassで書くのではなく、ProductStackを継承して書く必要がありそうでした。従来のソースをServiceCatalogで展開する場合は少し書き直しが必要そうです。もしStackベースでかけるやり方があればご連絡いただけると助かります。

コンソール画面の確認

上記のコードをデプロイした後、どのようにポートフォリオを利用できるのか画面上で確認してみます。まずServiceCatalogのポートフォリオから確認してみます。

displayNameに設定したMyFirstPortfolioが画面上で確認できます。こちらを開くとプロダクトが以下のように確認できます。

製品名や提供元に設定した名前が入っていることが確認できます。次に「グループ、ロール、およびユーザ」を見てみます。

ほとんどお見せできませんがコード内の「製品利用を許可するユーザ/グループ/ロールの設定」で設定したIAMロール名とArnが確認できます。次は実際にプロダクトを起動してAWSリソースを展開してみます。サイドバーから「プロビジョニング」->「製品」を選択すると作成したプロダクトが表示されます。

作成した「My Product」をクリックして右上の「製品を起動」を押下し画面に従って進めると製品が展開できます。

サイドバーから「プロビジョニングされた製品」を確認すると起動したプロダクトが確認でき、展開されたリソースの確認などができます。

ちなみにCloudFormationのスタック名はSC-{アカウント名}-pp-{ハッシュ値}のような構成で生成されていました。

上記はシングルアカウントの場合の確認でしたが、ポートフォリオはOrganizations内や他のアカウントと共有できるので、ControlTowerなどで共通のロールが設定済みであればポートフォリオの共有だけでまとめて設定することができそうです。やり方は以下の記事が参考になるかと思います。

所感

やっとCDKでもマルチアカウントに設定展開がしやすくなったように感じています。CDKを組織のベースとして使う場合は非常に有益かと思うので参考になれば幸いです。後はリソース名が固定にできたりスタック名が固定できれば個人的にはうれしいです。