【CI/CD】 Git Codedeploy 連携まとめ


#参考文献

- [CircleCI 2.0とcodedeployでデプロイを自動化する](https://dev.classmethod.jp/articles/deploy-with-codedeploy-circleci2-0/)
- [CircleCIとAWS（CodeDeploy/S3）で作るCI環境](https://qiita.com/hardreggaecafe/items/7ff3ada575a1100fa4a2)
- [CodeDeployでGitHubのソースをEC2にデプロイするまとめ](https://qiita.com/saka-shin/items/b388f9c2d62a1ffadb8c)
- [CodeDeployとCircleCIを利用したBlue/Greenデプロイメント](https://dev.classmethod.jp/articles/bg-deploy-with-codedeploy-and-circleci/)
- [AWS CodeDeploy の AppSpec を読み解く](https://dev.classmethod.jp/articles/code-deploy-appspec/)
- [ステップ 2: サンプルのアプリケーションリビジョンを作成する](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorials-on-premises-instance-2-create-sample-revision.html)


#code-deploy-agentのインストール

```
$ sudo yum update
$ sudo yum install ruby
$ sudo yum install wget
$ cd /home/ec2-user
$ wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
$ sudo service codedeploy-agent start
```

#circle.ymlの記述

#####下記参照▼
[CodeDeployとCircleCIを利用したBlue/Greenデプロイメント](https://dev.classmethod.jp/articles/bg-deploy-with-codedeploy-and-circleci/)

```circle.yml
deployment:
  blue:
    branch: release/blue
    codedeploy:
      bg-deploy-app: 　　　　　   #CodeDeploy作成時のアプリケーション名
        application_root: /app  #appspec.ymlのパス
        revision_location:      
          revision_type: S3　　　#リビジョンの保管場所（S3）
          s3_location:
            bucket: bg-deploy-app
            key_pattern: apps/{SHORT_COMMIT}  #S3バケットのキー名指定
        region: ap-northeast-1
        deployment_group: Blue　　　　　　　　　　   #デプロイメントグループ名
        deployment_config: CodeDeployDefault.AllAtOnce
  green:
    branch: release/green
    codedeploy:
      bg-deploy-app:
        application_root: /app
        revision_location:
          revision_type: S3
          s3_location:
            bucket: bg-deploy-app
            key_pattern: apps/{SHORT_COMMIT}
        region: ap-northeast-1
        deployment_group: Green
        deployment_config: CodeDeployDefault.AllAtOnce
```

#appspec.ymlの記述

#####下記参照▼
[CircleCIとAWS（CodeDeploy/S3）で作るCI環境](https://qiita.com/hardreggaecafe/items/7ff3ada575a1100fa4a2)

```appspec.yml
version: 0.0
os: linux # このあたりはお約束なのでそのまま記述すること

files: 
# You can specify one or more mappings in the files section.
  - source: /
    destination: /home/ec2-user # 他が良ければ事前にユーザ名、ディレクトリは作成すること
hooks:
  BeforeInstall:
    - location: Scripts/BeforeInstall.sh      #下記デプロイ用シェル参照
  AfterInstall:
    - location: Scripts/AfterInstall.sh　 　   #下記デプロイ用シェル参照
      timeout: 60
  ApplicationStart:
    - location: Scripts/ApplicationStart.sh　  #下記デプロイ用シェル参照
      timeout: 60
  ValidateService:
    - location: Scripts/ValidateService.sh　   #下記デプロイ用シェル参照
      timeout: 60 
```

#デプロイ用シェルの作成　
#####下記参照▼
[ステップ 2: サンプルのアプリケーションリビジョンを作成する](https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/tutorials-on-premises-instance-2-create-sample-revision.html)

###BeforeInstall.sh

```Scripts/BeforeInstall.sh
#!/bin/bash
export FOLDER=/tmp/CodeDeployExample

if [ -d $FOLDER ]
then
 rm -rf $FOLDER
fi

mkdir -p $FOLDER
```

###AfterInstall.sh

```Scripts/AfterInstall.sh
#!/bin/bash
cd /tmp/CodeDeployExample

echo "The AfterInstall deployment lifecycle event successfully completed." > after-install.txt
```

###ApplicationStart.sh

```
#!/bin/bash
cd /tmp/CodeDeployExample

echo "The ApplicationStart deployment lifecycle event successfully completed." > application-start.txt
```

###ValidateService.sh

```
#!/bin/bash
cd /tmp/CodeDeployExample

echo "The ValidateService deployment lifecycle event successfully completed." > validate-service.txt

unset FOLDER
```

###実行権限付与
```
$ chmod +x ./Scripts/*
```


#CircleCI CodeDeployの連携
#####下記参照▼
[CircleCI 2.0とcodedeployでデプロイを自動化する](https://dev.classmethod.jp/articles/deploy-with-codedeploy-circleci2-0/)

```.circleci/config.yml
version: 2
jobs:
  build: #単体テストを実行するジョブ
    working_directory: ~/my-app
    docker:
      - image: ruby:2.4.0
    steps:
      - checkout
      - run: bundle install --path vendor/bundle
      - run:
          name: Run Test
          command: bundle exec rspec
  deploy: #デプロイするジョブ
    working_directory: ~/my-app
    docker:
    - image: ruby:2.4.0
    steps:
      - checkout
      - run: bundle install --path vendor/bundle
      - run: bundle exec rake deploy
workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy: # deployはbuildのあとに実行
          requires:
            - build
          filters: # developブランチの場合のみデプロイする
            branches:
              only: develop
```

```:Rakefile
# frozen_string_literal: true

require 'aws-sdk-codedeploy'
require 'aws-sdk-s3'

# Configs for codedeploy
APP_NAME = 'app_name'
S3_BUCKET = 'mybucket'
S3_PREFIX = 'app/versions/'
TAG = `git describe --tags`.strip
DEPLOY_GROUP_NAME = 'deploy_group_name'

desc "Deploy with codedeploy"
task :deploy do
  # upload files to s3
  zip_file = "#{APP_NAME}_#{TAG}.zip"
  s3_key = S3_PREFIX + '/' + zip_file
  `git archive HEAD --output=#{zip_file}`
  begin
    Aws::S3::Client.new.put_object(bucket: S3_BUCKET, key: s3_key, body: File.open(File.basename(zip_file)))
  ensure
    File.delete(zip_file)
  end
  # register revision
  revision = {
    revision_type: 'S3',
    s3_location: {
      bucket: S3_BUCKET,
      key: s3_key,
      bundle_type: 'zip',
    },
  }
  codedeploy = Aws::CodeDeploy::Client.new
  codedeploy.register_application_revision(application_name: APP_NAME, revision: revision)
  # deploy
  codedeploy.create_deployment(application_name: APP_NAME,
                               deployment_group_name: DEPLOY_GROUP_NAME,
                               revision: revision,
                               file_exists_behavior: 'OVERWRITE')
end
```