WebサイトをBitbucket pipelinesでS3に環境に自動公開するようにしたまとめ

CI環境は昨今色々ありますがせっかくbitbucketを使っているので（安いし）、そのまま追加料金なしで利用できるbitbucketのpipelinesを使って小規模プロジェクトは済ませたいということで、AWSのデプロイの仕組みばかりいじってましたがpipelinesを使ってチェックポイントをまとめてみました。

# Bitbucket Pipelinesとは

bitbucketを使っていると無料で使えるCIツールです。dockerを使ってデプロイする仕組みのようで、デプロイだけでなく自分でDockerイメージも作ってしまえば色々なことができそうです。無料利用アカウントだと月に50minまで、スタンダードで500minまで利用できるようです。

# 静的サイトをS3にあげるまでのまとめ

## 実現したいこと

- git管理しているWebサイトのソースコードを自動的にS3でWeb公開してアップしたい
- masterブランチを自動的にstagingのバケットに転送したい
- tag:release-[YYYYmmddHH]なタグをつけたら自動的にproductionに本番化したい

## チェックポイントまとめ

1. [AWS] S3に公開用のバケツを作る
2. [AWS] IAMで公開用のバケツに権限があるポリシーを作る
3. [AWS] IAMで上記ポリシーを振り分けたユーザーを作る
4. [Bitbucket] 対象のリポジトリのPipelinesをオンにする
5. [Bitbucket] S3に環境ごとに転送するbitbucket-pipelines.ymlを作る
6. [Bitbucket] 環境変数を設定する

## 1. [AWS] S3に公開用のバケツを作る

作成の注意点は２点

- [アクセス許可の設定]の時に[パブリックアクセスを全てブロック]のチェックを外す
- 作成後に設定変更でStatic Web Hostingを有効にする

この画面からです
<img width="1076" alt="スクリーンショット 2019-12-17 19.15.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/d05ddc13-6c4d-7f94-b8fd-4d75f75c4476.png">

作成後に一覧に表示されるバケツ名をクリックしてStatic Web Hostingを有効にします。

<img width="997" alt="スクリーンショット 2019-12-17 19.18.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/722c5f7f-e3f5-1cb8-9b87-67c268593b7c.png">

<img width="561" alt="スクリーンショット 2019-12-17 19.18.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/2619a259-297b-dc3c-a7ab-dd1d3c00d44c.png">

## 2. [AWS] IAMで公開用のバケツに権限があるポリシーを作る

1. 最初にIAMにアクセスして[ポリシー]をクリックして[ポリシーの作成]をしましょう。
2. バケツを指定してポリシーを作成したいので[JSON]タグをクリックしてJSONを直接書きましょう。
3. バケット自体とバケットの中身全てに許可をする必要があるのがポイントです。

下記サンプルでは開発・ステージ・本番の３つのバケツに全ての権限を許可するようにしています。作成するポリシー名は自由ですが、私はサイトの名前＋WebDeployerという名前で作ってます。後からサイトが増えてもサイト名が入っていれば権限わけがしやすいですからね。

```JSON:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::develop.example.com",
                "arn:aws:s3:::stage.example.com",
                "arn:aws:s3:::example.com",
                "arn:aws:s3:::develop.example.com/*",
                "arn:aws:s3:::stage.example.com/*",
                "arn:aws:s3:::example.com/*"
            ]
        }
    ]
}
```

## 3. [AWS] IAMで上記ポリシーを振り分けたユーザーを作る

これは簡単ですね。とりあえずなんの権限もつけないユーザーを作ってから一覧でユーザー名をクリックし、[アクセス権限]タブから[アクセス権限を追加]で既存のポリシーから先ほど作成したポリシーをアタッチしてください。ユーザー名はなんでもいいのですが管理しやすいので私は[サイト名]を英語で書いてユーザー名にしてます。

## 4. [Bitbucket] 対象のリポジトリのPipelinesをオンにする

ここがちょっとわかりにくいところ。設定をオンにするのにどこにあるのかわかりにくいですが、対象リポジトリに画面の「設定」メニューをクリックした後に出てくる設定メニューの下の方にスクロールしたところに[PIPELINES]の直下の[Setting]メニューをクリックすると現れます。
<img width="548" alt="Bitbucket-setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/4164153c-15c4-cb78-d620-0c26f2cf297b.png">

ここをクリックしたら出る画面でトグルボタンをオンにするだけです。
<img width="764" alt="Bitbucket.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/c44c09e9-effa-6bba-d633-9bcb5b778e60.png">

## 5. [Bitbucket] S3に環境ごとに転送するbitbucket-pipelines.ymlを作る

AttlasianのHow to記事はリンクを辿るのが面倒なほど不親切ですが、ある程度CIにこなれた人が読むなら最初にこの記事が良いと思います。

