Bitbucket Pipelines使ってSpringBootのDeployをやってみた。

まータイトルで内容は終わりなんだけど。SpringBootは実際には全然関係ない。

# 構成

![MR_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115285/fca51ce8-9eb4-408b-2271-588203fde5b9.png)
こんなの。
# 料金プラン的な話
https://support.atlassian.com/bitbucket-cloud/docs/manage-your-plan-and-billing/#BitbucketCloudplandetails-Frequentlyaskedquestions
Freeプランだと50min/月なので、ちょっと使いにくいかもねー。
# Bitbucket Pipelines
いやー初めて使ったけど、意外とテンプレート充実してる。
ただ、一つの`bitbucket-pipelines.yml`に全部書かなきゃならないんだよな。
今回は珍しくmaven使ったので、こんな感じ。
artifactのVersionが完全に直値なので、実際の運用はこれじゃダメだね。

```bitbucket-pipelines.yml
#  Template maven-build

#  This template allows you to test and build your Java project with Maven.
#  The workflow allows running tests, code checkstyle and security scans on the default branch.

# Prerequisites: pom.xml and appropriate project structure should exist in the repository.

image: maven:3.6.3-amazoncorretto-11

pipelines:
  default:
    - parallel:
      - step:
          name: Build and Test
          caches:
            - maven
          script:
            - mvn -B verify --file pom.xml
            - yum -y install zip
            - zip -j sample.zip ./target/sample-0.0.1-SNAPSHOT.jar ./script/stop.sh ./script/start.sh ./appspec.yml
          artifacts:
            - sample.zip
          after-script:
              # Collect checkstyle results, if any, and convert to Bitbucket Code Insights.
            - pipe: atlassian/checkstyle-report:0.2.0
      - step:
          name: Security Scan
          script:
            # Run a security scan for sensitive data.
            # See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
            - pipe: atlassian/git-secrets-scan:0.4.3
    - step:
        name: deploy
        deployment: test
        trigger: manual
        script:
          - pipe: atlassian/aws-code-deploy:0.5.4
            variables:
              AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
              AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
              AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
              COMMAND: 'upload'
              APPLICATION_NAME: 'deploy-app'
              S3_BUCKET: 'sample-artifact'
              ZIP_FILE: 'sample.zip'
          - pipe: atlassian/aws-code-deploy:0.5.4
            variables:
              AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
              AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
              AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
              DEPLOYMENT_GROUP: 'deploy-group'
              S3_BUCKET: 'sample-artifact'
              COMMAND: 'deploy'
              APPLICATION_NAME: 'deploy-app'
              WAIT: 'false'
              IGNORE_APPLICATION_STOP_FAILURES: 'true'
              FILE_EXISTS_BEHAVIOR: 'OVERWRITE'
```
当然だけど、appspec.ymlも必要。
ま、でも今回は、EC2のインプレースデプロイなので、大したことやってない。stopはkillしてるだけだし、startもjavaコマンドを叩いているだけ。
EC2の再構築とかも全然やってないから簡単。

```appspec.yml
version: 0.0
os: linux
files:
  - source: ./sample-0.0.1-SNAPSHOT.jar
    destination: /var/app
hooks:
  ApplicationStop:
    - location: ./stop.sh
  ApplicationStart:
    - location: ./start.sh
```
## 補足
### Bitbucket側
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY

最低限この二つはBitbucketの環境変数として登録する必要がある。なので、事前にAWS側で払い出し。

### AWS(EC2)
#### CodeDeployAgentのインストール

今回はAL2だったので、この辺。
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html

#### IAMロールにS3ReadOnlyAccessの追加

### AWS(CodeDeploy)
省略…、ってしちゃっていいのかな。CodeDeployのIAMRoleはEC2をDeployできる権限はそれは必要。
### AWS(S3)
これも当然だけど、artifact用S3は事前に作っておく必要がある。

# 解説
## deploy
S3 Upload→deployのところがいまいちわからなかったんだけど、pipelineのuploadの最後にこういうログが出てるんだよね。

```
aws deploy register-application-revision --application-name deploy-app --revision revisionType=S3,s3Location={bucket=sample-artifact,key=deploy-app-22-d54df194,bundleType=zip}
```
なので、リビジョンの登録をしてるっぽい。
https://docs.aws.amazon.com/ja_jp/codedeploy/latest/userguide/application-revisions-register.html
この後は↓のような流れですね。なるほどー。

```
aws deploy get-application-revision 
aws deploy create-deployment 
```

ただ、bitbucket側はDeployの指令出したところで終わっちゃうので、後はCodeDeploy側のログを見なければならない。でもCodeDeployのログ見てもよくわかんないから、結局EC2側のログ見る必要があった…。
## CodeDeploy
Bitbucketとは全く関係ないんだけど、CodeDeploy側のInstallが全然終わらないことに悩んだ。
https://su-kun1899.hatenablog.com/entry/2018/05/09/210000
結論はこれと一緒で、start.shの書き方を修正した。↓のBackground起動では駄目で、

```
nohup java -jar /var/app/sample-0.0.1-SNAPSHOT.jar &
```

こんな風にする必要がある。

```
java -jar "/var/app/sample-0.0.1-SNAPSHOT.jar" \
    >> "/var/log/sample.log" \
    2>&1 &
```

# bitbucket-pipelinesのいいところ
そんなに使い込んでいるわけじゃないけど…。
## pipeline内image変更
pipelineの途中でimageを変更できるのは便利かも。
https://www.it-swarm-ja.tech/ja/bitbucket-pipelines/bitbucket%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A7%E8%A4%87%E6%95%B0%E3%81%AEdocker%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F/827893157/
要するにこれだけど。

````bitbucket-pipelines.yml
pipelines:
  default:
    - step:
        name: Build and test
        image: node:8.6
        script:
          - npm install
          - npm test
          - npm run build
        artifacts:
          - dist/**
    - step:
        name: Deploy
        image: python:3.5.1
        trigger: manual
        script:
          - python deploy.py
```
知らなかったけど、docker hubとかも使えるんだね。
https://ja.confluence.atlassian.com/bitbucket/use-docker-images-as-build-environments-792298897.html
## 初心者向け
用意されているテンプレートをそのまま使うだけで、とりあえずCIは出来る。本当に5分で出来た。これは取っ掛かりとしてはいいんじゃないかなー。
# bitbucket-pipelinesのいまいちなところ
## (多分)モジュール化が出来ない。
Jenkinsとかだとデフォルトは1,2の処理は動いて、3の処理はmaster branchだけ、ってよくやってるんだけど、出来ると思ったら、なんか出来ないっぽい。
https://support.atlassian.com/bitbucket-cloud/docs/configure-bitbucket-pipelinesyml/
結局、こんな感じで書かなきゃならないんだよな。モジュール化とかあるのかな？そこまで調べてないんだけど、なさそうな気が。

```bitbucket-pipelines.yml
pipelines:
  default:
    - step:
      name: Build and Test
    - step:
      name: Deploy
  branches:
    master:
      - step:
        name: Build and Test
      - step:
        name: Deploy
```
## 無料プランだと50分
しょうがないんだけど、ymlの変更って、ローカルの動作はあんまり意味なくて、pipelineを動作させないとわからず、それだけで殆ど終わってしまうという…。