Amazon EKSでAWS Load Balancer ControllerにS3ログ出力を設定する

# はじめに
Amazon EKSで[AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/)にS3ログ出力を設定する方法をまとめます。
Mac環境を想定しています。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

1.  EKSのコンテキストの設定
[MacにてAmazon EKSの設定をする](https://qiita.com/miyabiz/items/b98d145cedb35dab9524)を参考にしてください。

1.  Helmの設定
[Amazon EKSでHelmを利用する](https://qiita.com/miyabiz/items/453361e6af64b324443c)を参考にしてください。

1.  ArgoCDの設定
[Amazon EKSでArgoCDを利用する](https://qiita.com/miyabiz/items/4022b0aba372a8f2c292)を参考にしてください。

1.  AWS Load Balancer Controllerの設定
[Amazon EKSでAWS Load Balancer Controllerを利用する](https://qiita.com/miyabiz/items/b46c8333d8283ea451dc)を参考にしてください。

1.  AWS Load Balancer ControllerのAWS Certificate Managerの設定
[Amazon EKSでAWS Load Balancer ControllerにAWS Certificate Managerを利用する](https://qiita.com/miyabiz/items/af179dc6da160133d22a)を参考にしてください。

# S３バケットの作成

1. S３バケットを作成する
    ※今回は `akane-dev-elb-access-log` というバケット名にする
    ```sh
    BUCKET_NAME=akane-dev-elb-access-log
    aws s3api create-bucket \
      --bucket ${BUCKET_NAME} \
      --create-bucket-configuration LocationConstraint=ap-northeast-1
    ```

1.  バケットポリシーを設定する
    ※[Application Load Balancer のアクセスログを有効にする](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/enable-access-logging.html)を参考にしてください。
    ※今回は東京リージョンのため、ELBのサービスアカウント(ELBのAWSアカウントID)である`582318560864`を設定する
    ※今回はプレフィクスを`public-elb`にする。

    ```sh
    export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
    BUCKET_NAME=akane-dev-elb-access-log
    PREFIX=public-elb
    BUCKET_POLICY=$(echo -n '{
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::582318560864:root"
          },
          "Action": "s3:PutObject",
          "Resource": "arn:aws:s3:::'; echo -n "${BUCKET_NAME}"; echo -n '/'; echo -n "${PREFIX}"; echo -n '/AWSLogs/'; echo -n "${ACCOUNT_ID}"; echo -n '/*"
        }
      ]
    }')
    aws s3api put-bucket-policy \
    --bucket ${BUCKET_NAME} \
    --policy "${BUCKET_POLICY}"
    ```

# 環境設定
1.  `akane-ingress.yaml` を作成する
    ※[Custom attributes](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/#load-balancer-attributes)を参考にしてください。
    ※`ACMのARN`を設定する
    ※今回は `akane-dev-elb-access-log` というバケット名にする
    ※今回はプレフィクスを`public-elb`にする。

    ```yaml:akane-ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        alb.ingress.kubernetes.io/certificate-arn: ${ACMのARN}
        alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=akane-dev-elb-access-log,access_logs.s3.prefix=public-elb
      namespace: akane
    spec:
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: guestbook-ui
                port:
                  number: 3000
    ```

1.  クラスターに適用する

    ```sh
    kubectl apply -f akane-ingress.yaml
    ```

# クリーンアップ

1.  クラスターから削除する

    ```sh
    kubectl delete -f akane-ingress.yaml
    ```

1.  S3バケットを削除する
    ※今回は `akane-dev-elb-access-log` というバケット名にする。

    ```sh
    aws s3 rb s3://akane-dev-elb-access-log --force
    ```