CodeDeployでECR、ECSにデプロイするパイプラインのチュートリアル
2021/08/30
チュートリアル: Amazon ECR ソースと、ECS と CodeDeploy 間のデプロイを含むパイプラインを作成する
ECSでAppSpecをどう使うのかを知りたかったので、こちらのチュートリアルをやってみました。
目次
IAMロールの作成
- ecsTaskExecutionRole
ecsTaskExecutionRoleの実行ポリシーはAWS管理ポリシーのAmazonECSTaskExecutionRolePolicyです。
信頼ポリシーは、ecs-tasks.amazonaws.comからのリクエストを許可します。
これは、ロール作成時に「Elastic Container Service Task」を選択することで設定されました。
- CodeDeployECSRole
AWS管理ポリシーはAWSCodeDeployRoleForECSです。
信頼ポリシーは、codedeploy.amazonaws.comからのリクエストを許可します。
ロール作成時に「CodeDeploy – ECS」を選択することで設定されました。
イメージを作成してECRにプッシュ
CloudShellでできないかなと思ったのですが、AWS CloudShellコンピューティング環境:仕様とソフトウェアに「現在、AWS CloudShellコンピューティング環境はDockerコンテナをサポートしていません。」とあるので、Cloud9にしました。
1 2 |
$ docker pull nginx |
Nginxのイメージをダウンロードしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ aws ecr create-repository --repository-name nginx { "repository": { "repositoryUri": "123456789012.dkr.ecr.us-east-1.amazonaws.com/nginx", "imageScanningConfiguration": { "scanOnPush": false }, "encryptionConfiguration": { "encryptionType": "AES256" }, "registryId": "123456789012", "imageTagMutability": "MUTABLE", "repositoryArn": "arn:aws:ecr:us-east-1:123456789012:repository/nginx", "repositoryName": "nginx", "createdAt": 1628430987.0 } } |
チュートリアルどおりで、nginxという名前にECRリポジトリを作成しました。
レスポンスのrepositoryUriをコピーしておきます。
1 2 |
$ docker tag nginx:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/nginx:latest |
repositoryUriでnginx:latestイメージをタグ付けしました、
1 2 3 4 5 6 7 8 |
$ aws ecr get-login-password | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com/nginx WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded |
get-login-passwordコマンドで一時的認証を取得して、docker loginコマンドでログインしました。
警告は出ますが、ログイン成功です。
1 2 |
$ docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/nginx:latest |
プッシュしました。
デプロイされました。
CodeCommitリポジトリの作成とクローン
CodeCommitリポジトリはある前提でしたので、作成してCloud9でクローンしました。
Cloud9には、CodeCommit 認証情報ヘルパーがセットアップ済です。
AWS CodeCommit 認証情報ヘルパーをmacOSに設定しました
1 2 |
$ git clone git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/repository-name |
タスク定義ファイルとAppSpecファイルを作成してCodeCommitリポジトリにプッシュ
クローンしたリポジトリのディレクトリに以下のtaskdef.jsonとappspec.yamlを作成しました。
taskdef.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{ "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "containerDefinitions": [ { "name": "sample-website", "image": "nginx", "essential": true, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ] } ], "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "memory": "512", "family": "ecs-demo" } |
1 2 |
$ aws ecs register-task-definition --cli-input-json file://taskdef.json |
タスク定義を登録しました。
登録されました。
taskdef.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
{ "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "containerDefinitions": [ { "name": "sample-website", "image": "<IMAGE1_NAME>", "essential": true, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ] } ], "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "memory": "512", "family": "ecs-demo" } |
ローカルのtaskdef.jsonで、”image”: “
appspec.yaml
1 2 3 4 5 6 7 8 9 10 |
version: 0.0 Resources: - TargetService: Type: AWS::ECS::Service Properties: TaskDefinition: <TASK_DEFINITION> LoadBalancerInfo: ContainerName: "sample-website" ContainerPort: 80 |
1 2 3 4 |
$ git add . $ git commit -m "Added task definition files" $ git push |
プッシュされました。
Application Load Balancerとターゲットグループの作成
リスナー 8080ポートを追加しました。
デフォルトVPCに作成しました。
セキュリティグループは新規作成で80と8080を許可しました。
ターゲットグループはIPアドレスをターゲットにしました。
ALBを作成しました。
作成後、デフォルトVPCを選択してもう1つターゲットグループを作成しました。
IPアドレスをターゲットにポートは8080にしました。
追加で作成したターゲットグループをALBのリスナー8080に設定しました。
ECSクラスターとサービスを作成する
クラスターはFargateで作成しました。
create-service.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
{ "taskDefinition": "ecs-demo:1", "cluster": "Demo", "loadBalancers": [ { "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/EcsTargetGroup1/c74a49794939716d", "containerName": "sample-website", "containerPort": 80 } ], "desiredCount": 1, "launchType": "FARGATE", "schedulingStrategy": "REPLICA", "deploymentController": { "type": "CODE_DEPLOY" }, "networkConfiguration": { "awsvpcConfiguration": { "subnets": [ "subnet-98085fc7", "subnet-e6004a80" ], "securityGroups": [ "sg-0631b5c45331d63b1" ], "assignPublicIp": "ENABLED" } } } |
サービスをCLIで作成するためのJsonファイルを作成しました。
- taskDefinition
- cluster
- targetGroupArn
- subnets
- securityGroups
上記はそれぞれの環境で変更する必要があります。
1 2 |
$ aws ecs create-service --service-name my-service --cli-input-json file://create-service.json |
サービスを作成しました。
サービスの作成ができました。
この時点でALBのDNSにアクセスすると、『Welcome to nginx!』と表示されて、ひとまずのデプロイができている状態です。
ここからパイプラインを構築していきます。
CodeDeployアプリケーションとデプロイグループを作成
プラットフォームでECSを選択してアプリケーションを作成しました。
IAMロールはCodeDeployECSRole、ECSクラスター、サービス、ALB、リスナー、ターゲットグループをそれぞれ選択しました。
「すぐにトラフィックを再ルーティング」を選択して、[元のリビジョンの終了]の時間を5分にしました。
これはブルーグリーンデプロイでデプロイの時間を短縮するためです。
[デプロイグループの作成]ボタンを押下しました。
パイプラインを作成
サービスロールは新しいIAMロールを作成しました。
ソースステージはCodeCommitリポジトリを選択しました。
ビルドステージはスキップしました。
アクションプロバイダーはAmazon ECS(ブルー/グリーン)を選択しました。
CodeDeployのアプリケーションとデプロイグループを選択しました。
ECSタスク定義とAppSpecファイルを指定しました。
保存時にパイプラインが実行されて、デプロイがエラーになって、「無効なアクション設定Container.image contains invalid characters.」と表示されますが、まだ設定は完了していないので大丈夫です。
パイプラインにECRソースを追加
CodePipelineを編集して、ソースステージを編集して、CodeCommitの右で[アクションの追加]を選択しました。
アクションプロバイダーにECRを選択して、リポジトリとタグを指定しました。
出力アーティファクトはMyImageにしました。
CloudWatchのイベントが作成されました。
デプロイステージの編集からデプロイアクションを編集して、入力アーティファクトにMyImageを追加しました。
そして下までスクロールして、入力アーティファクトでMyImageを選択、プレースホルダー文字にIMAGE1_NAMEを入力しました。
これで保存して、[変更をリリースする]ボタンを押下しました。
コンテナを変更してプッシュ
コンテナを変更してdocker pushしました。
パイプラインが起動しました。
デプロイが進行しています。
デプロイが完了しました。
最後までお読みいただきましてありがとうございました!
「AWS認定資格試験テキスト&問題集 AWS認定ソリューションアーキテクト - プロフェッショナル 改訂第2版」という本を書きました。
「AWS認定資格試験テキスト AWS認定クラウドプラクティショナー 改訂第3版」という本を書きました。
「ポケットスタディ AWS認定 デベロッパーアソシエイト [DVA-C02対応] 」という本を書きました。
「要点整理から攻略するAWS認定ソリューションアーキテクト-アソシエイト」という本を書きました。
「AWSではじめるLinux入門ガイド」という本を書きました。
開発ベンダー5年、ユーザ企業システム部門通算9年、ITインストラクター5年目でプロトタイプビルダーもやりだしたSoftware Engineerです。
質問はコメントかSNSなどからお気軽にどうぞ。
出来る限りなるべく答えます。
このブログの内容/発言の一切は個人の見解であり、所属する組織とは関係ありません。
このブログは経験したことなどの共有を目的としており、手順や結果などを保証するものではありません。
ご参考にされる際は、読者様自身のご判断にてご対応をお願いいたします。
また、勉強会やイベントのレポートは自分が気になったことをメモしたり、聞いて思ったことを書いていますので、登壇者の意見や発表内容ではありません。
ad
ad
関連記事
-
API Gateway Lambdaプロキシ統合で渡されるリクエストを確認しました
API Gatewayの統合リクエストでLambdaを指定するときにプロキシ統合 …
-
Cloud9環境を共有した際の環境認証
Cloud9を環境を構築したIAMユーザー以外に共有したとき、その環境から実行す …
-
AWS APIリクエストにPostmanで署名を作成する
新年明けましておめでとうございます! 署名バージョン4 「AWSはマネジメントコ …
-
Apple Silicon M1 MacBook ProにAWS CLI v2をインストール
公式手順どおりにインストールしました。 macOS での AWS CLI バージ …
-
AWSルートユーザーのパスワード復旧
AWSルートユーザーのパスワード最設定は、メールアドレスだけでいいのですね。 M …
-
Developers Summit 2018 「AWSのフルマネージドな環境でCI/CDをやってみよう!AWS Cloud9からAWS Fargateへの継続的デプロイをご紹介」を聞きました
※写真は展示のAmazon Echoです。 以下は、思ったことや気になったことを …
-
Rocket.ChatからOut Going Webhookを設定してみる
API GatewayとLambda とりあえず、どんなデータが飛んでくるのか見 …
-
macOSにAWS Schema Conversion Toolをインストール
環境 macOS BigSur バージョン11.5(20G71) MacBook …
-
Organizations組織でAWS SSOを有効にする
先日AWS Control Towerで環境を作ったら、自動でAWS SSOがで …
-
TuneCoreの売上データCSVをS3に格納してAthenaのクエリをRe:dashのデータソースにして可視化する
先日参加しましたAWS Summit Tokyo 2017で、 [JapanTa …