Amazon Web Services ブログ

AWS CloudFormation のパブリックレジストリの紹介

AWS CloudFormationAWS Cloud Development Kit (CDK) は、AWS リソース (コンピューティングインフラストラクチャ、モニタリングツール、データベースなど) のスケーラブルで一貫性のあるプロビジョニングを提供します。AWS パートナーネットワーク (APN) メンバー、サードパーティベンダー、オープンソーステクノロジーからリソースをプロビジョニングするときに、クラウドインフラストラクチャを定義するために CloudFormation テンプレートを使用しているか CDK を採用しているかにかかわらず、同じ一貫性とスケーラビリティの恩恵を受けたいという話を多くのお客様から聞いたことがあります。

AWS、APN パートナー、サードパーティ、および開発者コミュニティによって公開された、検索可能な拡張機能コレクション (リソースタイプまたはモジュール) を提供する CloudFormation の新しいパブリックレジストリを発表できることを嬉しく思います。

レジストリを使用すると、AWS によって提供されたリソースを使用するのと同じ方法で、CloudFormation テンプレートと CDK アプリケーションでこれらの拡張機能を簡単に検出してプロビジョニングできます。拡張機能を使用することで、サードパーティベンダーのリソースタイプのカスタムプロビジョニングロジックを作成して維持する必要がなくなりました。また、単一の Infrastructure as Code ツール CloudFormation を使用して AWS とサードパーティのリソースのプロビジョニングと管理を行うことができ、インフラストラクチャのプロビジョニングプロセスをさらに簡素化できます (CDKCloudFormation をフードの下で使用します)。

ローンチパートナー
数十を超える APN パートナーがレジストリのローンチに参加できることを嬉しく思います。現在ご利用いただける拡張機能は 35 種類以上あります。このローンチでコラボレーションした APN パートナーからのブログ投稿とお知らせは、AWS クイックスタートとともに、以下に記載されています (一部は数日後に追加されます)。

レジストリとリソースタイプ
2019年、CloudFormation はプライベートレジストリのサポートを開始しました。これにより、AWS およびサードパーティベンダーのプロバイダーを含む、アカウントでのリソースプロバイダー (Lambda 関数) の登録と使用が可能になりました。プロバイダーを登録した後、CloudFormation テンプレートのプロバイダーからのカスタムプロビジョニングロジックで構成されるリソースタイプを使用できました。リソースタイプはプロバイダーによってAmazon Simple Storage Service (Amazon S3) バケットにアップロードされ、ユーザーは関連する S3 URL を参照してそのタイプを使用していました。パブリックレジストリはリソースタイプとモジュールの調達の一貫性を提供するため、Amazon Simple Storage Service (Amazon S3) バケットのコレクションを使用する必要がなくなります。

パブリックレジストリ内のサードパーティのリソースタイプも、ドリフト検出と統合されます。サードパーティのリソースタイプからリソースを作成した後、CloudFormation は、AWS リソースの場合と同様に、テンプレート設定 (設定のドリフト) からリソースの変更を検出します。AWS Config を使用して、レジストリから消費されるサードパーティリソースのコンプライアンスを管理することもできます。リソースタイプは、それらを記録するように AWS Config を設定し、CloudFormation を使用して作成、更新、および削除すると、自動的に設定項目として追跡されます。使用するリソースタイプがサードパーティリソースまたは AWS リソースのいずれであっても、AWS Config ルールを作成して設定のベストプラクティスを確認できるだけでなく、それらの設定履歴を表示できます。

パブリックレジストリはタイプ設定もサポートしており、アカウントとリージョンごとに API キーと OAuth トークンを使用してサードパーティのリソースタイプを構成できます。設定すると、構成は安全に保存され、更新できます。これにより、サードパーティのリソースタイプを一元的に構成することもできます。

拡張機能をパブリックレジストリに公開する
拡張機能のパブリッシャーは、AWS Marketplace の出品者か、GitHub または BitBucket のユーザーとして検証される必要があり、拡張機能はベストプラクティスに対して検証されます。拡張機能 (リソースタイプまたはモジュール) をレジストリに公開するには、前述のアカウントタイプのいずれかを使用して AWS リージョンに登録する必要があります。

