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

Terraformのあれこれで苦労した話
【6/19開催】Kong Community Japan Meetup #4
本イベントでは、Kong Inc. のVP of ProductであるReza Shafii氏もプレゼンターとして参加。当社からはアーキテクト マネージャーの槌野の登壇が決定!参加無料です!!

【6/21開催】開発者目線でのSBOMとの向き合い方
SBOMの導入から開発者がSBOMの作成・管理を自動で行っていくための方法(デモ)を紹介します。

【7/5開催】azd+Terraform? ~ポイントを押えてAzure上へのアプリケーション環境をラクチン構築~
ツールの概要説明から、実際の開発におけるポイントをお伝えします!

【7/19開催】現場で役立つAzure神小技10+α 〜生成AI,RAG,コスト削減など旬な技術満載のLT大会〜
Azureの最新技術や実用的な小技を紹介する特別なライトニングトーク大会を開催します!

【7/26開催】最適なIaCツールを選ぼう
プロジェクトでのツール選びに困らないための重要な観点をご説明します!

みなさんこんにちは、サイオステクノロジーの南です。私は案件で既存の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.


*


質問はこちら 閉じる