AWS Protonでコンテナアプリの自動管理を試す

はじめに

マイクロサービスやコンテナベースのアプリケーション開発が一般的になる中、インフラストラクチャの管理や標準化の課題が増大しています。特に複数チームが関わる大規模な開発環境では、アプリケーションデプロイの一貫性と効率性の確保が重要です。本記事では、AWSが提供するフルマネージドサービスである「AWS Proton」を活用して、コンテナアプリケーションの自動管理を実践する方法を紹介します。

AWS Protonとは

AWS Protonは、コンテナやサーバーレスアプリケーションのデプロイを自動化するためのフルマネージドサービスです。主に以下の特徴を持っています:

  • 環境とサービステンプレートの標準化: インフラストラクチャとアプリケーションのプロビジョニングを標準化されたテンプレートで管理
  • セルフサービス機能: 開発者が自分でインフラの詳細を理解せずにアプリケーションをデプロイ可能
  • 自動化されたプロビジョニング: CI/CDパイプラインを含めた環境全体の自動プロビジョニング
  • インフラストラクチャ・アズ・コード: AWS CloudFormation、Terraform、AWS CDKなどのIaCツールとの統合

AWS Protonは、主にプラットフォーム管理者と開発者という二つの役割を想定しています。プラットフォーム管理者はテンプレートを作成・管理し、開発者はそれらのテンプレートを使用してアプリケーションをデプロイします。

AWS Protonの主要コンポーネント

AWS Protonを理解するためには、以下の主要コンポーネントを把握することが重要です:

  1. 環境テンプレート: アプリケーションが実行されるインフラストラクチャを定義するもの(VPC、クラスター、ネットワーク設定など)
  2. サービステンプレート: アプリケーションとそのリソースを定義するもの(コンテナ、Lambda関数、ロードバランサーなど)
  3. 環境: 環境テンプレートから作成された実際のインフラストラクチャリソースの集合
  4. サービス: サービステンプレートから作成された実際のアプリケーションとそのリソース
  5. コンポーネント: サービスの一部として動作する小さな機能単位(オプション)

ハンズオン:AWS Protonでコンテナアプリを自動管理する

前提条件

  • AWSアカウント
  • AWS CLI(設定済み)
  • GitHubアカウント(リポジトリ連携用)
  • Docker(ローカル開発用)

1. AWS Protonの有効化

まず、AWS Management ConsoleからAWS Protonサービスにアクセスし、サービスを有効化します。初めて使用する場合は、必要なIAMロールの作成を行います。

2. 環境テンプレートの作成

環境テンプレートは、サービスが実行されるインフラストラクチャを定義します。ここでは、ECSクラスターを含む基本的な環境テンプレートを作成します。

環境テンプレートのディレクトリ構造

fargate-environment/
├── infrastructure/
│   ├── cloudformation.yaml
│   └── manifest.yaml
└── schema/
    └── schema.yaml

manifest.yamlの例

infrastructure:
  templates:
    - file: "cloudformation.yaml"
      rendering_engine: jinja
      template_language: cloudformation
schema: schema.yaml

cloudformation.yamlの例(一部抜粋)

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Environment template for ECS Fargate'

Parameters:
  VpcCidr:
    Type: String
    Default: 10.0.0.0/16

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCidr
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub '${AWS::StackName}-vpc'

  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Sub '${AWS::StackName}-cluster'
      CapacityProviders:
        - FARGATE
        - FARGATE_SPOT
      DefaultCapacityProviderStrategy:
        - CapacityProvider: FARGATE
          Weight: 1

schemaの例

schema:
  format:
    openapi: "3.0.0"
  environment_input_type: "EnvironmentInput"
  types:
    EnvironmentInput:
      type: object
      properties:
        vpc_cidr:
          type: string
          default: 10.0.0.0/16
          description: "VPCのCIDRブロック"
        environment_name:
          type: string
          description: "環境の名前"
      required:
        - environment_name

3. 環境テンプレートの登録

作成したテンプレートをGitHubリポジトリにプッシュし、AWS Protonに登録します。

# GitHubリポジトリにプッシュ
git init
git add .
git commit -m "Add environment template"
git remote add origin https://github.com/yourusername/proton-templates.git
git push -u origin main

# AWS Protonにテンプレートを登録(AWS CLIを使用)
aws proton create-environment-template \
  --name "fargate-environment" \
  --display-name "Fargate Environment" \
  --description "ECS Fargateを使用した基本環境"
  
# テンプレートバージョンを登録
aws proton create-environment-template-version \
  --template-name "fargate-environment" \
  --source-s3-bucket "my-proton-templates-bucket" \
  --source-s3-key "fargate-environment.zip" \
  --major-version "1" \
  --minor-version "0"

