CrossplaneでAWSのRoute53にHosted zoneとレコードを作る方法

この記事では、Crossplaneを使ってAWS Route53のHosted ZoneとDNSレコードを作成する方法について、具体的な手順を説明します。

CrossplaneはKubernetesのカスタムリソースとしてクラウドリソースを管理できるツールです。今回は、CrossplaneのAWSプロバイダーを使って、Route53のリソースを管理する方法を紹介します。

## 前提条件

- Kubernetesクラスターを用意しておいてください
- kubectlコマンドが必要です
- AWSアカウントとIAMクレデンシャルが必要です

## 1. AWS Providerのインストール

まず、CrossplaneのAWSプロバイダーをインストールします。以下のマニフェストを`provider-aws.yaml`として保存します：

```yaml
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
  name: provider-aws
spec:
  ignoreCrossplaneConstraints: false
  package: xpkg.upbound.io/crossplane-contrib/provider-aws:v0.50.2
  packagePullPolicy: IfNotPresent
  revisionActivationPolicy: Automatic
  revisionHistoryLimit: 1
  skipDependencyResolution: false
```

以下のコマンドでプロバイダーをインストールします：

```bash
kubectl apply -f provider-aws.yaml
```

## 2. AWS認証情報の設定

### 2.1 認証情報ファイルの作成

`aws-credentials.txt`ファイルを作成し、AWSの認証情報を記述します：

```ini
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
```

### 2.2 Kubernetes Secretの作成

認証情報をKubernetesのSecretとして作成します：

```bash
kubectl create secret \
    generic aws-secret \
    -n crossplane-system \
    --from-file=creds=./aws-credentials.txt
```

## 3. ProviderConfigの設定

AWSプロバイダーの設定を行います。以下のマニフェストを`provider-config.yaml`として保存します：

```yaml
apiVersion: aws.crossplane.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    secretRef:
      key: creds
      name: aws-secret
      namespace: crossplane-system
    source: Secret
```

設定を適用します：

```bash
kubectl apply -f provider-config.yaml
```

## 4. Route53 Hosted Zoneの作成

Hosted Zoneを作成するマニフェストを`hosted-zone.yaml`として保存します：

```yaml
apiVersion: route53.aws.crossplane.io/v1alpha1
kind: HostedZone
metadata:
  name: suin.jp  # Kubernetesリソースとしての名前
spec:
  deletionPolicy: Delete  # リソース削除時の動作を指定
  forProvider:
    name: suin.jp  # 実際のDNSゾーン名
```

### HostedZoneの設定項目の解説

- `metadata.name`: Kubernetesリソースとしての識別子です。後でレコードを作成するとき、この識別子を用います。
- `spec.deletionPolicy`: 
  - `Delete`: マニフェストを削除した時にRoute53のHosted Zoneも削除されます
  - `Orphan`: マニフェストを削除してもRoute53のHosted Zoneは残ります
- `spec.forProvider.name`: Route53に作成される実際のDNSゾーン名です。有効なドメイン名を指定します。

Hosted Zoneを作成します：

```bash
kubectl apply -f hosted-zone.yaml
```

## 5. DNSレコードの作成

最後に、DNSレコードを作成します。以下のマニフェストを`record-set.yaml`として保存します：

```yaml
apiVersion: route53.aws.crossplane.io/v1alpha1
kind: ResourceRecordSet
metadata:
  name: www.suin.jp  # Kubernetesリソースとしての名前
spec:
  deletionPolicy: Delete  # リソース削除時の動作を指定
  forProvider:
    resourceRecords:
    - value: '127.0.0.1'  # レコードの値
    ttl: 300  # キャッシュ時間（秒）
    type: A  # レコードタイプ
    zoneIdRef:
      name: suin.jp  # 所属するHostedZoneの名前（metadata.name）
```

### ResourceRecordSetの設定項目の解説

- `metadata.name`: Kubernetesリソースとしての識別子です。
- `spec.deletionPolicy`: HostedZoneと同様に、`Delete`または`Orphan`を指定できます。
- `spec.forProvider`:
  - `resourceRecords`: レコードの値を配列で指定します
    - `value`: IPアドレスやCNAMEの値など、レコードタイプに応じた値
  - `ttl`: Time To Live（キャッシュ時間）を秒単位で指定
  - `type`: レコードタイプを指定（A, AAAA, CNAME, MX, TXT等）
  - `zoneIdRef.name`: このレコードを作成するHostedZoneを指定。HostedZoneリソースの`metadata.name`と一致させます



レコードを作成します：

```bash
kubectl apply -f record-set.yaml
```

## リソースの確認方法

作成したリソースは以下のコマンドで確認できます：

```bash
# Hosted Zoneの確認
kubectl get hostedzone

# DNSレコードの確認
kubectl get resourcerecordset
```

## 注意点

- `deletionPolicy: Delete`を指定していますが、本番環境では慎重に設定してください
- Route53の料金が発生するため、不要なリソースは削除することをお勧めします
- IAMユーザーには適切な権限が必要です（Route53の管理権限）

## まとめ

Crossplaneを使うことで、Route53のリソースをKubernetesのマニフェストとして管理できるようになりました。これにより：

- インフラのコード化（IaC）が実現できる
- GitOpsワークフローに組み込める
- Kubernetesの作法でDNS管理ができる

という利点があります。

## 参考リンク

- [Crossplane公式ドキュメント](https://docs.crossplane.io/)
- [AWS Provider for Crossplane](https://marketplace.upbound.io/providers/crossplane-contrib/provider-aws)