GitHub Actionsを使用してOKEへのDevOps実施

## 概要
GitHub Actionsを使用してOKEへのDevOps実施しました。
実施に当たり以下を参考にしています
[OCIで人気の4つのGitHubアクション](https://blogs.oracle.com/oracle4engineer/post/ja-4-popular-github-actions-for-oci)


## 構成
ソースコードリポジトリはGitHubを利用しています。
GitHub ActionsにてBuild、コンテナレジストリへのPushとKubernetesのマニフェストを使用したdeployを行っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/6cba7dd8-671c-b54f-b119-8ca454cfce2e.png)
								
## 前提
- Webコンテンツを作成してGitHubリポジトリにPush済み
- OCI OKEクラスターを構築済み

## コンテンツ作成とGitHubへのPush
サンプルアプリケーションとしてNginxを使用しました。

     |--deployment.yaml
     |--Dockerfile
     +--conf
     |  +--NGINX構成ファイル
     +--src
        +--コンテンツ

- deployment.yaml
container imageは以下のように設定します。
【コンテナ・レジストリ】/【ネームスペース】/【コンテナ名】:0000000000
 コンテナ・レジストリは東京であればnrt.ocir.io
 タグはGitHub Actions Workflowで変更するので0000000000としています。
 
```deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: 【app名】-deployment     # app名は任意
  labels:
    app: 【app名】
spec:
  replicas: 1   # テストなのでreplicaは1つ
  selector:
    matchLabels:
      app: 【app名】
  template:
    metadata:
      labels:
        app: 【app名】
    spec:
      containers:
      - name: 【app名】
        image: 【コンテナ・レジストリ】/【ネームスペース】/【コンテナイメージ】:0000000000  #コンテナ・レジストリのイメージへの完全修飾パス
        imagePullPolicy: Always
        ports:
        - containerPort: 8080  # nginx confファイルで設定したnginxのlisten port
          protocol: TCP
      imagePullSecrets:
        - name: 【secret】 # 事前にOCIRのlogin情報をsecretとして登録要
---
apiVersion: v1
kind: Service
metadata:
  name: 【app名】-svc
spec:
  selector:
    app: 【app名】
  ports:
    - port: 8085         # ServiceのExpose port
      targetPort: 8080   # nginx confファイルで設定したnginxのlisten port
      nodePort: 30990    # nodeで公開するport
  type: NodePort
```
## ポリシー設定
今回のDevOpsを行うために以下のポリシーを設定します。

- OCIRを管理可能とするポリシー
Allow Group ‘userが所属するグループ名’ to manage all-artifacts in compartment ‘コンパートメント名’

- OKEを管理するためのポリシー
Allow Group ‘userが所属するグループ名’ to manage cluster-family in compartment ‘コンパートメント名’

## コンテナ・レジストリ作成
コンテナイメージの格納先を作成します。
- OCIナビゲーションメニューから開発者サービス>>コンテナとアーティファクト>>コンテナ・レジストリを選択して「リポジトリの作成」を押下
- リポジトリ名に【コンテナ名】を入力して「作成」を押下

## secrets登録
GitHub Repository secretsに以下を設定します。
OCI_CLI_USER: OCI UserのOCID
OCI_CLI_TENANCY: OCIテナンシーのOCID
OCI_CLI_FINGERPRINT: OCI Userで追加したAPIキーFingerprintのOCID
OCI_CLI_KEY_CONTENT: OCI Userで追加したAPIキーの秘密キー
OCI_CLI_REGION: リージョン(例：ap-tokyo-1)
OKE_CLUSTER_OCID: OKEクラスターのOCID
OCI_AUTH_TOKEN: OCI Userで追加した認証トークン

参考
[必要なキーとOCID](https://docs.oracle.com/ja-jp/iaas/Content/API/Concepts/apisigningkey.htm)
[認証トークンの操作](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingcredentials.htm#Working)

## Workflowの作成
GitHub Actions Workflowを作成します。
今回コンテナイメージタグはCommit SHAを使用しています。

```.github/workflows/Build_Push_Deploy.yml 

name: Build_Push_Deploy

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:

  build:

    runs-on: ubuntu-latest
    env:
      OCI_CLI_USER: ${{ secrets.OCI_CLI_USER }}
      OCI_CLI_TENANCY: ${{ secrets.OCI_CLI_TENANCY }}
      OCI_CLI_FINGERPRINT: ${{ secrets.OCI_CLI_FINGERPRINT }}
      OCI_CLI_KEY_CONTENT: ${{ secrets.OCI_CLI_KEY_CONTENT }}
      OCI_CLI_REGION: ${{ secrets.OCI_CLI_REGION }}

    steps:
        # ソースコードをclone
      - uses: actions/checkout@v3

        # Dockerfileを元にbuild
      - name: Build the docker image
        id: build-docker-image
        run: docker build . --file Dockerfile --tag syd.ocir.io/orasejapan/docker-nginx:${{ github.sha }}

        # OCI コンテナレジストリにlogin
      - name: Log into OCIR
        uses: oracle-actions/login-ocir@v1.2.1
        id: login-into-ocir
        with:
          auth_token: ${{ secrets.OCI_AUTH_TOKEN }}

        # コンテナをOCI コンテナレジストリにpush
      - name: Push a container image
        id: push-container-image
        run: docker push syd.ocir.io/orasejapan/docker-nginx:${{ github.sha }}

        # OCI OKEの構成
      - name: Kubectl cluter
        uses: oracle-actions/configure-kubectl-oke@v1.3.2
        id: kubectl-cluster
        with:
          cluster: ${{ secrets.OKE_CLUSTER_OCID }}

        # コンテナイメージタグをCommit SHAに書き換えてdeployment.yamlをapply
      - name: Kubectl apply
        id: kubectl-apply
        run: |
          sed -i 's/0000000000/${{ github.sha }}/g' deployment.yaml
          kubectl apply -f deployment.yaml
```

## 実行結果
Code PushするとWorkflowが開始します。
完了後Podがローリングアップデートされたことが確認できました。

```
#Push前
NAME                                           READY   STATUS    RESTARTS   AGE
pod/docker-nginx-deployment-56cf499b96-r8224   1/1     Running   0          44m

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/docker-nginx-svc   NodePort    10.96.143.225   <none>        8085:30990/TCP      44m

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/docker-nginx-deployment   1/1     1            1           44m

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/docker-nginx-deployment-56cf499b96   1         1         1       44m


#Push後
NAME                                           READY   STATUS    RESTARTS   AGE
pod/docker-nginx-deployment-79d476c885-mc4c8   1/1     Running   0          7m37s

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/docker-nginx-svc   NodePort    10.96.143.225   <none>        8085:30990/TCP      56m

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/docker-nginx-deployment   1/1     1            1           56m

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/docker-nginx-deployment-56cf499b96   0         0         0       56m
replicaset.apps/docker-nginx-deployment-79d476c885   1         1         1       7m37s

```