AGICのセットアップ手順書 Helm v3

少し雑すぎるので随時追記していきます。🙇‍♂️

# 構築手順
## 必要なリソース
- Azure Kubernetes service
- Application gateway
- Virtual network
- Public IP address
- Managed ID

## 手順
### リソースの作成
#### 1. Virtual network
リソース名：agicsample-vnet

**サブネットの作成**
**IPアドレス**タブからサブネットの追加
![add-subnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256522/c3640f52-ebfe-91a6-65d0-63c493b13717.png)

1. Application gateway

| 設定項目 | 値 |
|:-----------|:------------|
| サブネット名 | appgwSubnet |
| サブネットアドレス範囲 | 10.1.0.0/16 |

2. Azure Kubernetes service 

| 設定項目 | 値 |
|:-----------|:------------|
| サブネット名 | aksSubnet |
| サブネットアドレス範囲 | 10.0.0.0/16 |

#### 2. Public IP address
リソース名：agicsample-publicip
**SKU**
Application gatewayのSKUと合わせる必要があるため___Standard___を選択

#### 3. Application gateway
**レベル**
AGICに対応しているのがV2のみのため
___Standard V2___もしくは___WAF V2___

**仮想ネットワークの構成**

| 設定項目 | 値 |
|:-----------|:------------|
| 仮想ネットワーク | agicsample-vnet |
| サブネット | appgwsubnet |

**パブリックIPアドレス**

| 設定項目 | 値 |
|:-----------|:------------|
| パブリックIPアドレス | agicsample-publicip |

#### 4. Azure Kubernetes service
**ネットワーク構成**を詳細に切り替え以下の設定をする

| 設定項目 | 値 |
|:-----------|:------------|
| 仮想ネットワーク | agicsample-vnet |
| クラスター サブネット | akssubnet |

#### 5. Managed Identity
リソース名：agicsample-managedid

### 権限設定
マネージドIDに各種必要な権限を割り振ります
それぞれのリソースの「アクセス制御(IAM)」から「追加」を選択
1. Application gateway
共同作成者

2. リソースグループ
観覧者

### Kubernetes
**前提**
以下3点がインストールされていることが前提
- Azure CLI
- kubectl
- helm

#### 準備
ログインをして操作するサブスクリプションに切り替えておく

```powershell
az login 
```

`get-credentials`で資格情報を取得する

```powershell
az aks get-credentials -g <AKSのリソースグループ名> -n <AKSのリソース名>
```

#### アプリケーションの追加
##### AKSとACRの連携

```powershell
az aks update -n <AKSのリソース名>  -g <リソースグループ名> --attach-acr <ACRの名前>
```

##### Deploymentの作成

```yaml:deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: agicsample-webapp
spec:
  template:
    metadata:
      labels:
        app: agicsample-webapp
    spec:
      nodeSelector:
        "beta.kubernetes.io/os": linux
      containers:
      - name: agicsample-webapp
        image: <container>:<tag>
        ports:
        - containerPort: 80
```

```yaml:service.yaml
apiVersion: v1
kind: Service
metadata:
  name: agicsample-webapp
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: agicsample-webapp
```

上記2点の設定で以下のコマンドを実行

```powershell
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
```

それぞれを

```powershell
kubectl get -f deployment.yaml
kubectl get -f service.yaml
```
で正常に動いているかを確認し問題がなければアプリケーションの追加完了です。

#### AAD POD Identityの設定
これを設定することでPodがAADに依存するリソースを使用できるようになります。
##### aad-pod-identityのdeployment作成
RBAC(ロールベースアクセス制御)の有効・無効で作成するdeploymentが変わります。

```powershell:RBAC有効時
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml
```

```powershell:RBAC無効時
kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment.yaml
```

##### Azure Identityリソースの作成
先程作成したマネージドIDのリソースIDを使用します。

思い出せない場合は

```powershell
az identity show -g <リソースグループ名> --name <IDの名前(今回はagicsample-managedid)>
```
で表示されたidの欄を使用します。

```powershell
/subscriptions/<サブスクリプションID>/resourcegroups/<リソースグループ名>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<リソース名>
```
形式はこのような感じになっています。

```yaml:aadpodidentity.yaml
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentity
metadata:
  name: <任意の名前>
spec:
  type: 0
  ResourceID: <マネージドIDのリソースID>
  ClientID: <clientId>
```

```powershell
kubectl apply -f aadpodidentity.yaml
```

##### Azure Identity Bindingリソースの作成

`spec`の`AzureIdentity`は前項で作成したAzureIdentityの名前を入力します。

```yaml:aadpodidentitybinding.yaml
apiVersion: "aadpodidentity.k8s.io/v1"
kind: AzureIdentityBinding
metadata:
  name: <任意の名前>
spec:
  AzureIdentity: <AzureIdentityの名前>
```

```powershell
kubectl apply -f aadpodidentitybinding.yaml
```

#### AGICのインストール

下の`helm-config.yaml`をIngress Controllerをインストールする際に使用します。

引用元:[helm-config.yaml](https://azure.github.io/application-gateway-kubernetes-ingress/examples/sample-helm-config.yaml)

```yaml:helm.config
verbosityLevel: 3

appgw:
    subscriptionId: <Application gatewayのサブスクリプションID>
    resourceGroup: <Application gatewayのリソースグループ名>
    name: <Application gateway名>
    usePrivateIP: false
    shared: false

armAuth:
    type: aadPodIdentity
    identityResourceID: <マネージドIDのリソースID>
    identityClientID:  <マネージドIDのクライアントID>

rbac:
    enabled: false # true/false
```

```powershell
helm repo add application-gateway-kubernetes-ingress https://appgwingress.blob.core.windows.net/ingress-azure-helm-package/
helm repo update
helm install -f helm-config.yaml application-gateway-kubernetes-ingress/ingress-azure --generate-name
```
helm installを実行してインストールを行います。

ここで

```powershell
Error: unable to build kubernetes objects from release manifest: error validating "": error validating data: unknown object type "nil" in ConfigMap.data.USE_PRIVATE_IP
```

このようなエラーが出た場合は末尾に`--set appgw.usePrivateIP=false`と付け足し回避します。

#### Ingressリソースの設定
現状のPodを確認すると正しく動作している場合は下のようになっていると思います。
micとnmiはAAD POD IDの設定で追加されたManaged Identity ControllerとNode Managed Identityです。
ingress-azureはさっきインストールしたAGICです。

```powershell
kubectl get po

NAME                                        READY   STATUS    RESTARTS   AGE
ingress-azure-1584084813-6d66486f88-hgqkh   1/1     Running   0          3d22h
mic-9fcd99877-f8jfm                         1/1     Running   0          4d2h
mic-9fcd99877-pj9qw                         1/1     Running   0          4d2h
nmi-22bq9                                   1/1     Running   0          4d2h
nmi-q5qt4                                   1/1     Running   0          4d2h
nmi-xznrg                                   1/1     Running   0          4d2h
```

ここからはIngressリソースの設定をしていきます。ここを元にApplication gatewayの設定が変更されます。

```yaml:ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: agicsample-webapp
  annotations:
    kubernetes.io/ingress.class: azure/application-gateway
    appgw.ingress.kubernetes.io/backend-path-prefix: "/"
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: agicsample-webapp
          servicePort: 80
```

`backend`の`serviceName`と`servicePort`はアプリケーションの追加で設定した値を使用します。

```yaml:ingress.yaml
kubectl apply -f ingress.yaml
```

これでAzure Portal上で確認してApplication gatewayの設定が変更されていればセットアップ成功となります。