登録後、次に拡張機能を同じリージョン内のプライベートレジストリに公開します。それから、拡張機能が公開要件を満たしていることをテストする必要があります。リソースタイプ拡張機能の場合、そのタイプに定義されたすべてのコントラクトテストに合格する必要があることを意味します。モジュールにはさまざまな要件が適用されます。詳細については、ドキュメントを参照してください。テストが完了したら、拡張機能をリージョンのパブリックレジストリに公開できます。拡張機能の公開の詳細については、ユーザーガイドを参照してください

パブリックレジストリでの拡張機能の使用
AWS クイックスタートによる Kubernetes に関連するいくつかの拡張機能を試して、クラスターの設定を変更することにしました。個人的には、Kubernetes とその API について多くの経験がないので、拡張機能で時間と労力を大幅に節約できる方法を検討する絶好の機会でした。この記事を書く過程で、他の人から、Kubernetes API (私が念頭に置いていた変更を達成するための通常の方法) を使用する場合、より多くの経験を持つ人でも通常は努力が必要であることを学びました。

この例では、Kubernetes クラスターが必要だったので、このチュートリアルに従って、マネージドノード – Linux ノードタイプを使用して、Amazon Elastic Kubernetes Service (EKS) でクラスターをセットアップしました。クラスターの準備が整ったら、2 つの構成変更を行いたいと思います。

まず、クラスターに新しい名前空間を追加します。名前空間は、分離を提供することで、競合することなく同じリソースセットを同じクラスター内の異なる名前空間にデプロイできるパーティション構成です。次に、Kubernetes のパッケージマネージャーである Helm をセットアップして使いたいと思います。Helm を使用して、クラスターメトリクスを収集するために Prometheus helm-charts リポジトリから kube-state-metrics パッケージをインストールします。これまで、CloudFormation を使用してクラスターとコンピューティングリソースをプロビジョニングすることはできましたが、これら 2 つの設定タスクを実行するには、API またはさまざまなカスタムツールチェーンに切り替える必要がありました。レジストリとこれら 2 つの拡張機能を使用すると、CloudFormation を使用してすべてを行うことができます (もちろん、前述したように、後で示す CDK で拡張機能を使用することもできます)。

拡張機能を使用する前に、マイアカウントで拡張機能を有効にする必要があります。コンソールを使用して単一のアカウントに対してアクティベーションを行うことは簡単ですが、AWS Organizations を使用していて、組織全体または特定の組織単位 (OU) でさまざまなサードパーティの拡張機能をアクティブ化したい場合は、CloudFormationサービスマネージド StackSets を使用してこれを実現できます。サービスマネージド StackSet に送信されたテンプレートでリソースタイプ AWS::CloudFormation::TypeActivation を使用して、組織全体または特定の OU をターゲットにして、アクティブ化するサードパーティの拡張機能を識別する Amazon リソースネーム (ARN) を渡します。拡張機能のアクティベーションは、(AWS Organizations を使用するかどうかにかかわらず) CDK を使用してもわずか数行のコードでも非常に簡単に実現できます。この場合も、前述の TypeActivation リソースタイプを利用します。

拡張機能をアクティブ化するには、 CloudFormation コンソールに移動し、ナビゲーションバーから [パブリック拡張機能] をクリックします。これにより、Registry:Public extensions のホームページが表示され、サードパーティのリソースタイプ拡張機能の表示に切り替わります。

レジストリ内のサードパーティの種類を表示する

私が望む拡張機能は、AWSQS::Kubernetes::ResourceAWSQS::Kubernetes::Helm です。Resource 拡張機能は、構成の変更を記述したマニフェストをクラスターに適用するために使用されます。私の場合、マニフェストは名前空間の作成を要求します。AWSQS::Kubernetes::Resource 拡張機能の名前をクリックすると、拡張機能のスキーマ、設定の詳細、バージョンを確認できるページが表示されます。

リソース拡張機能の詳細を表示する

