EKSを terraform に移行、作成した際に苦労した話

Terraformのあれこれで苦労した話
◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【5/21開催】Azure OpenAI ServiceによるRAG実装ガイドを公開しました
生成AIを活用したユースケースで最も一番熱いと言われているRAGの実装ガイドを公開しました。そのガイドの紹介をおこなうイベントです!!
https://tech-lab.connpass.com/event/315703/

みなさんこんにちは、サイオステクノロジーの南です。私は案件で既存のEKSを terraform 側で全て管理できるように移行する作業を行っていたのですが、そこでつまづいたことが多々ありました。そこで今回は、移行するにあたって苦労した点や、解決方法などを書いていきたいと思います

リソース量が他クラウドk8sサービスよりも多い

以下の表ではterraformで管理しているk8sとその周辺リソースの数を、各クラウドごとでまとめたものです。

EKS

AKS

GKE

リソース数

98

58

61

見てもらうとAWS(EKS)が圧倒的に多いことがわかりますね・・

なぜ多くなるかというとEKS(AWS)が持つ以下のリソースをterraformで定義してあげる必要があるからです。

  • IAM
  • サブネット、IPアドレス、iptable などのネットワークに関連するもの

IAM

AWSにはIAMをアタッチすることで、リソースを動かすうえで必要な権限を付与することができます。

これらを運用することでリソースやユーザーがどれくらいアクセスできるかの範囲を調節が可能となりますが、それらの分だけIAMをterraformで定義するためにリソース数が増大しています。

IAMが付与される対象は以下のようなものになります。

EKS cluster

EKS node

Cloud watch

EBS-CSI-driver(eks addon)

auto scaler

具体的なものとして以下にterraformリソースを挙げています

resource "aws_iam_role" "role" {
  name               = "test-role"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "aws_iam_policy_document" "policy" {
  statement {
    effect    = "Allow"
    actions   = ["ec2:Describe*"]
    resources = ["*"]
  }
}

resource "aws_iam_policy" "policy" {
  name        = "test-policy"
  description = "A test policy"
  policy      = data.aws_iam_policy_document.policy.json
}

resource "aws_iam_role_policy_attachment" "test-attach" {
  role       = aws_iam_role.role.name
  policy_arn = aws_iam_policy.policy.arn
}

これはEC2に関するIAMですが見ての通りIAMロールとポリシー、IAMロールとポリシーを紐づけるアタッチメントで3つ必要になっています。

今回IAMが付与されていたのは上の5種類なので、合計で15個もリソースが増えることになります。

ネットワーク関連(サブネット、IPアドレスなど)

他k8s(AKS,GKE)などでは基本的にkubernetes周りのresourceをterraformに定義をしてあげるだけで、ネットワーク関連のものまで自動的に作成してくれます。

しかし、EKSでは別で、ネットワークのものもまとめて定義をしないと作成されない仕組みとなっています。

この部分だけでも20個を上回るため、やはりリソース増大に大きく影響している部分と言えます。

EBS CSIドライバーのアドオンを導入しないと、PodのPersistent Volumeがデプロイされない

Persistent Volume(PV)のマウントが必要なサービスをデプロイする際、podがずっとrunningにならないという問題がありました。

今回PVとしてはEBSを使用していたのですが、調べてみるとEBS CSIドライバーを導入しないとEBSをマウントすることができないとAWSが言っており、これに従って解決することができました。

ebs-csi-driverはAWSのストレージであるEBSをEKSで使えるようにするドライバーで、現在はAWS addonの一つであり、terraformのresourceとして定義することができます。

具体的なresourceとしては以下を定義しています。

resource "aws_eks_addon" "ebs_csi_driver" {
  cluster_name = aws_eks_cluster.my_cluster.name
  addon_name   = "ebs-csi-driver"
  addon_version = "1.3.0"  # ご利用のバージョンに適切な値を指定してください
  }

resource "aws_iam_role" "ebs_csi_driver_role" {
  name = "ebs-csi-driver-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "eks.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_policy" "ebs_csi_driver_policy" {
  name        = "ebs-csi-driver-policy"
  description = "IAM policy for EBS CSI Driver"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "ec2:AttachVolume",
          "ec2:CreateSnapshot",
          "ec2:CreateTags",
          "ec2:CreateVolume",
          "ec2:DeleteSnapshot",
          "ec2:DeleteTags",
          "ec2:DeleteVolume",
          "ec2:DescribeInstances",
          "ec2:DescribeSnapshots",
          "ec2:DescribeTags",
          "ec2:DescribeVolumes",
          "ec2:DetachVolume",
          "ec2:ModifyVolume",
          "ec2:Wait",
        ]
        Effect   = "Allow"
        Resource = "*"
      }
    ]
  })
}
resource "aws_iam_role_policy_attachment" "ebs_csi_driver_attachment" {
  policy_arn = aws_iam_policy.ebs_csi_driver_policy.arn
  role       = aws_iam_role.ebs_csi_driver_role.name
}

これらを定義することで解決しました。

特にEBSをpodのストレージとして使いたい方は要注意です。

terraform destroy時にサブネットや、vpcが削除できない

サブネットが削除できない

terraformでEKSを作成、もしくは移行を行ってから削除をする際、EKSのpublic subnetが削除されずにdestroyがエラーになってしまうことがよくありました。

これは、subnetに紐づいているload balancerが削除できていないために起こったエラーであり、terraform側もこれをHashiCorp社のGithubでissueとして報告しています。

サブネット削除問題に関しては、terraformコミッターの作ったmoduleを用いてロードバランサーを削除することで解決しました。

以下にURLとコードを記載します。

terraform-kubernetes-delete-eni

module "remove_eni" {
    source = "github.com/webdog/terraform-kubernetes-delete-eni"
    vpc_id = "your_vpc_id"
    region = "us-east-1"
}

vpcが削除できない

vpcもサブネット同様にdestroy時に削除ができなかったリソースでした。

こちらは、vpcに紐づいている複数のセキュリティグループのインバウンドルールがお互いを依存していることが原因であり、以下を実施することで解決しました。

  • 対象のセキュリティグループをimportする
  • 以下のコードのようにルールを空白にする
resource "aws_security_group" "example_sg" {
  vpc_id = aws_vpc.cluster_vpc.id
  ingress{
    description      = "Allow nodes to communicate with each other (all ports)"
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = []
    ipv6_cidr_blocks = []
  }
}
  • terraform destroyを行って対象リソースが消せることを確認する

まとめ

今回はEKSをterraformに移行、ないし作成でつまづいた点、解決方法などをお伝えしました。また何かこれらに関するネタがあれば書き出していこうと思います。

アバター画像
About 南 史弥 8 Articles
2021年に入社したのち、パブリッククラウドのkubernetesサービスなどを中心に業務に取り組んでいます。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる