Amazon Web Services ブログ

AWS Proton 自己管理型プロビジョニング

この記事は AWS Proton Self-Managed Provisioning (記事公開日: 2022 年 3 月 23 日) を翻訳したものです。

この記事は、本リリースに関する 2 つの記事のうちの後編です。この記事では、最近ローンチされた機能のうち、2 つ目の機能である、AWS Proton と自己管理型プロビジョニングワークフローの接続について説明します。HashiCorp Configuration Language (HCL) と Terraform を使って AWS Proton テンプレート を作成する方法については、AWS Proton Terraform テンプレート を参照してください。また、AWS Proton に慣れていない方は、製品全体の概要を説明する AWS Proton テンプレート (前編の記事) を読むことをお勧めします。

CloudFormation による AWS マネージドプロビジョニング

本リリース以前は、AWS Proton は AWS マネージドプロビジョニングオプションの 1 つだけをサポートしていました。AWS マネージドプロビジョニングでは、管理者はサポートされているプロビジョニングツール (現時点では AWS CloudFormation とAWS Identity and Access Management (IAM) サービスロール) の認証情報を渡し、あとは AWS Proton が処理します。このオプションは、プロビジョニングに関連するすべての作業を AWS Proton に処理させ、適用したいカスタマイズがない場合に最適です。

Diagram showing the AWS Proton/CloudFormation/Lambda environment

AWS マネージドプロビジョニングにおける役割と責任

AWS Proton 内でサービスとやりとりする 2 つの役割を整理しました。

最初の役割は、管理者、または AWS Proton のテンプレートを作成するユーザーです。この役割は一般的に、ベストプラクティスを確立し、組織全体のインフラストラクチャがそれらのベストプラクティスと一致するようにする責任があります。また、AWS Proton 環境を所有および維持する必要があります。

もう 1 つの役割は、開発者、つまり組織内でアプリケーションを構築する責任を負うユーザーです。AWS Proton は、開発者のエクスペリエンスを簡素化し、アプリケーションの設計に集中できるようにするために、開発者がインフラストラクチャのプロビジョニングに関連するあらゆる作業を行う必要がなくなることを目指しています。

Terraform による自己管理型プロビジョニング

前述の通り、AWS Proton は、自己管理型プロビジョニングオプションをサポートしました。AWS Proton は、テンプレートをコンパイルした後、ユーザーが設定した Git リポジトリにプルリクエストとして送信します。その時点から、そのテンプレートを実行 (つまり terraform apply コマンドを実行) し、その結果を AWS Proton に通知するのはあなたの責任となります。

自己管理型プロビジョニングオプションには、以下の手順が含まれます。

このオプションを使用すると、インフラストラクチャのプロビジョニングに関わる手順がいくつか増えますが、正しく行えば、ほとんどの手順は初期設定手順の一部として構成することができます。

自己管理型プロビジョニングにおける役割と責任

自己管理型プロビジョニングの世界では、管理者は自己管理型プロビジョニングのワークフローの管理を担当するユーザーであることが多いです。少なくとも初期設定を行う必要がありますが、組織の方針によっては、安全なデプロイを保証するために、AWS Proton のプルリクエストを継続的に承認する必要があるかもしれません。

管理者がそのプロセスを管理することで、開発者の手を煩わせることなく、インフラストラクチャの管理を行うことができます。理想的には、完全に自動化された自己管理型プロビジョニングフローと開発者が利用するサービスが連携し、開発者は AWS Proton エクスペリエンス内でデプロイの完了を待つだけとなります。

次の図は、上の自己管理型プロビジョニングの図の赤い線で示されている AWS Proton 環境の作成における様々なアクターの関与をより詳しく示しています。

前述したように、開発者は環境を作成する必要がありません。次に、上の自己管理型プロビジョニングの図の青い線で示されているサービスの作成について見てみましょう。

この記事を書いている時点では、AWS Proton の自己管理型プロビジョニングでサポートされているオプションは Terraform のみです。

プルリクエストの形式

理解すべき最も重要なコンセプトは、AWS Proton が Git リポジトリを管理するために使用するディレクトリ構造であると言えるでしょう。これを理解することは、マージされたプルリクエストに応答して Terraform を実行するオートメーションを構築するうえで重要です。

前編で述べたように、AWS Proton の重要なコンセプトは、環境とサービスの関係です。繰り返しになりますが、サービスは環境にデプロイされます。これは、自己管理型プロビジョニング方式で使用されるリポジトリ構造にも当てはまります。

環境を作成する際、プルリクエストを提出するリポジトリとブランチを指定します。次に AWS Proton がプルリクエストを作成し、コンパイルされた Terraform が環境と同じ名前のディレクトリに配置されます。サービスを作成する際に、AWS Proton はターゲットとなる環境からリポジトリとブランチを取得し、その環境の名前を付けたディレクトリの配下に、サービスの名前を付けたサブディレクトリを配置します。下の図は、それらの関係を示しています。

もう少し詳しく見てみましょう。

次のようなリソースがあるとします。

  • Git リポジトリ: acme-corp/proton-terraform-repo
    • この例では、このリポジトリは GitHub でホストされています。
  • 環境テンプレート: EnvironmentVpcTemplate
    • このテンプレートには、config.tfvpc.tfoutputs.tf の 3 つのファイルが含まれます。
  • サービステンプレート: LambdaServiceTemplate
    • このテンプレートには config.tf, lambda.tf, outputs.tf の 3 つのファイルが含まれます。

ここで、EnvironmentVpcTemplate から vpc-prod という環境を作成し、acme-corp/proton-terraform-repo:main にデプロイするとします。最初のデプロイ後、リポジトリは以下のようになります。

acme-corp/proton-terraform-repo
   /vpc-prod
        /config.tf
        /vpc.tf
        /outputs.tf
        /proton.environment.variables.tf
        /proton.auto.tfvars.json
        /.proton
            /deployment-metadata.json

環境名に対応するディレクトリと、対応する環境テンプレートのファイル (および後で説明するいくつかの追加ファイル) が表示されます。

ここで、LambdaServiceTemplate を使って、lambda-prod というサービスを作成し、そのサービスを vpc-prod にデプロイするとします。典型的なデプロイ手順を経て、最終的にリポジトリは以下のようになります。

acme-corp/proton-terraform-repo
   /vpc-prod
        /lambda-prod /config.tf /lambda.tf
            /outputs.tf /proton.service_instance.variables.tf /proton.auto.tfvars.json /.proton
                /deployment-metadata.json
        /config.tf
        /vpc.tf
        /outputs.tf
        /proton.environment.variables.tf
        /proton.auto.tfvars.json
        /.proton
            /deployment-metadata.json

太字は、vpc-prod/lambda-prod ディレクトリの下に新たに追加されたディレクトリで、Lambda サービスのコンパイルされた Terraform コードが格納されていることを示しています。

これが実際にどのように機能するかについて説明しましょう。AWS Proton は、プルリクエストごとに新しいブランチを作成し、そのブランチにプッシュします。そして、プルリクエストを作成します。プルリクエストのマージ対象となるブランチは、環境設定時に作成したブランチとなります。プルリクエストをマージしたら、AWS Proton が作成したブランチは自由に削除してかまいません。

変数の注入

AWS Proton テンプレート の重要な点は、入力変数システムにより様々なアプリケーションで再利用できることです。Terraform の場合、Terraform の組み込み設定言語を使って処理されます。たとえば、環境であれば、var.environment.inputs.vpc_name などの入力を参照します (使えるパラメータの一覧は、AWS Proton Parameters documentation を参照してください) 。

これらの変数の値を提供するために、AWS Proton は、variables.tf ファイルと proton.auto.tfvars.json の 2 つのファイルを生成します。variables.tf で終わるファイルは、変数の定義が提供され、proton.auto.tfvars.json はそれらの変数に実際の値を割り当てるためのファイルです。基本的に、これらのファイルはあなたからの入力やアクションを必要としません。Terraform を実行すると自動的に機能します。

deployment-metadata.json

最後にもう 1 つ、.proton/deployment-metadata.json というファイルに注意が必要です。AWS Proton は、すべてのリソースに対して deployment-metadata.json というファイルを作成し、コンパイルされたテンプレートと一緒にプルリクエストに含めます。このファイルは、AWS Proton がオートメーションと連携するための主要な手段であるため、非常に重要です。以下は、そのファイルの例です。

{
  # Identifier that uniquely represents the deployment associated with the change
  "deploymentId" : "123e4567-e89b-12d3-a456-42665544000",
  "isResourceDeleted": false,
  "resourceMetadata" : {
    # ARN of the resource being modified
    "arn" : "arn:aws:proton:us-east-1:111111111111:environment/terraform_env",
    # ARN of the AWS Proton Template the resource is deploying
    "templateArn" : "arn:aws:proton:us-east-1:111111111111:environment-template/terraform_env_template",
    # Major version of the AWS proton Template
    "templateMajorVersion" : "1",
    # Minor version of the AWS proton Template
    "templateMinorVersion" : "0"
  }
}

いくつかのフィールドの具体的な使用方法については、後ほど説明します。特に、deploymentIdresourceMetadata.arn について説明します。一部のフィールドは、主に情報であり、テンプレートに関連するものを含め、実際のプロビジョニングフローの一部として必ずしも必要ではありません。ただし、AWS Proton がプルリクエストを作成するために使用する基となるテンプレートの情報を簡単に取得したい場合に便利です。

初めての自己管理型プロビジョニングワークフロー

この記事の残りの部分は、自己管理型プロビジョニングワークフローを設定するために必要な知見を提供することに焦点を当てます。この情報は、自己管理型プロビジョニングに必要な考え方を得ることを目的としています。自己管理型機能の美しさとパワーは、非常に高度な柔軟性にあります。

Terraform を実行するためのオートメーションのサンプル全体については、サンプルリポジトリを確認してください。このリポジトリには、AWS Proton のプルリクエストに対応するための GitHub Actions ワークフローが動作する形で含まれています。

次の図は、自己管理型プロビジョニングワークフローのライフサイクルを通じて完了すべきタスクの流れを示しています。

Diagram of AWS Proton self-managed provisioning request workflow

では、各タスクの意味と、それを達成するために何ができるかを段階的に理解します。最初の 2 つのステップは AWS Proton 内で行われるので、それについて心配する必要はありません。

どのリソースが変更されたかを判断する

前のセクションで説明した deployment-metadata.json を思い出してください。これは、変更される特定の AWS Proton リソースに関する情報を含んでいます。JSON パーサーがあれば、プルリクエストで変更された deployment-metadata.json ファイルから deploymentIdresourceMetadata.arn を取得することが可能です。AWS Proton は、プルリクエストごとにこれらのファイルのインスタンスを 1 つだけ変更します。サンプルのオートメーションは、JSON をパースするための一般的なコマンドラインツールである jq を利用しています。例として、以下のコマンドは jq を活用して deployment-metadata.json ファイルからリソースの ARN を取得する方法を示しています。

$ jq -r '.resourceMetadata.arn' .proton/deployment-metadata.json

リソースがサービスインスタンスの場合、環境に関する情報を取得する必要があることもあります。deployment-metadata.json ファイルは、どの環境にデプロイされるかを示すもので、その情報を探すことができます。このファイルは、以下のようになります。

{
  "deploymentId" : "bc482680-0702-490d-80b7-af12b0f5ec9b",
  "resourceMetadata" : {
    "arn" : "arn:aws:proton:us-east-1:111111111111:service/lambda/service-instance/lambda-prod",
    "templateArn" : "arn:aws:proton:us-east-1:111111111111:service-template/LambdaServiceTemplate",
    "templateMajorVersion" : "1",
    "templateMinorVersion" : "0",
    "environmentArn" : "arn:aws:proton:us-east-1:111111111111:environment/prod-vpc"
  }
}

リソースの認証情報を取得する

