4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS & GameAdvent Calendar 2020

Day 23

copilotを利用したらモダンなECS環境を爆速で構築できた

Last updated at Posted at 2020-12-24

この記事について

AWS & Game Advent Calendar 2020 23日目の記事になります。

AWSでコンテナを動かす場合真っ先に候補に上がるサービスはECSかと思います。
とても便利なサービスなのは間違いありませんが、いざ使うとなると考慮する点がたくさんあります。

  • ネットワーク(VPC)設計
  • ECSのクラスタ/サービス/タスク定義の作成
  • デプロイフローの確立
  • ロギング

上記はあくまで一例ですが、基本どのプロジェクトでECSを使う場合でも、タスクが起動するVPCの設計から始まり、デプロイされたタスクが出力するログをどのように集約/管理するのかまでは共通で考える必要があるのではないかと思います。
その一方で、ECSが一般的に広く使われるようになっていて、ある種の「利用する上でのベストプラクティス」的なものが生まれつつあるように思います。
都度1から構築しても良いですが、できればベストプラクティスに沿ってもっと簡単に構築できるようになれば便利ですよね。
そんな願いを叶えてくれるツールが2020/11/23にGAしています。「AWS Copilot」と言います。

AWS Copilot is 何?

  • Amazon ECS CLI の後継に当たるものです
  • AWSのECSチームのエンジニアやユーザーが作り上げてきたベストプラクティスに基いてデフォルトでモダンかつプロダクションレディなインフラを構築できます

AWS Copilot のご紹介
https://aws.amazon.com/jp/blogs/news/introducing-aws-copilot/

実際に使ってみる

インストール

GitHubから最新のバイナリファイルを落としてきます

$ curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/download/v0.1.0/copilot-darwin-v0.1.0 && chmod +x /usr/local/bin/copilot
$ copilot --help

👩‍✈️ Launch and manage applications on Amazon ECS and AWS Fargate.

Commands 
  Getting Started 🌱
    init        Create a new ECS application.
    docs        Open the copilot docs.
 
  Develop ✨
    app         Commands for applications.
                Applications are a collection of services and environments.

    env         Commands for environments.
                Environments are deployment stages shared between services.

    svc         Commands for services.
                Services are long-running Amazon ECS services.
 
  Release 🚀
    pipeline    Commands for pipelines.
                Continuous delivery pipelines to release services.

    deploy      Deploy your service.
 
  Settings ⚙️
    version     Print the version number.
    completion  Output shell completion code.

Flags
  -h, --help      help for copilot
  -v, --version   version for copilot

Examples
  Displays the help menu for the "init" command.
  `$ copilot init --help`

サンプルアプリケーションのClone

$ git clone https://github.com/aws-samples/amazon-ecs-cli-sample-app.git aws-copilot-example

Credentialの設定

aws configure でプロファイルを作成してAWS_PROFILEとして環境変数に設定しておきます。

$ aws configure --profile copilot-example
$ export AWS_PROFILE=copilot-example

アプリケーションのセットアップ

GitからCloneしたディレクトリに移動してでセットアップを行っていきます。
copilot initを実行して対話式で情報の入力をしていくことでAWS上に必要なリソースを構築することができます。

$ cd aws-copilot-example
$ copilot init

Note: It's best to run this command in the root of your Git repository.
Welcome to the Copilot CLI! We're going to walk you through some questions
to help you get set up with an application on ECS. An application is a collection of
containerized services that operate together.


  What would you like to name your application? [? for help] copilot-example-app

Application name: copilot-example-app

  Which service type best represents your service's architecture?  [Use arrows to move, type to filter, ? for more help]
  > Load Balanced Web Service
    Backend Service

Application name: copilot-example-app
Service type: Load Balanced Web Service

  What do you want to name this Load Balanced Web Service? [? for help] copilot-example-service

Application name: copilot-example-app
Service type: Load Balanced Web Service
Service name: copilot-example-service

  Which Dockerfile would you like to use for copilot-example-service?  [Use arrows to move, type to filter, ? for more help]
  > ./Dockerfile

Application name: copilot-example-app
Service type: Load Balanced Web Service
Service name: copilot-example-service
Dockerfile: ./Dockerfile
no EXPOSE statements in Dockerfile ./Dockerfile

  Which port do you want customer traffic sent to? [? for help] (80) 80

Application name: copilot-example-app
Service type: Load Balanced Web Service
Service name: copilot-example-service
Dockerfile: ./Dockerfile
no EXPOSE statements in Dockerfile ./Dockerfile
Port: 80
Ok great, we'll set up a Load Balanced Web Service named copilot-example-service in application copilot-example-app listening on port 80.

✔ Created the infrastructure to manage services under application copilot-example-app.

✔ Manifest file for service copilot-example-service already exists at copilot/copilot-example-service/manifest.yml, skipping writing it.
Your manifest contains configurations like your container size and port (:80).

✔ Created ECR repositories for service copilot-example-service.

All right, you're all set for local development.

  Would you like to deploy a test environment? [? for help] (y/N) y

All right, you're all set for local development.
Deploy: Yes

All right, you're all set for local development.
Deploy: Yes

✔ Created the infrastructure for the test environment.
- Virtual private cloud on 2 availability zones to hold your services     [Complete]
- Virtual private cloud on 2 availability zones to hold your services     [Complete]
  - Internet gateway to connect the network to the internet               [Complete]
  - Public subnets for internet facing services                           [Complete]
  - Private subnets for services that can't be reached from the internet  [Complete]
  - Routing tables for services to talk with each other                   [Complete]
- ECS Cluster to hold your services                                       [Complete]
- Application load balancer to distribute traffic                         [Complete]
✔ Linked account XXXXXXXXXXXX and region ap-northeast-1 to application copilot-example-app.

✔ Created environment test in region ap-northeast-1 under application copilot-example-app.
Sending build context to Docker daemon  88.06kB
Step 1/2 : FROM nginx
 ---> ae2feff98a0c
Step 2/2 : COPY index.html /usr/share/nginx/html
 ---> Using cache
 ---> ad1b08cb2bb0
Successfully built ad1b08cb2bb0
Successfully tagged XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/copilot-example-app/copilot-example-service:cee7709
Login Succeeded
The push refers to repository [XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/copilot-example-app/copilot-example-service]
2e8160029ff7: Pushed 
4eaf0ea085df: Pushed 
2c7498eef94a: Pushed 
7d2b207c2679: Pushed 
5c4e5adc71a8: Pushed 
87c8a1d8f54f: Pushed 
cee7709: digest: sha256:fe7757f53a6d9a90c57cafd32578e5b5290430cf0a06067ba92b0031fb00c873 size: 1570


✔ Deployed copilot-example-service, you can access it at http://{ELB_ENDPOINT}

実行が完了するとテスト環境が作成されELBのエンドポイントのURLが返ってきました。アクセスしてみましょう。
スクリーンショット 2020-12-25 2.48.21.png

表示できましたね。今回はサンプルアプリケーションですが、実際の開発でこの画面を表示させるまでに構築する必要のあるAWSリソースは結構多いです。
コマンドの実行自体は10分程度で完了するので短時間で必要なものを揃えられるというのはとても魅力的です。
ちなみに裏ではCloudFormationのスタックが実行されています。

論理ID タイプ
AdministrationRole AWS::IAM::Role
ExecutionRole AWS::IAM::Role
CloudformationExecutionRole AWS::IAM::Role
Cluster AWS::ECS::Cluster
DefaultHTTPTargetGroup AWS::ElasticLoadBalancingV2::TargetGroup
DefaultPublicRoute AWS::EC2::Route
EnableLongARNFormatAction Custom::EnableLongARNFormatFunction
EnableLongARNFormatFunction AWS::Lambda::Function
EnvironmentManagerRole AWS::IAM::Role
EnvironmentSecurityGroup AWS::EC2::SecurityGroup
EnvironmentSecurityGroupIngressFromPublicALB AWS::EC2::SecurityGroupIngress
EnvironmentSecurityGroupIngressFromSelf AWS::EC2::SecurityGroupIngress
HTTPListener AWS::ElasticLoadBalancingV2::Listener
InternetGateway AWS::EC2::InternetGateway
InternetGatewayAttachment AWS::EC2::VPCGatewayAttachment
PrivateSubnet1 AWS::EC2::Subnet
PrivateSubnet2 AWS::EC2::Subnet
PublicLoadBalancer AWS::ElasticLoadBalancingV2::LoadBalancer
PublicLoadBalancerSecurityGroup AWS::EC2::SecurityGroup
PublicRouteTable AWS::EC2::RouteTable
PublicSubnet1 AWS::EC2::Subnet
PublicSubnet1RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation
PublicSubnet2 AWS::EC2::Subnet
PublicSubnet2RouteTableAssociation AWS::EC2::SubnetRouteTableAssociation
ServiceDiscoveryNamespace AWS::ServiceDiscovery::PrivateDnsNamespace
VPC AWS::EC2::VPC
ECRRepocopilotDASHexampleDASHservice AWS::ECR::Repository
KMSKey AWS::KMS::Key
PipelineBuiltArtifactBucket AWS::S3::Bucket
PipelineBuiltArtifactBucketPolicy AWS::S3::BucketPolicy
CustomResourceRole AWS::IAM::Role
DiscoveryService AWS::ServiceDiscovery::Service
ExecutionRole AWS::IAM::Role
HTTPListenerRule AWS::ElasticLoadBalancingV2::ListenerRule
HTTPRulePriorityAction Custom::RulePriorityFunction
HTTPWaitHandle AWS::CloudFormation::WaitConditionHandle
LogGroup AWS::Logs::LogGroup
RulePriorityFunction AWS::Lambda::Function
Service AWS::ECS::Service
TargetGroup AWS::ElasticLoadBalancingV2::TargetGroup
TaskDefinition AWS::ECS::TaskDefinition
TaskRole AWS::IAM::Role
WaitUntilListenerRuleIsCreated AWS::CloudFormation::WaitCondition