[bitbucket-pipelines.yml を設定する](https://ja.confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html)

とはいえ自分でゴリゴリ書かなければいけないという訳でもなく、各種一般的なものはDockerによるコマンド実行が用意されています。基本的には各ステップのDockerの組み合わせで実行するイメージでいれば良いと思います。

というところですがAWSのS3へのデプロイは用意されているので、こちらを参考に作ればOKです。

サイドメニューの[Pipelines]をクリックして下にスクロールするとbitbucket-pipelines.ymlを直接編集してリポジトリにコミットできる画面が現れます。ここの右側に利用できるDockerが表示されております。

<img width="1038" alt="スクリーンショット 2019-12-17 20.22.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/e4b577d4-fa48-9714-7d5e-0b22a93d8841.png">

デフォルトでは、リポジトリに設定した言語の初期設定が表示されています。それぞれのDockerのpipeをクリックすると説明とExampleが出てくるのでこれを参考に左側の画面で編集して実行すると良いでしょうという。

HTML/CSSのリポジトリだとデフォルトでは下記のようになっています。

```yml
# This is a sample build configuration for Other.
# Check our guides at https://confluence.atlassian.com/x/5Q4SMw for more examples.
# Only use spaces to indent your .yml configuration.
# -----
# You can specify a custom docker image from Docker Hub as your build environment.
image: atlassian/default-image:2

pipelines:
  default:
    - step:
        script:
          - echo "Everything is awesome!"
```

これにAWS S3 DeployのパイプのExamplesからコードを持ってきます。
こんな感じでOKです。バケツ名はよしなに変えてください。

```yml
pipelines:
  default:
    - step:
        name: Default deployment 
        script:
          - echo "Everything is awesome!"
  branches:
    develop:
      - step:
          name: Development deployment
          deployment: test
          script:
            - pipe: atlassian/aws-s3-deploy:0.3.8
              variables:
                AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
                AWS_DEFAULT_REGION: ＄AWS_DEFAULT_REGION
                S3_BUCKET: '[テスト環境のバケット名]'
                LOCAL_PATH: '[リポジトリ内で中身を転送するフォルダ名]'
                ACL: 'public-read'
                DELETE_FLAG: 'true'
    master:
      - step:
          name: Staging deployment
          deployment: staging
          script:
            - pipe: atlassian/aws-s3-deploy:0.3.8
              variables:
                AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
                AWS_DEFAULT_REGION: ＄AWS_DEFAULT_REGION
                S3_BUCKET: '[ステージのバケット名]'
                LOCAL_PATH: '[リポジトリ内で中身を転送するフォルダ名]'
                ACL: 'public-read'
                DELETE_FLAG: 'true'
  tags:
    release-*:
      - step:
          name: Production deployment
          deployment: production
          script:
            - pipe: atlassian/aws-s3-deploy:0.3.8
              variables:
                AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
                AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
                AWS_DEFAULT_REGION: ＄AWS_DEFAULT_REGION
                S3_BUCKET: '[プロダクションのバケット名]'
                LOCAL_PATH: '[リポジトリ内で中身を転送するフォルダ名]'
                ACL: 'public-read'
                DELETE_FLAG: 'true'
```

ポイント
1. ブランチごと、タグごとにステップを作ります。
2. 使えるDockerイメージはstepごとに一つだけでstepは上から順に実行されます。
3. タグ名やブランチ名にはワイルドカード*を利用できます。やったね。
4. $から初めて環境変数を利用できます。コミットするコードにいれたくないシークレットな情報などの入力や、デプロイごとに変えたいような内容を環境変数を使うと良いでしょう。環境変数の設定は次へ。

S3への転送では特に複雑なことはないので、AWSへのアクセスキー、シークレットキー、リージョンだけ環境変数にしました。

$AWS_ACCESS_KEY_ID
$AWS_SECRET_ACCESS_KEY
＄AWS_DEFAULT_REGION

## 6. [Bitbucket] 環境変数を設定する

ここでまたリポジトリの[設定]メニューから[Repository Variables]をクリックして上記環境変数三つを設定します。
<img width="480" alt="スクリーンショット 2019-12-17 20.37.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/16e9e972-4f19-2b2c-3428-bc4611ec663d.png">

アクセスキーとシークレットは[secured]にチェックをいれてから追加しました。こうすると画面上でもログでも内容を確認できなくなるので安心ですね。
<img width="822" alt="スクリーンショット 2019-12-17 20.39.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28471/6ca2cef4-ddcc-ae9f-710a-b79b04f7f0d9.png">

なんとこれだけでdevelopにマージするとテストサイトへ、masterにマージするとステージサイトへ、タグrelease-20191217など日付をいれつつ作ると自動的に本番化されるようになりました！簡単！

ドメインをS3に向けるなどの設定が必要ですがRoute53を使っているならAレコードでエイリアスを作るのが一般的でしょう。外部のDNSを使っているならCNAMEを作成してS3の公開ホスト名に向けましょう。

個人的にはCloudFrontを通すことをお勧めしますよ。S3だとSSL使えないですからね！