GitLab CI/CDからAWSへのデプロイ

GitLabはAWSへのデプロイに必要なライブラリやツールを含むDockerイメージを提供しています。CI/CDパイプラインでこれらのイメージを参照することができます。

GitLab.comを使用していて、Amazon Elastic Container Service (ECS)にデプロイする場合は、ECSへのデプロイをお読みください。

note
デプロイを自分で設定するのが簡単で、AWSのクレデンシャルを取得する必要があるだけなら、IDトークンとOpenID Connectの使用を検討してください。IDトークンはCI/CD変数に認証情報を格納するよりもセキュリティが高いですが、このページのガイダンスでは動作しません。

AWSでGitLabを認証します。

GitLab CI/CDを使ってAWSに接続するには、認証が必要です。認証を設定したら、CI/CDをデプロイするように設定します。

  1. AWSアカウントにサインオンします。
  2. IAMユーザーを作成します。
  3. ユーザーを選択して、その詳細にアクセスします。セキュリティ資格情報 > 新しいアクセスキーを作成します。
  4. アクセスキーIDとシークレットアクセスキーをメモします。
  5. GitLabプロジェクトで、Settings > CI/CDに進みます。以下のCI/CD変数を設定します:

    環境変数名
    AWS_ACCESS_KEY_IDアクセスキーID
    AWS_SECRET_ACCESS_KEY秘密のアクセスキー
    AWS_DEFAULT_REGIONリージョンコード使用するAWSサービスが選択したリージョンで利用可能か確認することをお勧めします。
  6. 変数はデフォルトで保護されています。保護されていないブランチやタグでGitLab CI/CDを使用するには、変数を保護するチェックボックスをオフにしてください。

イメージを使用して AWS コマンドを実行

イメージにAWS Command Line Interface が含まれている場合、プロジェクトの.gitlab-ci.yml ファイルでそのイメージを参照できます。そうすると、CI/CD ジョブでaws コマンドを実行できます。

使用例:

deploy:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  script:
   - aws s3 ...
   - aws create-deployment ...
  environment: production

GitLabはAWS CLIを含むDockerイメージを提供しています:

  • イメージはGitLabコンテナレジストリにホストされています。最新のイメージはregistry.gitlab.com/gitlab-org/cloud-deploy/aws-base:latest
  • イメージはGitLabリポジトリに保存されます。

別の方法として、Amazon Elastic Container Registry(ECR)イメージを使うこともできます。ECR リポジトリにイメージをプッシュする方法をご覧ください。

サードパーティのレジストリからイメージを使用することもできます。

ECSへのアプリケーションのデプロイ

  • GitLab 12.9で導入されました
  • Deploy-ECS.gitlab-ci.yml テンプレートは GitLab 13.2 でAWS/Deploy-ECS.gitlab-ci.yml移動しました。

Amazon ECSクラスターへのアプリケーションのデプロイを自動化できます。

前提条件:

  • GitLabでAWSを認証します。
  • Amazon ECSでクラスターを作成します。
  • ECSサービスやAmazon RDS上のデータベースなどの関連コンポーネントを作成します。
  • ECSタスク定義を作成します。containerDefinitions[].name 属性の値は、対象のECSサービスで定義されているContainer name と同じです。タスク定義は以下のようになります:

ECSクラスターにデプロイします:

  1. GitLabプロジェクトで、Settings > CI/CDに進みます。以下のCI/CD変数を設定します。これらの名前は、Amazon ECSダッシュボードで対象のクラスターを選択することで見つけることができます。

    環境変数名
    CI_AWS_ECS_CLUSTERデプロイの対象となるAWS ECSクラスターの名前。
    CI_AWS_ECS_SERVICEAWS ECS クラスターに関連付けられた対象サービスの名前。この変数が適切な環境 (production,staging,review/*) にスコープされていることを確認します。
    CI_AWS_ECS_TASK_DEFINITIONタスク定義が ECS にある場合、サービスに紐づくタスク定義の名前。
    CI_AWS_ECS_TASK_DEFINITION_FILEタスク定義が GitLab 内の JSON ファイルの場合は、パスを含むファイル名。例えば、ci/aws/my_task_definition.json 。 JSONファイル内のタスク定義の名前が、ECS内の既存のタスク定義と同じ場合、CI/CDの実行時に新しいリビジョンが作成されます。そうでない場合は、リビジョン1から始まる、まったく新しいタスク定義が作成されます。
    caution
    CI_AWS_ECS_TASK_DEFINITION_FILECI_AWS_ECS_TASK_DEFINITION の両方を定義した場合、CI_AWS_ECS_TASK_DEFINITION_FILE が優先されます。
  2. このテンプレートを.gitlab-ci.yml に含めてください:

    include:
      - template: AWS/Deploy-ECS.gitlab-ci.yml
    

    AWS/Deploy-ECS テンプレートはGitLabに同梱されており、GitLab.comで入手できます。

  3. 更新した.gitlab-ci.yml をコミットしてプロジェクトのリポジトリにプッシュしてください。

アプリケーションのDockerイメージが再構築され、GitLabコンテナレジストリにプッシュされます。イメージが非公開レジストリにある場合は、タスク定義がrepositoryCredentials 属性](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/private-auth.html) で[設定されていることを確認してください。

対象となるタスク定義は、新しいDockerイメージの場所で更新され、結果としてECSに新しいリビジョンが作成されます。

最後に、AWS ECSサービスがタスク定義の新しいリビジョンで更新され、クラスターがアプリケーションの最新バージョンをプルするようになります。

note
ECS デプロイジョブは、ロールアウトが完了するまで待機してから終了します。この動作を無効にするには、CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED を空でない値に設定します。
caution
AWS/Deploy-ECS.gitlab-ci.yml テンプレートには、Jobs/Build.gitlab-ci.ymlJobs/Deploy/ECS.gitlab-ci.ymlの 2 つのテンプレートが含まれます。これらのテンプレートを単独で含めないでください。](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml) テンプレートのみをインクルードしてください。これらの他のテンプレートは、メイン・テンプレートと共にのみ使用するように設計されています。これらのテンプレートは予期せず移動したり、変更される可能性があります。また、これらのテンプレート内のジョブ名は変更される可能性があります。名前が変更されるとオーバーライドが機能しなくなるため、独自のパイプラインでこれらのジョブ名をオーバーライドしないでください。

アプリケーションをEC2にデプロイします。

GitLab 13.5 で導入されました

GitLabはAmazon EC2へのデプロイを支援するために、AWS/CF-Provision-and-Deploy-EC2 と呼ばれるテンプレートを提供しています。

関連するJSONオブジェクトを設定し、テンプレートを使用すると、パイプライン:

  1. スタックが作成されます:AWS CloudFormationAPI を使用してインフラストラクチャがプロビジョニングされます。
  2. S3 バケットにプッシュします:ビルドが実行されると、アーティファクトが作成されます。アーティファクトはAWS S3バケットにプッシュされます。
  3. EC2にデプロイ: コンテンツはAWS EC2インスタンスにデプロイされます。

CF-Provision-and-Deploy-EC2 diagram

テンプレートとJSONの設定

EC2にデプロイするには、次の手順を実行します。

  1. スタック用のJSONを作成します。AWSテンプレートを使用します。
  2. S3にプッシュするJSONを作成します。以下の詳細を含めます。

    {
      "applicationName": "string",
      "source": "string",
      "s3Location": "s3://your/bucket/project_built_file...]"
    }
    

    source は、build ジョブがアプリケーションをビルドした場所です。ビルドはartifacts:pathsに保存されます。

  3. EC2にデプロイするJSONを作成します。AWSテンプレートを使用します。
  4. パイプラインからJSONオブジェクトにアクセスできるようにします:
    • これらのJSONオブジェクトをリポジトリに保存したい場合は、オブジェクトを3つの別々のファイルとして保存します。

      .gitlab-ci.yml ファイルに、プロジェクトルートからのファイルパスを指すCI/CD 変数を追加します。例えば、JSONファイルが<project_root>/aws フォルダにある場合:

       variables:
         CI_AWS_CF_CREATE_STACK_FILE: 'aws/cf_create_stack.json'
         CI_AWS_S3_PUSH_FILE: 'aws/s3_push.json'
         CI_AWS_EC2_DEPLOYMENT_FILE: 'aws/create_deployment.json'
      
    • これらのJSONオブジェクトをリポジトリに保存したくない場合は、プロジェクト設定で、各オブジェクトを別のファイルタイプのCI/CD変数として追加してください。上記と同じ変数名を使用してください。

  5. .gitlab-ci.yml ファイルに、スタック名の CI/CD 変数を作成します。例えば

    variables:
      CI_AWS_CF_STACK_NAME: 'YourStackName'
    
  6. .gitlab-ci.yml ファイルに CI テンプレートを追加します:

    include:
      - template: AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
    
  7. パイプラインを実行します。

    • CI_AWS_CF_CREATE_STACK_FILE 変数の内容に基づいて AWS CloudFormation スタックが作成されます。スタックが既に存在する場合、このステップはスキップされますが、provision ジョブは実行されます。
    • ビルドされたアプリケーションはS3バケットにプッシュされ、関連するJSONオブジェクトの内容に基づいてEC2インスタンスにデプロイされます。EC2へのデプロイが完了するか失敗すると、デプロイジョブは終了します。

トラブルシューティング

エラー'ascii' codec can't encode character '\uxxxx'

このエラーは、Cloud Deploy イメージが使用するaws-cli ユーティリティからの応答に Unicode 文字が含まれている場合に発生する可能性があります。弊社が提供する Cloud Deploy イメージにはロケールが定義されておらず、デフォルトでは ASCII が使用されます。このエラーを解決するには、次のCI/CD変数を追加します:

variables:
  LANG: "UTF-8"