使用している拡張機能を非アクティブ化した場合や、パブリッシャーによって拡張機能が廃止された場合はどうなるでしょうか。 スタックが依存する拡張機能を非アクティブ化すると、その拡張機能から作成されたリソースは影響を受けませんが、読み取り、更新、削除、リストなどのスタック操作は実行できなくなります (拡張機能が再度アクティブ化されるまで失敗します)。パブリッシャーは、拡張機能をレジストリから廃止することをクエストする必要があります (「削除」API はありません)。リクエストが許可された場合でも、廃止前に拡張機能をアクティブ化した顧客は、アカウント内の拡張機能の有効なスナップショットを使用して、作成/読み取り/更新/削除/リスト操作を実行できます。

[Activate] をクリックすると、拡張機能の背後にあるコードを実行するときに CloudFormation が引き受ける実行ロールの ARN を指定する必要があるページに移動します。このユーザーガイドのトピックに従ってロールを作成しますが、基本的な信頼関係については下記を参考にしてください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "resources.cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

また、使用しているリソースタイプの許可を実行ロールに追加します。選択したタイプに必要な許可の詳細は、GitHubで、HelmKubernetes について確認できます (GitHub の例には信頼関係も含まれていることに注意してください)。

拡張機能をアクティブ化するときに、テンプレートや CDK アプリケーションでタイプを参照する方法であるデフォルト名を使用するか、新しい名前を入力するかを選択できます。選択した名前はアカウント内で一意である必要があります。そのため、拡張機能のバージョンをデフォルト名で有効にしていて、別のバージョンを有効にしたい場合は、名前を変更する必要があります。詳細を入力し、バージョニング戦略を選択したら (拡張機能はセマンティックバージョニングを使用し、マイナーバージョン変更の自動更新を受け入れるか、特定のバージョンに「ロック」するかを選択できます)、[拡張機能の有効化] をクリックしてプロセスを完了します。

レジストリからの拡張機能のアクティブ化

これで最初の拡張機能のプロセスは完了し、AWSQS::Kubernetes::Helm 拡張機能についても同じ手順に従います。[アクティブ化された拡張機能] に移動すると、有効になっているすべての拡張機能のリストを表示できます。

有効な拡張機能のリストを表示する

更新する許可のセットがもう 1 つあります。リソースタイプは私に代わって Kubernetes API を呼び出すため、クラスターの aws-auth ConfigMap を更新して、先ほど使用した実行ロールを参照する必要があります。そうしないと、使用しているリソースタイプによる呼び出しは失敗します。これを行うには、コマンドプロンプトでコマンド kubectl edit cm aws-auth -n kube-system を実行します。開いたテキストエディタで、下に示す CfnRegistryExtensionExecRole を参照する新しいグループで ConfigMap を更新します (私に合わせて進めている場合は、アカウント ID とロール名を自分のものに合わせて変更してください)。

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::111122223333:role/myAmazonEKSNodeRole
      username: system:node:{{EC2PrivateDNSName}}
    - groups:
      - system:masters
      rolearn: arn:aws:iam::111122223333:role/CfnRegistryExtensionExecRole
      username: cfnresourcetypes
kind: ConfigMap
metadata:
  creationTimestamp: "2021-06-04T20:44:24Z"
  name: aws-auth
  namespace: kube-system
  resourceVersion: "6355"
  selfLink: /api/v1/namespaces/kube-system/configmaps/aws-auth
  uid: dc91bfa8-1663-45d0-8954-1e841913b324

これで、拡張機能を使用して、新しい名前空間、Helm、および kube-state-metrics パッケージを使用してクラスターを設定する準備が整いました。拡張機能を使用する CloudFormation テンプレートを作成し、スタックの作成時に指定する要素 (更新するクラスターの名前と、名前空間名) のパラメータを追加します。KubeStateMetrics リソースのプロパティは、Helm でインストールするパッケージを参照します。

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  ClusterName:
    Type: String
  Namespace:
    Type: String
