terraformによるECSへの連続配送

4260 ワード

連続配達は、我々がすべてのために努力している何かです.私は同じことをしていましたが、罠がありました.
  • 私のterraformコードとAPIコードは、別々のプロジェクト
  • にありました
  • 私はAPIコードに更新をして、ECSサービス
  • を構築して、更新しなければなりません
  • 私はあまりにも多くの依存関係のリソースを持っていたので、コンテナの定義を個別に管理する必要はありませんでした
  • あなたは複数の環境を持っていて、APIコードのために別々のGitブランチを使わなければなりません.
  • には、独立して配置されているインフラストラクチャ用の各環境用のブランチがあります.
  • たぶん、あなたもこの問題がある.Terraformはコンテナの定義を構築するために特定のECRイメージパスを使用するので、どうやって自動的に更新するのですか?
    この問題を解決するいくつかの方法があり、その多くはthis threadに記載されている.しかし、今日、私はこの問題を解決する方法をあなたに示すつもりです.
  • セットアップをビルド/展開パイプライン
  • まず最初に、我々はECRの中でAPI Dockerイメージを必要とします.これは、どのCIシステムを使用するかによって異なります.
    イメージが構築されているときは、一意にタグ付けします.理想的には、あなたは何か数値が欲しい.私たちのケースでは、私たちは、イメージをタグ付けするために、azureのビルトイン「ビルトイン」パラメータを使用することを選びました.
    以下に、CIパイプラインでビルドするステップを見ることができます.イメージが構築されたあと、それはビルトインでテキストファイルを作成して、「アーチファクト」として船を出荷します.これは後で重要になります.しかし、主なことは、そのパラメータを変更することに基づいて、あなたの環境のためのさらなるパイプラインをトリガする必要があります.
    - task: Docker@2
      inputs:
        command: build
        DockerFile: "$(Build.SourcesDirectory)/Dockerfile"
        repository: ${{parameters.projectName}}
        tags: |
          $(Build.BuildId)
    
    - task: ECRPushImage@1
      inputs:
        imageSource: "imagename"
        sourceImageName: ${{parameters.projectName}}
        sourceImageTag: "$(Build.BuildId)"
        repositoryName: ${{parameters.projectName}}
        pushTag: "$(Build.BuildId)"
    
    - task: Bash@3
      displayName: "Upload Build Artifact of the Docker image Id"
      inputs:
        targetType: "inline"
        script: |
          # Add the build Id to a new file that will then be published as an artifact
          echo $(Build.BuildId) > .buildId
          cat .buildId
    
    - task: CopyFiles@2
      displayName: "Copy BuildId file"
      inputs:
        Contents: ".buildId"
        TargetFolder: "$(Build.ArtifactStagingDirectory)"
    
    - task: PublishBuildArtifacts@1
      displayName: "Publish Artifact"
      inputs:
        pathToPublish: $(Build.ArtifactStagingDirectory)
    
    今すぐあなたがそれを作成したこのパイプラインを実行してください.
  • セットアップSSM (システムマネージャ)パラメータ
  • SSMは、私が以前に本当に本当に使用しなかったAWSサービスです.このパラメータストア機能により、後で更新することができる変数を格納することができます.この場合は、Docker画像タグです.
    AWS Systems Manager > Application Management > Parameter Storeに新しいパラメータを作成します./my-api/${env}/docker-image-tag(envが環境です)のようなパラメータを指定します.それは「ストリング」変数でなければならなくて、あなたのCIビルドパイプラインによって生成されるユニークなタグであるべきです.
  • あなたの展開パイプライン
  • を作成します
    今、我々は特定の環境(例えば、ちょうどdevelopment)でちょうどイメージを更新する方法を定義する必要があります.どうしたらそんなことできるの?我々のセットアップのため、重複努力はかなり最小限です.我々はすでにイメージビルド(すべての環境で一貫している)を持っています.ビルドのパイプラインが生成したユニークなタグ(build)を使用するには、SSMパラメータを更新する必要があります.
    Azureでは、ステップ1で生成したアーティファクトに基づいてパイプラインをトリガーできます.次に、以下の3つのタスクを設定しました.
  • ファイルからビルドを取得し、ランナー環境
  • に追加します
  • は、新しいビルドされた
  • にその環境のSSMパラメータを更新します
  • はその環境のためのインフラストラクチャ/terraformパイプラインをトリガーします-これは新しいSSMパラメタ値が拾われて、コンテナ定義で使用されるところです.
  • は、SSMパラメタ
  • を使用するためにterraformを更新します
    今、あなたは新しいビルドがあるたびに更新されているSSMパラメータを持っている、我々はイメージ名の一部としてSSMパラメータを使用するためにterraformを設定する必要があります.
    // Import the SSM parameter
    // This can be done on a module level because it depends on the environment
    data "aws_ssm_parameter" "docker_image_id" {
      name = "/my-api/${var.environment}/docker-image-tag"
    }
    
    // Use it later on...
    container_image = "<AWS_ACCOUNT_ID>.dkr.ecr.<REGION>.amazonaws.com/my-api:${data.aws_ssm_parameter.docker_image_id.value}"
    
  • すべての完了!
  • 現在、あなたはterraformとecsで完全な連続配備パイプラインを準備しました.ここでは、システムがどのように動作するかを示します
  • はユニークな方法でタグ付けされた新しいECRイメージを作成し、構築する
  • ビルドパイプラインは、この新しいイメージタグのリリースパイプラインを何らかの方法で通知します
  • リリースパイプラインは、イメージタグに基づいてSSMパラメータを更新し、その環境のための地形形式のパイプラインをトリガします.
  • Terraformは新しいSSM値を拾い上げて、それを実行します
  • このアプローチには2つの明らかな欠点があります.
    複数のAPIへの複数の更新プログラムは、手動でterraformパイプラインを一度実行する必要がロック問題を引き起こす可能性があります.
  • それは他のアプローチより少し遅いです、しかし、私が見つけることができた最高のもの.さらに、あなたのterraformレポが我々のもののような2分未満で展開するならば、それは大きな問題でありません.