Terraform を実行するために必要な最後の設定は、実際に Terraform を実行するために使用する AWS 認証情報 (つまり、リソースをプロビジョニングするアカウント) と、その他の必要な認証情報です。既存の AWS Proton のパターンに従うと、環境ごとに認証情報を構成することが推奨されますが、その限りでは有りません。これを実現する 1 つの方法として、以下のように AWS Proton の環境名から必要な認証情報へのマッピングをリポジトリで管理する方法があります。

{
    "beta-vpc": {
        "role": "arn:aws:iam::111111111111:role/TerraformRole",
        "region": "us-west-2",
        "state_bucket":"terraform-state-bucket",
        "state_locking_table": "terraform-state-locking"
    },
    "prod-vpc": {
        "role": "arn:aws:iam::222222222222:role/TerraformRole",
        "region": "us-west-2",
        "state_bucket":"terraform-state-bucket",
        "state_locking_table": "terraform-state-locking"
    }    
}

これで、プルリクエストがトリガーされ、デプロイ先の環境を決定すると、オートメーションがロールを引き受けることにより対応する資格情報をシンプルに取得します。

Terraform の実行

この時点で、オートメーションはテンプレートのプロビジョニングに必要なすべての情報を取得することに成功します。次に、プロビジョニングするリソースのディレクトリ内で Terraform の初期化をする必要があります。上記の例では、vpc-prod が更新される場合、オートメーションはディレクトリを vpc-prod/ ディレクトリに移動し、terraform init を実行する必要があります。

この時に考えるべきことは、Terraform のステート情報をどのように扱うかです。一般的には、Amazon Simple Storage Service (S3) などのリモートロケーションにステートファイルを保存することが推奨されています。Terraform が提供する追加の保護メカニズムとして、同じステートファイルでの同時実行を防ぐステートロックがあります。何を決めるにしても、それがどのように構成されるかを検討する必要があります。

Terraform が初期化されると、terraform apply を実行するだけで、インフラストラクチャがプロビジョニングされます!

デプロイ結果やインフラストラクチャのアウトプットを AWS Proton へ通知する

これはオートメーションの最終ステップです。AWS Proton は、インフラストラクチャのプロビジョニングの最新のステート、および出力データを保持しているので、詳細ページからアプリケーションのデプロイの健全性の概要を把握することができます。CloudFormation での AWS マネージドプロビジョニングオプションでは、AWS Proton がデプロイのトリガーとなるため、AWS Proton はデプロイの進捗を直接追跡することができます。しかし、自己管理型オプションでは、AWS Proton からは情報を取得することができないため、オートメーションからステータスの変更を AWS Proton に通知する必要があります。これは、AWS Proton への単一の API コールである NotifyResourceDeploymentStatusChange を介して行われます。

削除への対応

インフラ管理のライフサイクルの最終段階は、不要になったときにどうするかということです。この場合、AWS Proton は deployment-metadata.json ファイルに修正を加え、isResourceDeleted フラグを true に設定した状態でプルリクエストを提出します。このフラグは、オートメーションフローで使用され、isResourceDeleted フラグが true に設定されている場合には terraform apply ではなく、terraform destroy を実行することができます。

繰り返しになりますが、例を見たい方はサンプルリポジトリを確認してください。GitHub Actions を使った Terraform のオートメーションを設定するための詳細なウォークスルーがあります。GitHub Actions は決して必須ではありません。私たちは実装の利便性のためにこれを選びましたが、あなたが最も使いやすい CI/CD システムがあれば、それを使ってください。

最後に

クラウドインフラストラクチャをプロビジョニングする方法は、組織によって実に様々です。CloudFormation が好きな人もいれば、 Terraform が好きな人もいます。Terraform の中には Terraform Open Source と Terraform Cloud があります。そして Terraform Open Source には、実際に設定して実行するための多くのツールオプションがあります。変更をデプロイする前に人間の承認が必要な組織もあれば、強固な承認オートメーションを構築する組織もあります。AWS Proton の自己管理型プロビジョニングでは、デプロイされるインフラストラクチャをより厳しく管理できるテンプレート管理システムのメリットを得ながら、そのインフラストラクチャを自分の好みに合わせてプロビジョニングできる自由度があります。

翻訳はプロフェッショナルサービスの高橋たまが担当しました。原文はこちらです。