# テンプレートバージョンを公開
aws proton update-environment-template-version \
  --template-name "fargate-environment" \
  --major-version "1" \
  --minor-version "0" \
  --status "PUBLISHED"

4. サービステンプレートの作成

次に、コンテナアプリケーションを定義するサービステンプレートを作成します。

サービステンプレートのディレクトリ構造

fargate-service/
├── infrastructure/
│   ├── cloudformation.yaml
│   └── manifest.yaml
├── schema/
│   └── schema.yaml
└── instance_infrastructure/
    ├── cloudformation.yaml
    └── manifest.yaml

サービスのcloudformation.yaml(一部抜粋)

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Service template for ECS Fargate'

Parameters:
  EnvironmentName:
    Type: String
  ServiceName:
    Type: String
  ContainerPort:
    Type: Number
    Default: 80

Resources:
  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref ServiceName
      Cpu: '256'
      Memory: '512'
      NetworkMode: awsvpc
      RequiresCompatibilities:
        - FARGATE
      ExecutionRoleArn: !ImportValue 'ECSTaskExecutionRole'
      ContainerDefinitions:
        - Name: !Ref ServiceName
          Image: '{{ service_instance.inputs.image_url }}'
          Essential: true
          PortMappings:
            - ContainerPort: !Ref ContainerPort

5. サービステンプレートの登録

環境テンプレートと同様に、サービステンプレートをGitHubリポジトリにプッシュし、AWS Protonに登録します。

# AWS Protonにサービステンプレートを登録
aws proton create-service-template \
  --name "fargate-service" \
  --display-name "Fargate Service" \
  --description "ECS Fargateで実行されるコンテナサービス" \
  --pipeline-provisioning "CUSTOMER_MANAGED"

# テンプレートバージョンを登録
aws proton create-service-template-version \
  --template-name "fargate-service" \
  --source-s3-bucket "my-proton-templates-bucket" \
  --source-s3-key "fargate-service.zip" \
  --compatible-environment-templates '[{"templateName": "fargate-environment", "majorVersion": "1"}]' \
  --major-version "1" \
  --minor-version "0"

# テンプレートバージョンを公開
aws proton update-service-template-version \
  --template-name "fargate-service" \
  --major-version "1" \
  --minor-version "0" \
  --status "PUBLISHED"

6. 環境の作成

登録した環境テンプレートを使用して、実際の環境を作成します。

aws proton create-environment \
  --name "dev" \
  --template-name "fargate-environment" \
  --template-major-version "1" \
  --template-minor-version "0" \
  --proton-service-role-arn "arn:aws:iam::123456789012:role/ProtonServiceRole" \
  --spec "file://env-spec.yaml"

env-spec.yamlの内容:

proton: EnvironmentInput
spec:
  vpc_cidr: 10.0.0.0/16
  environment_name: dev

7. サンプルコンテナアプリケーションの準備

簡単なウェブアプリケーションをDockerコンテナ化し、Amazon ECRにプッシュします。

# ECRリポジトリの作成
aws ecr create-repository --repository-name proton-sample-app

# Dockerイメージのビルドとプッシュ
docker build -t proton-sample-app .
aws ecr get-login-password | docker login --username AWS --password-stdin 123456789012.dkr.ecr.region.amazonaws.com
docker tag proton-sample-app:latest 123456789012.dkr.ecr.region.amazonaws.com/proton-sample-app:latest
docker push 123456789012.dkr.ecr.region.amazonaws.com/proton-sample-app:latest

8. サービスのデプロイ

最後に、作成したサービステンプレートと準備したコンテナイメージを使用して、サービスをデプロイします。

aws proton create-service \
  --name "sample-app" \
  --template-name "fargate-service" \
  --template-major-version "1" \
  --template-minor-version "0" \
  --spec "file://service-spec.yaml"

service-spec.yamlの内容:

proton: ServiceInput
spec:
  port: 80
  desired_count: 2
  task_size: "x-small"
  image_url: "123456789012.dkr.ecr.region.amazonaws.com/proton-sample-app:latest"

9. サービスインスタンスの確認

デプロイが完了したら、AWS Protonコンソールでサービスインスタンスの状態を確認します。また、生成されたロードバランサーのDNS名を使って、アプリケーションにアクセスできます。

# サービスの詳細を取得
aws proton get-service --name "sample-app"

AWS Protonの高度な機能

CI/CDパイプラインの統合

AWS Protonは、AWS CodePipelineと統合して完全なCI/CDパイプラインを構築することができます。これにより、コードのプッシュから環境のプロビジョニング、アプリケーションのデプロイまでを自動化できます。

