2021〜2022年はAWS Copilot CLIにたくさん助けてもらった年でした

この記事は シーエー・アドバンス Advent Calendar 2022 10日目の記事です。

# TL;DR
### :one: :link: 担当サービスの運用がシンプル化し、運用コスト削減 :arrow_down_small: 
:white_check_mark: システム運用者にとってやりたくないタスクにも感じるセキュリティアップデートなどが発生してもすぐ対応できた :sweat_drops: :dash: 
### :two: :link: 別サービスへも開発フローに導入したら、 **ChatOps to GitOps** 化できた :tada: :tada: :tada: 
:white_check_mark: 長年利用してた **Hubot** さんが不要になり開発フローもシンプルに :heart_decoration: 
### :three: :link: 利用事例にも掲載 :newspaper: :tada: :tada: :tada: 
:white_check_mark: 公式サイトなどの利用事例に掲載してもらえたというのが初めてで、テンション爆アゲ(´∀｀∩)↑age↑

# AWS Copilot CLIとは
サイトはこちら👇
使い方などは他の記事や下記のサイトへ譲ります :bow:
[AWS Copilot CLI](https://aws.github.io/copilot-cli/ja/)

👇はサイトの説明からの引用です。

>Copilot CLI は、AWS App Runner、Amazon ECS on AWS Fargate を利用したプロダクションレディなコンテナ化されたアプリケーションのビルド、リリース、そして運用のためのツールです。 
開発のスタートからステージング環境へのプッシュ、そして本番環境へのリリースまで、Copilot はアプリケーション開発ライフサイクル全体の管理を容易にします。

# 具体的にお世話になったところ
## :one: :link: 担当サービスの運用がシンプル化し、運用コスト削減 :arrow_down_small:

:three: の利用事例の掲載にも詳細はありますが、ウェブサイトの立ち上げ(リリース)という作業において、
サーバ上での細かな設定をSSHして、NGINX と Apacheのconfigを修正して、他のサイトへの影響がないように間違えてないか確認して、サービスリロードなどといったリリースフローを踏まずとも、
**AWS Copilot CLI** さえ使えれば、リモートでも会社でも作業ができ、それぞれのサイトを別のサービスとしてデプロイすることで該当の作業が他の環境に大きな影響を与えない対応ができ、いつでも必要なときにコンテナ台数を増やしてスケールすることができる状態にすることができました👍

これにより、下記の作業負荷や心理的負荷が取り除かれ、安心して作業ができるようになり、
そのシンプルさ故に別の担当者へも引き継ぎのしやすい環境を生み出すことに成功しました :tada: :tada: :tada: 

- :white_check_mark: 該当サーバにSSHできる環境にいないといけないという条件がなくなった
- :white_check_mark: サイトの追加設定作業において別環境へ影響を与えないため、安心して作業ができる
- :white_check_mark: **Fargate Spot** も利用したコスト効率も高く、必要なときにスケール可能なため負荷上昇への耐久性アップができた

※Fargate Spotがわからない方は下記のクラスメソッド様のブログをご参照ください :bow:
[Fargateをスポットで7割引で使うFargate Spotとは？ #reinvent | DevelopersIO](https://dev.classmethod.jp/articles/fargate-spot-detail/)

>セキュリティアップデートなどが発生してもすぐ対応できた

こちらについては、詳細なお話はできませんが、[**Apache HTTP Server 2.4の脆弱性**](https://httpd.apache.org/security/vulnerabilities_24.html)は年に数回の頻度で
脆弱性が確認されており、これらへのアップデートについてもなるべく確認されたあとすぐに新しいDockerイメージを利用するなどして、
すぐに最新版へアップデートすることができます。

```bash:Dockerfile
👇Dockerfileのここ変えて再ビルドとデプロイするだけ👍
FROM php:8.0.19-apache
```

#### もうこれがとっても便利 :heart_decoration:

## :two: :link: 別サービスへも開発フローに導入したら、 **ChatOps to GitOps** 化できた :tada: :tada: :tada:
あるシステムにて、開発フローで **Hubot**を利用した **ChatOps** による開発環境の作成などに利用してる状況で、
レビューをしてもらう際に開発環境の作成や該当ブランチのソースのデプロイなど、SlackやGithub、AWSコンソールなど複数の画面やSlackチャンネルをまたいだ作業をする必要のあった作業を **AWS Copilot CLI**を利用した**Github Actions** 化をすることにより、特定のメッセージでコミットをプッシュするだけとシンプルになりました👍

AWS Copilot CLIのGithubリポジトリでも開発者と対話し、どうにかこうにかGitOpｓ化したワークフローが[こちら](https://github.com/aws/copilot-cli/issues/3474#issuecomment-1108338977)です👇
複数のサービスの一括デプロイコマンドがまだないというところから始まって自分で作りました。
サンプルでしかないことと、実際に利用するとGithub Actionsの実行時間を使いすぎがちですので、
利用する場合は用法、用量を守って(会社の利用方針にもならって)正しくお使いください :bow: 

```
      - 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}
```

#### もうこれもまたとっても便利 :heart_decoration: :heart_decoration:

## :three: :link: 利用事例にも掲載 :newspaper: :tada: :tada: :tada:
[AWS 導入事例：株式会社シーエー・アドバンス | AWS](https://aws.amazon.com/jp/solutions/case-studies/ca-advance/)

個人的にもとても嬉しかったので、自分の各SNSアカウントでも公開させていただきました :bow: :bow: :bow: 
現在も各所へポジティブな影響を与えてくださっています :bow_tone1: 
**AWS** さんはじめご提案いただいた @toricls さん 本当にありがとうございます❗ :bow: 

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">会社のHPでも発表していますが、AWS Copilot CLIの利用事例として掲載していただきました❗️🙌こんなこと初めてですが、大変嬉しいです🙌ありがとうございました🙇‍♂️😊<a href="https://t.co/GAW66jKz8N">https://t.co/GAW66jKz8N</a><a href="https://twitter.com/hashtag/aws?src=hash&amp;ref_src=twsrc%5Etfw">#aws</a><a href="https://twitter.com/hashtag/caadvance?src=hash&amp;ref_src=twsrc%5Etfw">#caadvance</a> <a href="https://twitter.com/hashtag/web%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2?src=hash&amp;ref_src=twsrc%5Etfw">#webエンジニア</a><a href="https://twitter.com/hashtag/copilot?src=hash&amp;ref_src=twsrc%5Etfw">#copilot</a><a href="https://twitter.com/hashtag/%E5%88%A9%E7%94%A8%E4%BA%8B%E4%BE%8B?src=hash&amp;ref_src=twsrc%5Etfw">#利用事例</a> <a href="https://t.co/27I44Y7FD9">https://t.co/27I44Y7FD9</a> <a href="https://t.co/GB38d8980K">pic.twitter.com/GB38d8980K</a></p>&mdash; 高良家@CA ADvance, Inc 沖縄🏖WEBエンジニア❤️BBQ🍖 (@takarake) <a href="https://twitter.com/takarake/status/1540592449537572864?ref_src=twsrc%5Etfw">June 25, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#### これがまた本当にハッピー :heart_decoration: :heart_decoration: :heart_decoration:

# 振り返り
- ecs-cli v1しかないときは本当に運用どうするか困ってたので、v2である **AWS Copilot CLI**には本当に助けられました :smile: :cracker:
- OSSへ開発要望(Issue)を作成し、英語で頑張ってコミニケーションし、実際に改善されるなど、面白い体験もできました
- AWSのエンジニアの方とお話ができたり、アドバイスもいただいて自分のDevOps(DevSecOpsでもある❓)スキルもついた気がします
- この体験により、その前よりもさらにAWSが大好きになりました(だから:heart_decoration:も増えてますｗ)
- 現在はさらに、バッチ処理もCopilot Jobsに変えてくことができそうなので、バッチ処理も移設していきます :muscle: 

AWSさん、AWS Copilot CLIさん、これからも末永くどうぞよろしくお願いいたします :bow::bow::bow: