web-dev-qa-db-ja.com

AWS CodeDeploy / CodePipeline / S3を使用してGitlab-CiでEC2にデプロイする方法

Gradleを使用してScalaをベースにしたSlackBotプロジェクトに取り組んでおり、AWS EC2にデプロイする目的でGitlab-CIを活用する方法を検討しています。

Gitlab-CIでアプリケーションを完全にビルドおよびテストできます。

CodeDeployとCodePipelineを使用してGitlab-CIからAmazon EC2へのデプロイを実行するにはどうすればよいですか?

これを行うためのガイドとして回答してください。

30
autronix

以下に示すガイドに合わせてサンプルファイルのセットを作成しました。これらのファイルは、次のリンクから入手できます。 https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/

範囲

このガイドでは、次のことを前提としています。

  • Gitlab EEホストプロジェクト-プライベートCE/EEインスタンスで動作する場合があります(テストされていません)
  • GITバージョン管理リポジトリとしてのGitlab
  • 継続的統合エンジンとしてのGitlab-CI
  • 既存のAWSアカウント
  • デプロイメントのターゲット本番またはステージングシステムとしてのAWS EC2
  • Amazon Linux AMIを実行しているAWS EC2インスタンス
  • デプロイファイルのストレージ機能としてのAWS S3
  • プロジェクトの展開エンジンとしてのAWS CodeDeploy
  • デプロイのパイプラインとしてのAWS CodePipeline

提供されている_.gitlab-ci.yml_サンプルは、Java/Scala + Gradleプロジェクトに基づいています。このスクリプトは一般的な例として提供されており、この方法で継続的デリバリーを実装する場合、特定のニーズに合わせて調整する必要があります。

このガイドでは、ユーザーがAWSサービスと必要なタスクの実行方法に関する基本的な知識を持っていることを前提としています。

:このサンプルで提供されるガイドでは、AWSコンソールを使用してタスクを実行します。ここで実行されるタスクに相当するCLIが存在する可能性がありますが、これらはガイド全体ではカバーされません。

動機

これらのスクリプトと展開ガイドを作成する動機は、GitlabとAWS EC2を使用して継続的デリバリーを実装する方法を示す適切なチュートリアルが利用できないことにあります。 Gitlabは、Digital Oceanと提携して、無料で利用可能なCIエンジンを導入しました。これにより、ユーザーリポジトリは良質のCIを無料で利用できます。

Gitlabを使用する主な利点の1つは、さまざまな手順を実行してビルドを検証するための組み込みの継続的統合コンテナーを提供することです。残念なことに、GitblabもAWSも、ビルドを渡すことで継続的な配信を実行できる統合を提供します。

このガイドとスクリプト( https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/ )は、 GitlabとAWS EC2の両方を使用した成功したCIとCD。このタイプの実装を他の誰もが開始するのに役立ちます。

AWSで環境をセットアップする

継続的配信プロセスを成功させるための最初のステップは、AWSに必要なオブジェクトをセットアップして、展開プロセスを成功させることです。

AWS IAMユーザー

最初の要件は、IAMユーザーをセットアップすることです。

https://console.aws.Amazon.com/iam/home#users

  1. ユーザーを作成する
  2. 次のアクセス許可を添付します。

    • CodePipelineFullAccess
    • AmazonEC2FullAccess
    • AmazonS3FullAccess
    • AWSCodeDeployFullAccess
    • インラインポリシー:

      _  {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "autoscaling:*",
                "codedeploy:*",
                "ec2:*",
                "elasticloadbalancing:*",
                "iam:AddRoleToInstanceProfile",
                "iam:CreateInstanceProfile",
                "iam:CreateRole",
                "iam:DeleteInstanceProfile",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:GetInstanceProfile",
                "iam:GetRole",
                "iam:GetRolePolicy",
                "iam:ListInstanceProfilesForRole",
                "iam:ListRolePolicies",
                "iam:ListRoles",
                "iam:PassRole",
                "iam:PutRolePolicy",
                "iam:RemoveRoleFromInstanceProfile",
                "s3:*"
              ],
              "Resource": "*"
            }
          ]
        }
      _
  3. セキュリティ認証情報を生成する

:上記のポリシーの範囲は非常に広いです。特定のリソースのみへのアクセスを制限するカスタムポリシーを作成することにより、要件を調整できます。

:これらの資格情報を安全な場所に保管してください。それらは後のステップで必要になります。

AWS EC2インスタンスとロール

CodeDeployのインスタンスロール

https://console.aws.Amazon.com/iam/home#roles

S3にアクセスするためにEC2インスタンスに割り当てられる新しいロールを作成し、

  1. 命名規則に従って名前を設定します(例:MyDeploymentAppRole
  2. EC2インスタンスが他のAWSサービスを実行できるようにするには、_Amazon EC2_を選択します
  3. 次のポリシーを添付します。
    • AmazonEC2FullAccess
    • AmazonS3FullAccess
    • AmazonCodeDeployRole

:上記のポリシーの範囲は非常に広いです。特定のリソースのみへのアクセスを制限するカスタムポリシーを作成することにより、要件を調整できます。

インスタンスを起動

https://console.aws.Amazon.com/ec2/v2/home

_Launch Instance_をクリックして、次の手順に従います。

  • Amazon Linux AMI 2016.03.3 (HVM), SSD Volume Typeを選択します
  • 必要なインスタンスタイプを選択します(デフォルトではt2.micro)
  • _IAM Role_を選択してMyDeploymentAppRoleにします(前のセクションで作成した名前に基づいて)
  • 適切なストレージを選択します
  • 適切な名前でインスタンスにタグを付けます(つまり_MyApp-Production-Instance_)
    • 必要に応じて追加のタグを追加します
  • 必要に応じてセキュリティグループを構成します
  • インスタンスを確認して起動する

SSHキーを生成または使用する可能性が提供されます。適切な適切な方法を選択してください。

インスタンス環境のセットアップ

CodeDeploy Agentのインストール

新しく作成したEC2インスタンスにログインし、指示に従います:

CodeDeployの重要なパス:

  • CodeDeploy展開ベースディレクトリ:_/opt/codedeploy-agent/deployment-root/_
  • CodeDeployログファイル:_/var/log/aws/codedeploy-agent/codedeploy-agent.log_

Tip:_tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log_を実行して、展開をリアルタイムで追跡します。

プロジェクトの前提条件をインストールしますプロジェクトに実行する前提条件がある場合は、デプロイメントを実行する前にそれらをインストールしてください。そうしないと、起動スクリプトが失敗する可能性があります。

AWS S3リポジトリ

https://console.aws.Amazon.com/s3/home

この手順では、展開ファイルを保持するS3バケットを作成する必要があります。

次の手順に従ってください。

  1. _Create Bucket_ を選択します
    • バケット名を選択します(例:_my-app-codepipeline-deployment_)
    • 地域を選択してください
  2. バケットのコンソールでProperties を選択します
    • Versioningメニューを展開します
    • _Enable Versioning_を選択します

AWS CodeDeploy

https://console.aws.Amazon.com/codedeploy/home#/applications

基本的な要素が設定されたので、CodeDeployでDeploymentアプリケーションを作成する準備ができました

CodeDeployデプロイメントアプリケーションを作成するには、次の手順に従います。

  1. _Create New Application_を選択します
  2. アプリケーション名を選択します(つまり_MyApp-Production_)
  3. 展開グループ名を選択します(例_MyApp-Production-Fleet_)
  4. この展開の影響を受けるEC2インスタンスを選択します-_Search by Tags_
    • Keyの下でNameを選択します
    • Valueの下で_MyApp-Production-Instance_を選択します
  5. _Service Role_で、MyDeploymentAppRoleを選択します
  6. _Create Application_をクリックします

:デプロイメントの対象となる目的のインスタンスに適用される関連タグにデプロイメントを割り当てることができます。簡単にするために、名前タグのみを使用して、以前に定義したインスタンスを選択しています。

AWS CodePipeline

https://console.aws.Amazon.com/codepipeline/home#/dashboard

次のステップは、S3バケットとCodeDeployプロセス間の接続の実行を担当するCodePipelineの作成に進むことです。

CodePipelineを作成するには、次の手順を実行します。

  1. _Create Pipeline_をクリックします
  2. パイプラインに名前を付けます(例:MyAppDeploymentPipeline
  3. _Source Provider_を_Amazon S3_ に設定します
    • _Amazon S3 location_をバケットとターゲット展開ファイルのアドレスに設定します(つまり_s3://my-app-codepipeline-deployment/myapp.Zip_)
  4. _Build Provider_をNoneに設定-これは、後で説明するようにGitlab-CIによって既に処理されています
  5. _Deployment Provider_を_AWS CodeDeploy_ に設定します
    • _Application Name_をCodeDeployアプリケーションの名前に設定します(つまり_MyApp-Production_)
    • _Deployment Group_をCodeDeploy展開グループの名前に設定します(つまり_MyApp-Production-Fleet_)
  6. パイプラインサービスロールの作成または選択
  7. 確認して、_Create Pipeline_をクリックします

Gitlabで環境をセットアップする

AWS環境がアプリケーションのデプロイを受け取る準備ができたので、CI環境と設定のセットアップを進めて、S3、CodeDeploy、およびCodePipelineを使用してコードがビルドされ、EC2インスタンスにデプロイされるようにします。

Gitlab変数

展開が機能するためには、プロジェクトリポジトリにいくつかの環境変数を設定する必要があります。

Gitlabプロジェクトで、プロジェクトのVariablesエリアに移動し、次の変数を設定します。

  • _AWS_DEFAULT_REGION_ => AWSリージョン
  • _AWS_SECRET_ACCESS_KEY_ => AWSユーザー認証情報の秘密キー(ユーザーの認証情報を生成したときに取得)
  • _AWS_ACCESS_KEY_ID_ => AWSユーザー認証情報キーID(ユーザーの認証情報を生成したときに取得)
  • _AWS_S3_LOCATION_ =>展開Zipファイルの場所(つまり_s3://my-app-codepipeline-deployment/my_app.Zip_)

これらの変数には、Gitlab-CIコンテナーによって実行されるスクリプトからアクセスできます。

起動スクリプト

簡単な起動スクリプトが提供されています( https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/blob/master/deploy/extras/my_app.sh )次のタスクを実行するための展開:

  • アプリケーションを起動し、PIDファイルを作成します
  • PIDファイルを使用してアプリケーションのステータスを確認します
  • アプリケーションを停止する

このスクリプトは_deploy/extras/my_app.sh_にあります

Gitlab-ci.ymlを作成する

_gitlab-ci.yml_ファイルは、特定のコミットに関連付けられた継続的統合タスクの実行を担当します。これは、継続的インテグレーションのステップのさまざまなフェーズに対応する段階で編成されたシェルスクリプトの単純化されたグループとして機能します。

詳細とリファレンスの詳細については、次の2つのリンクを参照してください。

次のツールを使用して、いつでも_gitlab-ci.yml_ファイルの構文を検証できます。 https://gitlab.com/ci/lint

展開のために、このガイドで提供されるサンプルの最後の部分のみを取り上げます。

_deploy-job:
  # Script to run for deploying application to AWS
  script:
    - apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
    - pip install -U pip  # pip update
    - pip install awscli  # AWS CLI installation
    - $G build -x test -x distTar # # Build the project with Gradle
    - $G distZip  # creates distribution Zip for deployment
    - aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
  # requires previous CI stages to succeed in order to execute
  when: on_success
  stage: deploy
  environment: production
  cache:
    key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME"
    untracked: true
    paths:
        - build/
  # Applies only to tags matching the regex: ie: v1.0.0-My-App-Release
  only:
    - /^v\d+\.\d+\.\d+-.*$/
  except:
    - branches
    - triggers
_

この部分は、前のC.Iがある場合は、それに続く展開に関連付けられているジョブ全体を表します。ステージ。

展開に関連する関連部分は次のとおりです。

_# Script to run for deploying application to AWS
script:
  - apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
  - pip install -U pip  # pip update
  - pip install awscli  # AWS CLI installation
  - $G build -x test -x distTar # # Build the project with Gradle
  - $G distZip  # creates distribution Zip for deployment
  - aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
_

最初のステップでは、pythonパッケージ管理システム:pippipはAWS CLIをインストールするために必要です。 S3

この例では、Gradle(環境変数_$G_で定義)を使用しています。 Gradleは、デプロイメントファイルを自動的に圧縮するモジュールを提供します。配布するプロジェクトのタイプに応じて、このメソッドは配布Zipファイル_my_app.Zip_を生成するために異なります。

_aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION_コマンドは、以前に定義したAmazon S3の場所に配布Zipファイルをアップロードします。このファイルは、CodePipelineによって自動的に検出され、処理されてCodeDeployに送信されます。最後に、CodeDeployは_appspec.yml_ファイルで指定されたCodeDeployエージェントを介して必要なタスクを実行します。

Appspec.ymlの作成

_appspec.yml_は、展開ファイルを受け取った後にCodeDeployが従う動作を定義します。

このガイドとともに、展開のさまざまな段階で実行されるサンプルスクリプトとともにサンプルファイルが提供されています。

_appspec.yml_ファイルのビルド方法の詳細については、CodeDeploy AppSpecの仕様を参照してください: http://docs.aws.Amazon.com/codedeploy/latest/userguide/app-spec- ref.html

展開ZipFileの生成

CodeDeployが正しく機能するためには、アプリケーションの適切に生成されたZipファイルを作成する必要があります。

Zipファイルには以下が含まれている必要があります。

  • Zipルート
    • _appspec.yml_ => CodeDeployの展開手順
    • 展開段階のスクリプト
    • サンプルがZipファイルのscriptsディレクトリに配置される場合、アプリケーションディレクトリのルートに存在する_my_app.sh_スクリプトが必要になります(つまり、_my_app_ディレクトリがZip)
    • 配布コード-この例では、_my_app_ディレクトリの下にあります

GradleやMavenなどのツールは、Zip生成プロセスに特定の変更を加えた配布Zipファイルを生成できます。このようなツールを使用しない場合は、Gitlab-CIにこのZipファイルを別の方法で生成するよう指示する必要があります。この方法は、このガイドの範囲外です。

アプリケーションをEC2にデプロイする

このガイドの最後の手順は、実際に展開を成功させることです。

継続的インテグレーションの段階は、_gitlab-ci.yml_で設定されたルールによって定義されます。このガイドで提供される例は、次の正規表現に一致する参照のデプロイを開始します:_/^v\d+\.\d+\.\d+-.*$/_。

この場合、タグ_v1.0.0-My-App-Alpha-Release_をgit経由でリモートGitlabにプッシュすると、展開プロセスが開始されます。プロジェクトの要件に応じて、これらのルールを調整できます。

提供されている_gitlab-ci.yml_の例は、タグ_v1.0.0-My-App-Alpha-Release_を検出するときに次のジョブを実行します。

  • ビルドジョブ-ソースのコンパイル
  • テストジョブ-単体テストの実行
  • deploy-job-ソースをコンパイルし、配布Zipを生成し、ZipをAmazon S3にアップロードします

配布ZipがAmazon S3にアップロードされると、次の手順が実行されます。

  • CodePipelineは、S3 Zipファイルのリビジョンの変更を検出します
  • CodePipelineはファイルを検証します
  • CodePipelineは、CodeDeployのバンドルの準備ができたというシグナルを送信します
  • CodeDeployは展開手順を実行します
    • 開始-デプロイメントの初期化
    • アプリケーション停止-フック用に定義されたスクリプトを実行します
    • DownloadBundle-CodePipelineを介してS3リポジトリからバンドルファイルを取得します
    • BeforeInstall-フック用に定義されたスクリプトを実行します
    • インストール-_appspec.yml_のfilesセクションで定義された展開場所にコンテンツをコピーします
    • AfterInstall-フック用に定義されたスクリプトを実行します
    • ApplicationStart-フック用に定義されたスクリプトを実行します
    • ValidateService-フック用に定義されたスクリプトを実行します
    • End-展開が正常に完了したことをCodePipelineに通知します

展開に成功したスクリーンショット:

Gitlab Deploy Job

CodePipeline Deploy

CodeDeploy hook script log

参照資料

116
autronix