これだけのリソースが構築されていました。
今のところは起動タイプがFargateのみになっていて、EC2で起動したい場合は手動で作成する必要がありそうなので
copilotをECS環境構築のスターターキットとして利用し、細かな要件や設定は自分達で追加していくといった使い方が1番しっくり来ますね。

アプリケーションに対してのcopilotからの操作

copilot app showでcopilotで構築したアプリケーション/環境/サービスの情報を参照できます。

$ copilot app show
About

  Name              copilot-example-app
  URI               

Environments

  Name              AccountID           Region
  test              XXXXXXXXXXXX        ap-northeast-1

Services

  Name                     Type
  copilot-example-service  Load Balanced Web Service

起動したタスクから出力されるログはCloudWatchlogsに保存されるようになっています。
マネジメントコンソールから見てもいいですがcopilot svc logsでログの閲覧が可能です。

$ copilot svc logs
Showing logs of service copilot-example-service deployed in environment test
copilot-example-service/0 10.0.1.45 - - [24/Dec/2020:18:03:01 +0000] "GET / HTTP/1.1" 200 3165 "-" "ELB-HealthChecker/2.0" "-"
copilot-example-service/0 10.0.1.45 - - [24/Dec/2020:18:03:12 +0000] "GET / HTTP/1.1" 200 3165 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "XXX.XXX.XXX.XXX"
copilot-example-service/0 10.0.1.45 - - [24/Dec/2020:18:03:12 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "XXX.XXX.XXX.XXX"

現在はテスト環境しかないので本番環境を作成してみましょう。
新たにprodという環境を作成して先ほど作成したcopilot-example-serviceをデプロイします。

$ copilot env init --name prod
$ copilot svc deploy --name copilot-example-service --env prod

デプロイが完了するとテスト環境を作成したときと同じくELBのエンドポイント経由でECSにアクセスできるようになります。
アプリケーションの情報とログを見てみましょう。

$ copilot app show                                            
About

  Name              copilot-example-app
  URI               

Environments

  Name              AccountID           Region
  test              XXXXXXXXXXXX        ap-northeast-1
  prod              XXXXXXXXXXXX        ap-northeast-1

Services

  Name                     Type
  copilot-example-service  Load Balanced Web Service

$ copilot svc logs copilot-example-service --env prod
Showing logs of service copilot-example-service deployed in environment prod
copilot-example-service/7 10.0.0.206 - - [24/Dec/2020:18:20:25 +0000] "GET / HTTP/1.1" 200 3165 "-" "ELB-HealthChecker/2.0" "-"
copilot-example-service/7 10.0.0.206 - - [24/Dec/2020:18:20:30 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "XXX.XXX.XXX.XXX"
copilot-example-service/7 10.0.0.206 - - [24/Dec/2020:18:20:30 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" "XXX.XXX.XXX.XXX"

正常にアクセスが来ていますね、問題なさそうです。
copilot app showだと若干情報が少なめですがcopilot svc statusでサービスのステータスを確認できます。

$ copilot svc status copilot-example-service --env prod
Showing status of service copilot-example-service deployed in environment prod
Service Status

  ACTIVE 1 / 1 running tasks (0 pending)

Last Deployment

  Updated At        6 minutes ago
  Task Definition   arn:aws:ecs:ap-northeast-1:XXXXXXXXXXXX:task-definition/copilot-example-app-prod-copilot-example-service:1

Task Status

  ID                Image Digest        Last Status         Health Status       Started At          Stopped At
  7788f7bc          fe7757f5            RUNNING             UNKNOWN             7 minutes ago       -

Alarms

  Name              Health              Last Updated        Reason

一通り動作を確認できました。費用がかかるのでお掃除しましょう。copilot app deleteを実行します。

$ copilot app delete
Are you sure you want to delete application copilot-example-app? Yes
✔ Deleted service copilot-example-service from environment test.
✔ Deleted service copilot-example-service from environment prod.
✔ Deleted service copilot-example-service resources from application copilot-example-app.
✔ Deleted service copilot-example-service from application copilot-example-app.
✔ Deleted environment test from application copilot-example-app.
✔ Deleted environment prod from application copilot-example-app.
✔ Cleaned up deployment resources.
✔ Deleted application resources.
✔ Deleted application configuration.
✔ Deleted local .workspace file.

お掃除できました、CloudFormationで管理されているのでそこから削除すれば不要なものは残らず綺麗になりますね。

まとめ

copilotを利用することでベストプラクティスに沿ったECS環境をお手軽に構築できました。
今回の記事ではご紹介していませんが、デプロイに利用するCodePipelineなどのCode系サービスもcopilotから構築して
GitへのPushをトリガーに自動デプロイするフローを整えることが可能ですのでまたの機会に試してみたいと思います。
まだGAされたばかりなので今後もさらに便利なアップデートが行われていくに違いありません。
私自身も定期的にcopilotのアップデートをウォッチしていきたいと思います。

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?