この記事は シーエー・アドバンス Advent Calendar 2022 10日目の記事です。
TL;DR
担当サービスの運用がシンプル化し、運用コスト削減
システム運用者にとってやりたくないタスクにも感じるセキュリティアップデートなどが発生してもすぐ対応できた
別サービスへも開発フローに導入したら、 ChatOps to GitOps 化できた
長年利用してた Hubot さんが不要になり開発フローもシンプルに
利用事例にも掲載
公式サイトなどの利用事例に掲載してもらえたというのが初めてで、テンション爆アゲ(´∀`∩)↑age↑
AWS Copilot CLIとは
サイトはこちら👇
使い方などは他の記事や下記のサイトへ譲ります
AWS Copilot CLI
👇はサイトの説明からの引用です。
Copilot CLI は、AWS App Runner、Amazon ECS on AWS Fargate を利用したプロダクションレディなコンテナ化されたアプリケーションのビルド、リリース、そして運用のためのツールです。
開発のスタートからステージング環境へのプッシュ、そして本番環境へのリリースまで、Copilot はアプリケーション開発ライフサイクル全体の管理を容易にします。
具体的にお世話になったところ
担当サービスの運用がシンプル化し、運用コスト削減
の利用事例の掲載にも詳細はありますが、ウェブサイトの立ち上げ(リリース)という作業において、
サーバ上での細かな設定をSSHして、NGINX と Apacheのconfigを修正して、他のサイトへの影響がないように間違えてないか確認して、サービスリロードなどといったリリースフローを踏まずとも、
AWS Copilot CLI さえ使えれば、リモートでも会社でも作業ができ、それぞれのサイトを別のサービスとしてデプロイすることで該当の作業が他の環境に大きな影響を与えない対応ができ、いつでも必要なときにコンテナ台数を増やしてスケールすることができる状態にすることができました👍
これにより、下記の作業負荷や心理的負荷が取り除かれ、安心して作業ができるようになり、
そのシンプルさ故に別の担当者へも引き継ぎのしやすい環境を生み出すことに成功しました
- 該当サーバにSSHできる環境にいないといけないという条件がなくなった
- サイトの追加設定作業において別環境へ影響を与えないため、安心して作業ができる
- Fargate Spot も利用したコスト効率も高く、必要なときにスケール可能なため負荷上昇への耐久性アップができた
※Fargate Spotがわからない方は下記のクラスメソッド様のブログをご参照ください
Fargateをスポットで7割引で使うFargate Spotとは? #reinvent | DevelopersIO
セキュリティアップデートなどが発生してもすぐ対応できた
こちらについては、詳細なお話はできませんが、Apache HTTP Server 2.4の脆弱性は年に数回の頻度で
脆弱性が確認されており、これらへのアップデートについてもなるべく確認されたあとすぐに新しいDockerイメージを利用するなどして、
すぐに最新版へアップデートすることができます。
👇Dockerfileのここ変えて再ビルドとデプロイするだけ👍
FROM php:8.0.19-apache
もうこれがとっても便利
別サービスへも開発フローに導入したら、 ChatOps to GitOps 化できた
あるシステムにて、開発フローで Hubotを利用した ChatOps による開発環境の作成などに利用してる状況で、
レビューをしてもらう際に開発環境の作成や該当ブランチのソースのデプロイなど、SlackやGithub、AWSコンソールなど複数の画面やSlackチャンネルをまたいだ作業をする必要のあった作業を AWS Copilot CLIを利用したGithub Actions 化をすることにより、特定のメッセージでコミットをプッシュするだけとシンプルになりました👍
AWS Copilot CLIのGithubリポジトリでも開発者と対話し、どうにかこうにかGitOps化したワークフローがこちらです👇
複数のサービスの一括デプロイコマンドがまだないというところから始まって自分で作りました。
サンプルでしかないことと、実際に利用するとGithub Actionsの実行時間を使いすぎがちですので、
利用する場合は用法、用量を守って(会社の利用方針にもならって)正しくお使いください
- name: Delete your Copilot Application
if: "contains(github.event.head_commit.message, '[close copilot]')"
continue-on-error: true
run: |
echo "copilot version check 👀"
copilot --version
echo "👋👋👋 Delete copilot your app 💪"
copilot app delete -n app-${BRANCH_NAME} --yes # 困ったらこれ使って一度削除
- name: check copilot version and app init
if: "contains(github.event.head_commit.message, '[start copilot]')"
id: check_copilot_app_exist
run: |
echo "copilot version check 👀"
copilot --version
echo "copilot make your app 💪"
copilot app init app-${BRANCH_NAME} --domain example.com
- name: check copilot env exist
if: "contains(github.event.head_commit.message, '[start copilot]')"
id: check_env_exist
continue-on-error: true
run: |
echo "Show Target Env for copilot 👀"
copilot env show -a app-${BRANCH_NAME} --name ${BRANCH_NAME}
- name: when NOT exist copilot target env
if: ${{ steps.check_env_exist.outcome == 'failure' && contains(github.event.head_commit.message, '[start copilot]') }}
run: |
echo "not exist copilot target env"
# VPC import
copilot env init -a app-${BRANCH_NAME} --name ${BRANCH_NAME} --profile XXXXXX \
--import-vpc-id vpc-XXXXXXX \
--import-public-subnets subnet-XXXXXX,subnet-XXXXXXX \
--import-private-subnets subnet-XXXXXXX,subnet-XXXXXX
# <Backend Serviceからデプロイ>
# <mysql-svc>
- name: check MySQL service exist
if: "contains(github.event.head_commit.message, '[start copilot]')"
id: check_mysql_svc_exist
continue-on-error: true
run: |
copilot svc show -a app-${BRANCH_NAME} --name mysql-svc
# service initが未完ならやる
- name: when NOT exist copilot MySQL service
if: ${{ steps.check_mysql_svc_exist.outcome == 'failure' && contains(github.event.head_commit.message, '[start copilot]') }}
run: |
echo "not exist copilot MySQL service"
echo "Init Service for MySQL"
copilot svc init -a app-${BRANCH_NAME} --name mysql-svc
# <redis-svc>
- name: check redis service exist
if: "contains(github.event.head_commit.message, '[start copilot]')"
id: check_redis_svc_exist
continue-on-error: true
run: |
copilot svc show -a app-${BRANCH_NAME} --name redis-svc
# service init未完ならやる
- name: when NOT exist copilot redis service
if: ${{ steps.check_redis_svc_exist.outcome == 'failure' && contains(github.event.head_commit.message, '[start copilot]') }}
run: |
echo "not exist copilot redis service"
echo "Init Service for redis"
copilot svc init -a app-${BRANCH_NAME} --name redis-svc
# <web-svc>
- name: check web service exist
if: "contains(github.event.head_commit.message, '[start copilot]')"
id: check_web_svc_exist
continue-on-error: true
run: |
copilot svc show -a app-${BRANCH_NAME} --name web-svc
# service init未完ならやる
- name: when NOT exist copilot web service
if: ${{ steps.check_web_svc_exist.outcome == 'failure' && contains(github.event.head_commit.message, '[start copilot]') }}
run: |
echo "not exist copilot web service"
echo "Init Service for web"
copilot svc init -a app-${BRANCH_NAME} --name web-svc
# all svc deploy
- name: deploy all service
if: "contains(github.event.head_commit.message, '[start copilot]')"
run: |
copilot svc deploy -a app-${BRANCH_NAME} --name mysql-svc --env ${BRANCH_NAME}
copilot svc deploy -a app-${BRANCH_NAME} --name redis-svc --env ${BRANCH_NAME}
copilot svc deploy -a app-${BRANCH_NAME} --name web-svc --env ${BRANCH_NAME}
もうこれもまたとっても便利
利用事例にも掲載
個人的にもとても嬉しかったので、自分の各SNSアカウントでも公開させていただきました
現在も各所へポジティブな影響を与えてくださっています
AWS さんはじめご提案いただいた @toricls さん 本当にありがとうございます❗
会社のHPでも発表していますが、AWS Copilot CLIの利用事例として掲載していただきました❗️🙌こんなこと初めてですが、大変嬉しいです🙌ありがとうございました🙇♂️😊https://t.co/GAW66jKz8N#aws#caadvance #webエンジニア#copilot#利用事例 https://t.co/27I44Y7FD9 pic.twitter.com/GB38d8980K
— 高良家@CA ADvance, Inc 沖縄🏖WEBエンジニア❤️BBQ🍖 (@takarake) June 25, 2022
これがまた本当にハッピー
振り返り
- ecs-cli v1しかないときは本当に運用どうするか困ってたので、v2である AWS Copilot CLIには本当に助けられました
- OSSへ開発要望(Issue)を作成し、英語で頑張ってコミニケーションし、実際に改善されるなど、面白い体験もできました
- AWSのエンジニアの方とお話ができたり、アドバイスもいただいて自分のDevOps(DevSecOpsでもある❓)スキルもついた気がします
- この体験により、その前よりもさらにAWSが大好きになりました(だからも増えてますw)
- 現在はさらに、バッチ処理もCopilot Jobsに変えてくことができそうなので、バッチ処理も移設していきます
AWSさん、AWS Copilot CLIさん、これからも末永くどうぞよろしくお願いいたします