# パイプライン定義の例(cloudformation.yaml内)
Pipeline:
  Type: AWS::CodePipeline::Pipeline
  Properties:
    RoleArn: !GetAtt CodePipelineServiceRole.Arn
    ArtifactStore:
      Type: S3
      Location: !Ref ArtifactBucket
    Stages:
      - Name: Source
        Actions:
          - Name: Source
            ActionTypeId:
              Category: Source
              Owner: AWS
              Provider: CodeStarSourceConnection
              Version: '1'
            Configuration:
              ConnectionArn: !Ref GitHubConnection
              FullRepositoryId: "{{ service_instance.inputs.repository }}"
              BranchName: main
            OutputArtifacts:
              - Name: SourceCode

サービスの更新とバージョン管理

アプリケーションの更新が必要な場合、新しいコンテナイメージをビルドしてECRにプッシュし、サービスの仕様を更新します。

# サービスの更新
aws proton update-service-instance \
  --name "sample-app" \
  --service-name "sample-app" \
  --spec "file://service-spec-update.yaml"

service-spec-update.yamlの内容:

proton: ServiceInput
spec:
  port: 80
  desired_count: 3  # スケールアップ
  task_size: "small"
  image_url: "123456789012.dkr.ecr.region.amazonaws.com/proton-sample-app:v2"  # 新バージョン

マルチ環境デプロイ

本番環境と開発環境など、複数の環境にサービスをデプロイすることも簡単です。

# 本番環境の作成
aws proton create-environment \
  --name "prod" \
  --template-name "fargate-environment" \
  --template-major-version "1" \
  --template-minor-version "0" \
  --proton-service-role-arn "arn:aws:iam::123456789012:role/ProtonServiceRole" \
  --spec "file://prod-env-spec.yaml"

# 本番環境へのサービスデプロイ
aws proton create-service-instance \
  --name "prod-instance" \
  --service-name "sample-app" \
  --environment-name "prod" \
  --template-major-version "1" \
  --template-minor-version "0" \
  --spec "file://prod-service-spec.yaml"

AWS Protonを活用するメリット

標準化と一貫性の確保

AWS Protonを使用することで、組織全体で一貫したインフラストラクチャとアプリケーションデプロイのアプローチを実現できます。これにより、以下のメリットがあります:

  • 環境間の一貫性確保
  • 運用オーバーヘッドの削減
  • セキュリティポリシーの標準的な適用
  • 新しいプロジェクトの迅速な開始

開発者の生産性向上

開発者はインフラストラクチャの詳細を気にすることなく、アプリケーションの開発に集中できます:

  • セルフサービスでのデプロイ
  • インフラストラクチャ管理の学習コスト削減
  • デプロイプロセスの簡素化
  • 迅速なフィードバックループ

プラットフォームチームの負担軽減

インフラストラクチャと運用を担当するプラットフォームチームは、個々のアプリケーションのデプロイサポートではなく、テンプレートの管理と改善に集中できます:

  • テンプレートの一元管理
  • ベストプラクティスの組織全体への展開
  • インフラストラクチャの進化の管理
  • コンプライアンスとガバナンスの強化

実践的なTips

1. テンプレート設計のベストプラクティス

  • モジュール性: 再利用可能なコンポーネントに分割する
  • パラメータ化: 柔軟性を確保するために適切なパラメータを定義する
  • デフォルト値: 合理的なデフォルト値を設定して使いやすくする
  • バージョニング: テンプレートのバージョニング戦略を計画する

2. コスト管理

AWS Protonそのものは使用量に応じた課金ですが、プロビジョニングされるリソースのコストを管理することも重要です:

  • 環境の分離: 開発/ステージング/本番環境で適切なサイズのリソースを使用する
  • 自動スケーリング: 需要に応じたリソースのスケーリングを設定する
  • 非アクティブ環境の削除: 不要な環境は削除してコストを削減する

3. セキュリティ考慮事項

  • 最小権限の原則: サービスや環境に必要最小限のIAMアクセス許可を付与する
  • シークレット管理: AWS Secrets ManagerやParameter Storeを使用してシークレットを管理する
  • ネットワークセキュリティ: 適切なセキュリティグループと私設サブネットの設定を行う

まとめ

AWS Protonは、コンテナやサーバーレスアプリケーションのためのプラットフォームチームと開発者のコラボレーションを促進する強力なツールです。環境とサービスを標準化されたテンプレートを通じて管理することで、一貫性、スケーラビリティ、生産性の向上を実現します。

特に以下のようなケースで効果を発揮します:

  • 複数のマイクロサービスを運用する組織
  • 複数チームが協力して開発を行うプロジェクト
  • 環境間の一貫性が重要な規制対象業界
  • インフラストラクチャのベストプラクティスを標準化したい場合

AWS Protonを導入することで、インフラストラクチャ管理の負担を軽減し、開発者がアプリケーション開発に集中できる環境を構築することができます。ぜひプロジェクトに取り入れて、コンテナアプリケーションの自動管理を実現してみてください。

コメント

タイトルとURLをコピーしました