privateリポジトリでもJenkinsとS3を使ってGithubPagesみたいなことしてみた

# 目的

**Github**の**privateリポジトリ**で管理している**静的コンテンツ**をmasterブランチに**マージしたタイミング**でJenkinsで**自動的**にAWSの**S3バケット**に転送し、**特定のIPからのみ閲覧出来る**ようにする

# 背景

**Github**の**privateリポジトリ**でも、**GithubPages**のような機能を実現する必要があった。
かつ、**特定IPからのみ**の**閲覧制限**をかける必要があった。

# 要点

## Jenkins

- Githubからの**Webhookで実行**されるJobの定義
- JenkinsのJob内で**AWS-cliを利用してS3バケットに転送**


## Github

- **privateリポジトリ**で静的コンテンツ管理
- Webhook機能を使って**GithubのマージをJenkinsに通知**

## S3
- S3バケットを**Webサイトホスティング化**
- S3のバケットポリシーを利用して、**特定のIPのみホワイトリストに追加**


# 参考にさせて頂いた記事

- [【全自動雑用おいたん】Githubへのpushを受け取ってJenkinsのJobを実行してみよう](https://blogenist.jp/it/2018/03/15/2604/)
- [【以外と簡単】S3バケットにIP制限をかける方法](https://blogenist.jp/it/2018/03/19/2951/)
- - [GitHub-Jenkins 連携とりあえずメモ](https://qiita.com/esukei/items/e6e135225725cee75d22)



# 作業

## Jenkins

### GithubからのWebhook用IP許可

GithubからWebhook通知を受ける際には、**以下のIPから通信**があるらしいので、セキュリティグループなりconfファイルなりで、**IPを許可する必要**があります。

```shell:ip
①192.30.252.0/22
②185.199.108.0/22
```

※詳しくは[コチラ](https://api.github.com/meta)

### SSHキーの発行

次にJenkinsサーバーにて、Jenkinsユーザーの**SSHキー**を発行します。
今回はとりあえず以下のコマンドでサクッと作成しちゃいます。

```shell:command
ssh-keygen -t rsa
```

ここで出来た公開鍵は**後ほどGithub側に登録する**ので、控えておきましょう。

### Github接続用の認証情報の作成

次に上記で作成した秘密鍵を使って**Githubと接続するための認証情報をJenkinsにて登録**します。

<img width="1256" alt="screencapture- 2018-03-18 19.37.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/df95722b-4022-7824-1676-f447e479f61d.png">

### Jobの作成

次にGithubからのWebhookを受けた際に実行するJobを作ってみましょう。

<img width="960" alt="screencapture- 2018-03-18 19.40.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/f46631cd-29cb-9631-4236-41ea2ba6547d.png">

ここで押さえるべきポイントは

- 認証情報に**先ほど作成したもの**を選択する
- **通知を受けたいブランチ名**を指定する
- ブランチを**チェックアウトするディレクトリ**を指定する(必要があれば)

なお、先ほど登録していた認証情報が**間違っている**と、選択した際に**<font color="red">以下のような認証エラー</font>**が出るので設定をもう一度見直しましょう。

<img width="971" alt="screencapture- 2018-03-18 19.35.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/02f69afb-924d-9c5e-b4d7-650c09e72a14.png">


次に**Jobで実行するシェル**を定義します。
今回は**AWS-cli**で転送するので以下のようになります。

```shell:command
aws --profile {対象プロフィール} s3 cp {チェックアウトディレクトリ} s3://{対象バケット名}  --recursive --acl public-read
```

上記コマンドは、**再帰的(--recursive)**に**公開設定(public-read)**で**チェックアウトしたファイル全て**を転送する、という設定になっています。
**特定のファイルは転送したくない！**等があれば、各自お好みで調整してください。

これで**Jenkins側の設定は完了**です。

## Github

### SSHの設定

先ほど作成した**Jenkinsの公開鍵を登録**しましょう。
**コピペして保存！！**

<img width="919" alt="screencapture- 2018-03-18 19.53.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/0f6f2e1e-5850-eaee-8e5f-dbd5ba60461d.png">


### Webhookの設定

次に、**Jenkinsに通知を実行したいリポジトリ**にWebhookの設定をします。

<img width="885" alt="screencapture- 2018-03-18 19.26.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/71d193b0-85e9-7d64-1144-0a27135c5135.png">

## S3

### バケットポリシーの設定

以下のように**バケットポリシーを設定**してください。

```json:ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::{転送先バケット名}",
                "arn:aws:s3:::{転送先バケット名}/*"
            ],
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "{許可するIP}",
                        "{JenkinsサーバーのIP}"
                    ]
                }
            }
        }
    ]
}
```

**※JenkinsサーバーからAWS-cliでの通信を許可する必要**があるので忘れないように設定しましょう。

<img width="1212" alt="screencapture- 2018-03-18 19.59.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/b50a7fdd-dec5-2998-d0e7-2b186bce4777.png">

# 確認

これで準備は整いました。
試しに**masterブランチへマージ**をしてみてください。

Jenkinsにて**Jobが走り**、

<img width="1257" alt="screencapture- 2018-03-18 20.15.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/6e48e704-f4e0-c227-df16-da97eeb44057.png">

S3に**コンテンツが転送され**、

<img width="1220" alt="screencapture- 2018-03-18 20.18.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/c6d0f255-a349-94a2-d052-cbff46c5ab9a.png">

ブラウザにて**表示**がされています。

<img width="1190" alt="screencapture- 2018-03-18 20.21.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/e8a1b0d0-452d-8a9b-16ed-b4caeba0823f.png">

**許可していないIP**だと**<font color="red">403エラー</font>**が出ています。

<img width="868" alt="screencapture- 2018-03-18 20.24.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/487dfa46-e63e-dd87-ee9d-f001c17777e7.png">

# 終わりに

**なんちゃってGithubPagesの完成☆**