Resources:
  KubeStateMetrics:
    Type: AWSQS::Kubernetes::Helm
    Properties:
      ClusterID: !Ref ClusterName
      Name: kube-state-metrics
      Namespace: !GetAtt KubeNamespace.Name
      Repository: https://prometheus-community.github.io/helm-charts
      Chart: prometheus-community/kube-state-metrics
  KubeNamespace:
    Type: AWSQS::Kubernetes::Resource
    Properties:
      ClusterName: !Ref ClusterName
      Namespace: default
      Manifest: !Sub |
        apiVersion: v1
        kind: Namespace
        metadata:
          name: ${Namespace}
          labels:
            name: ${Namespace}

CloudFormation コンソールの [スタック] ページで、[スタックを作成] をクリックし、テンプレートをアップロードし、スタックの名前と宣言されたパラメータの値を指定します。

アクティブ化された拡張機能でスタックを起動する

[次へ] をクリックしてウィザードの残りの部分に進み、その他の設定をデフォルト値のままにし、[スタックを作成] をクリックしてプロセスを完了します。

スタックの作成が完了したら、kubectl コマンドラインツールを使用して変更を確認します。最初に、新しい名前空間 newsblog-sample-namespacekubectl get namespaces コマンドに存在することを確認します。次に、kubectl get all --namespace newsblog-sample-namespace コマンドを実行して、kube-state-metrics パッケージがインストールされていることを確認します。

変更によって適用された拡張機能の確認

拡張機能は AWS Cloud Development Kit でも使用できます。新しいレジストリの使用に関するこの探索をまとめるために、先ほど示した YAML テンプレートと同じ拡張機能を使用して、同じ効果を達成する CDK アプリケーションスニペットの例を TypeScript に含めました (C#、Java、Python など、CDK でサポートされている言語でも記入できます)。

import {Stack, Construct, CfnResource} from '@aws-cdk/core';
export class UnoStack extends Stack {
  constructor(scope: Construct, id: string) {
    super(scope, id);
    const clusterName = 'newsblog-cluster';
    const namespace = 'newsblog-sample-namespace';

    const kubeNamespace = new CfnResource(this, 'KubeNamespace', {
      type: 'AWSQS::Kubernetes::Resource',
      properties: {
        ClusterName: clusterName,
        Namespace: 'default',
        Manifest: this.toJsonString({
          apiVersion: 'v1',
          kind: 'Namespace',
          metadata: {
            name: namespace,
            labels: {
              name: namespace,
            }
          },
        }),
      },
    });
    
    new CfnResource(this, 'KubeStateMetrics', {
      type: 'AWSQS::Kubernetes::Helm',
      properties: {
        ClusterID: clusterName,
        Name: 'kube-state-metrics',
        Namespace: kubeNamespace.getAtt('Name').toString(),
        Repository: 'https://prometheus-community.github.io/helm-charts',
        Chart: 'prometheus-community/kube-state-metrics',
      },
    });
  }
};

この記事で前述したように、私は Kubernetes API と一般的な Kubernetes の経験はあまりありません。しかし、パブリックレジストリのリソースタイプを CloudFormation と組み合わせて使用することで、API や特注のツールチェーンに頼ることなく、使い慣れた環境を使用してクラスターを簡単に構成することができました。

CloudFormation パブリックレジストリを使い始める
パブリックレジストリの価格は、既存のレジストリおよびプライベートリソースタイプと同じです。ネイティブ AWS リソースタイプを使用するための追加料金は発生しません。サードパーティのリソースタイプでは、1 か月あたりに実行するハンドラーオペレーション (追加、削除、リストなど) の数に基づいて課金されます。詳細については、AWS CloudFormation の料金表ページを参照してください。 現在、新しいパブリックレジストリは、米国東部 (バージニア北部、オハイオ)、米国西部 (オレゴン、北カリフォルニア)、カナダ (中部)、欧州 (アイルランド、フランクフルト、ロンドン、ストックホルム、パリ、ミラノ)、アジアパシフィック (香港、ムンバイ、大阪、シンガポール、シドニー、ソウル、東京)、南米 (サンパウロ)、中東 (バーレーン)、アフリカ (ケープタウン) の AWS リージョンで利用できます。

詳細については AWS CloudFormation ユーザーガイドおよび拡張機能の開発のためのユーザーガイドを参照し、拡張機能の公開と使用を今すぐ開始してください。

– Steve