Help us understand the problem. What is going on with this article?

AWS CodePipelineがECSへのデプロイをサポートしたのでやってみる

More than 1 year has passed since last update.

AWS CodePipeline が Amazon ECSへのデプロイをサポートしました。(先日発表されたばかりのFargateも)
https://aws.amazon.com/jp/about-aws/whats-new/2017/12/aws-codepipeline-adds-support-for-amazon-ecs-and-aws-fargate/
これによりコンテナ上で稼働するアプリケーションの継続的デリバリーがより簡単に実装できるようになります。

早速チャレンジしてみました。

ECSでテスト用のコンテナを起動する

ECR の設定

Elastic Container Registry に今回のテスト用のリポジトリを作成します。
後ほどリポジトリのURIを使用しますので、メモしておきます。

image.png

Dockerfileの作成

今回は公式ドキュメントのhello-worldを流用しました。
基本的にはこちらの手順を踏襲します。

FROM ubuntu:12.04

# Install dependencies
RUN apt-get update -y
RUN apt-get install -y apache2

# Install apache and write hello world message
RUN echo "Hello World!" > /var/www/index.html

# Configure apache
RUN a2enmod rewrite
RUN chown -R www-data:www-data /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2

EXPOSE 80

CMD ["/usr/sbin/apache2", "-D",  "FOREGROUND"]

イメージをビルド

Dockerfileをビルドし、ECRにプッシュします

$ docker build -t ecs-test-repo .
$ docker tag ecs-test-repo:latest 012345678910.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test-repo:latest
$ docker push 012345678910.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test-repo:latest

ECSへのデプロイ

以下のようなタスク定義ファイルを作成します。

imagedefinitions.json
{
    "family": "ecs-hello-world",
    "containerDefinitions": [
        {
            "name": "ecs-hello-world",
            "image": "012345678910.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test-repo:latest",
            "cpu": 10,
            "memory": 128,
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80
                }
            ],
            "entryPoint": [
                "/usr/sbin/apache2",
                "-D",
                "FOREGROUND"
            ],
            "essential": true
        }
    ]
}

AWS CLIでタスク定義の登録を行います。

$ aws ecs register-task-definition --cli-input-json ./imagedefinitions.json

コンソールでタスク定義が登録されていることを確認します。

image.png

新規サービスを作成し、登録したタスクを起動します。

image.png
image.png

クラスタインスタンスのパブリックIPにアクセスすると、Hello Worldが表示されます。
長くなりましたが、以上で事前準備が完了しました。

image.png

AWS CodeCommitの設定

DockerイメージをECRにプッシュするための buildspec.yml を作成し、CodeCommitのリポジトリに追加します。

リポジトリの作成

リポジトリ名を指定して、新規作成します。

image.png

今回、Eメール通知の設定はスキップします。

image.png

リポジトリへの接続

ローカルに作成したリポジトリをcloneします。
リポジトリへの接続には適切な権限をもったIAMユーザおよびGit認証情報が必要ですので
あらかじめ作成しておきます。

$ git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/ecs-test-repo
Cloning into 'ecs-test-repo'...
warning: You appear to have cloned an empty repository.

buildspec.ymlの作成

REPOSITORY_URIにはECRのURIを設定します。
またイメージタグにソースコードのコミットIDを追加するようにします。

buildspec.yml
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION)
      - REPOSITORY_URI=012345678910.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test-repo
      - IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Writing image definitions file...
      - printf '[{"name":"ecs-hello-world","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
    files: imagedefinitions.json

artifacts として事前準備で作成したタスク定義ファイルを指定します。
パイプラインの中でタスク定義の新しいリビジョンが作成され、サービスが更新されます。

CodeCommitへプッシュ

Dockerfile, buildspec.yml, imagedefinitions.json をCodeCommitへプッシュします。
Dockerfileの中身を少しだけ編集しています。

RUN echo "Hello World! by CodePipeline" > /var/www/index.html
$ git add.
$ git commit -m "Adding build specification."
$ git push

image.png

Piepelineの設定

Pipelineの作成

マネージドコンソールの AWS CodePipelineから新規パイプラインを作成します。

image.png

ソースの設定でソースプロバイダを CodeCommitに設定し、先程作成したリポジトリを指定します。

image.png

ビルドの設定で以下のように、選択/入力し、ビルドプロジェクトを保存します。

  • ビルドプロパイダでAWS CodeBuildを選択
  • 新しいビルドプロジェクトを作成 を選択し、任意のプロジェクト名を入力
  • 環境イメージで AWS CodeBuildマネージド型イメージの使用を選択し、OS:Ubuntu、ランタイム:Dockerとする

image.png

デプロイの設定で、プロバイダに Amazon ECS を選択し、展開先のクラスタ名、サービス名を指定します。

image.png

AWS サービスロールを選択します。必要に応じて新規作成もできます。

image.png

レビュー画面で設定値を確認し、パイプラインを作成します。

パイプラインの実行

作成直後にパイプラインが起動します。
パイプライン作成ウィザードの中で、CodeBuildのビルドプロジェクト用のサービスロールを作成していますが、
初期の状態ではECRに対する権限が不足しているため、以下のようにビルドが失敗します。

image.png

そのためIAM管理画面で、作成したサービスロールに対し、AmazonEC2ContainerRegistryPowerUserポリシーを追加します。

image.png

Buildステージを再実行すると今度はステージングまで処理が完了します。
image.png

結果確認

タスク定義を確認すると新しいリビジョンが作成されています。
※途中メモリの設定などを誤り複数回デプロイしているため、以下の画面ショットではリビジョンが4まで増えています。。。

image.png

同様にサービスも新しいタスク定義のリビジョンで更新されています。

image.png

最後にブラウザで確認します。Hello worldのメッセージが更新されていることを確認できました!

image.png

最後に

以上の手順でCodePipelineでECSへのデプロイを行うことができました。
参考になれば幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした