Terraform

[Terraform] 테라폼으로 EKS 프로비저닝

운덩하는 개발자 2023. 12. 14.
반응형


 

main.tf

# AWS 프로바이더 설정: AWS 리소스를 관리하기 위해 지정된 리전을 설정합니다.
provider "aws" {
  region = var.region
}

# 사용 가능한 가용 영역을 필터링합니다. 이는 관리형 노드 그룹에서 현재 지원되지 않는 로컬 존을 제외하기 위한 것입니다.
data "aws_availability_zones" "available" {
  filter {
    name   = "opt-in-status"
    values = ["opt-in-not-required"]
  }
}

# 클러스터 이름을 지정하는 로컬 변수를 설정합니다. 여기서는 랜덤 문자열을 포함하여 고유한 이름을 생성합니다.
locals {
  cluster_name = "dohyung-eks-${random_string.suffix.result}"
}

# 랜덤 문자열 리소스를 생성합니다. 이는 클러스터 이름에 사용됩니다.
resource "random_string" "suffix" {
  length  = 8
  special = false
}

# VPC 모듈을 사용하여 가상 프라이빗 클라우드를 생성합니다. 이는 EKS 클러스터에 필요한 네트워크 환경을 설정합니다.
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "education-vpc"

  cidr = "10.0.0.0/16"
  azs  = slice(data.aws_availability_zones.available.names, 0, 3)

  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.4.0/24", "10.0.5.0/24", "10.0.6.0/24"]

  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true

  # 퍼블릭 서브넷에 태그를 지정하여 이들이 EKS 클러스터에 사용될 수 있도록 합니다.
  public_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/elb"                      = 1
  }

  # 프라이빗 서브넷에 태그를 지정하여 이들이 내부적으로 사용될 수 있도록 합니다.
  private_subnet_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
    "kubernetes.io/role/internal-elb"             = 1
  }
}

# EKS 모듈을 사용하여 EKS 클러스터를 생성합니다. 여기에는 클러스터 이름, 버전, 사용할 VPC 및 서브넷이 포함됩니다.
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "19.15.3"

  cluster_name    = local.cluster_name
  cluster_version = "1.27"

  vpc_id                         = module.vpc.vpc_id
  subnet_ids                     = module.vpc.private_subnets
  cluster_endpoint_public_access = true

  # 관리형 노드 그룹의 기본 설정입니다.
  eks_managed_node_group_defaults = {
    ami_type = "AL2_x86_64"
  }

  # 두 개의 관리형 노드 그룹을 정의합니다.
  eks_managed_node_groups = {
    one = {
      name = "node-group-1"

      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 3
      desired_size = 2
    }

    two = {
      name = "node-group-2"

      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 2
      desired_size = 1
    }
  }
}

# AWS EBS CSI 드라이버에 대한 IAM 정책을 데이터 소스로 가져옵니다. 이는 EBS 볼륨을 관리하기 위한 권한을 설정하는 데 사용됩니다.
data "aws_iam_policy" "ebs_csi_policy" {
  arn = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy"
}

# EBS CSI 드라이버에 사용할 IAM 역할을 생성합니다. OIDC를 사용하여 EKS 클러스터와 통합합니다.
module "irsa-ebs-csi" {
  source  = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc"
  version = "4.7.0"

  create_role                   = true
  role_name                     = "AmazonEKSTFEBSCSIRole-${module.eks.cluster_name}"
  provider_url                  = module.eks.oidc_provider
  role_policy_arns              = [data.aws_iam_policy.ebs_csi_policy.arn]
  oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:ebs-csi-controller-sa"]
}

# EBS CSI 드라이버를 EKS 클러스터에 애드온으로 추가합니다. 이는 EKS 클러스터에서 EBS 볼륨을 관리하는 데 사용됩니다.
resource "aws_eks_addon" "ebs-csi" {
  cluster_name             = module.eks.cluster_name
  addon_name               = "aws-ebs-csi-driver"
  addon_version            = "v1.20.0-eksbuild.1"
  service_account_role_arn = module.irsa-ebs-csi.iam_role_arn
  tags = {
    "eks_addon" = "ebs-csi"
    "terraform" = "true"
  }
}

 

outputs.tf

# 이 코드는 Terraform을 사용하여 AWS EKS 클러스터를 구성한 후
# 구성된 클러스터의 중요한 정보를 출력하는 부분입니다.
# 코드의 각 항목은 다음과 같은 정보를 출력하도록 설정되어 있습니다.


# EKS 컨트롤 플레인의 엔드포인트를 출력합니다. 이는 클러스터에 접근하기 위한 주소입니다.
output "cluster_endpoint" {
  description = "Endpoint for EKS control plane"
  value       = module.eks.cluster_endpoint
}

# 클러스터 컨트롤 플레인에 연결된 보안 그룹 ID를 출력합니다. 이 보안 그룹은 클러스터의 네트워크 액세스를 제어하는 데 사용됩니다.
output "cluster_security_group_id" {
  description = "Security group ids attached to the cluster control plane"
  value       = module.eks.cluster_security_group_id
}

# 사용된 AWS 리전을 출력합니다. 이는 클러스터가 구성된 지리적 위치를 나타냅니다.
output "region" {
  description = "AWS region"
  value       = var.region
}

# Kubernetes 클러스터의 이름을 출력합니다. 이 이름은 클러스터를 식별하는 데 사용됩니다.
output "cluster_name" {
  description = "Kubernetes Cluster Name"
  value       = module.eks.cluster_name
}

 

terraform.tf

# 이 코드는 Terraform 구성의 일부로,
# Terraform 클라우드 작업 공간 설정, 필요한 프로바이더의 정의, 그리고 사용되는 Terraform 버전에 대한 요구 사항을 지정합니다.


# Terraform 클라우드 설정: 이는 Terraform 클라우드에서 관리되는 작업 공간을 지정합니다.
terraform {
  cloud {
    organization = "dohyung-awscloudschool" 

    workspaces {
      name = "dohyung-eks"
    }
  }

  # 필요한 프로바이더를 지정합니다. 프로바이더는 Terraform이 리소스를 관리하기 위해 사용하는 플러그인입니다.
  required_providers {
    # AWS 프로바이더: AWS 리소스를 관리하기 위해 사용됩니다. 특정 버전을 지정하여 호환성을 유지합니다.
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.7.0"
    }

    # Random 프로바이더: 랜덤 값 생성에 사용됩니다. 예를 들어, 리소스 이름에 랜덤 문자열을 추가하는 데 사용할 수 있습니다.
    random = {
      source  = "hashicorp/random"
      version = "~> 3.5.1"
    }

    # TLS 프로바이더: TLS(Transport Layer Security) 관련 리소스 생성에 사용됩니다.
    tls = {
      source  = "hashicorp/tls"
      version = "~> 4.0.4"
    }

    # Cloudinit 프로바이더: 클라우드 초기화 구성을 관리하기 위해 사용됩니다. 이는 클라우드 인스턴스의 초기 설정을 정의하는 데 사용될 수 있습니다.
    cloudinit = {
      source  = "hashicorp/cloudinit"
      version = "~> 2.3.2"
    }
  }

  # 사용되는 Terraform 버전을 지정합니다. 이는 해당 버전이나 이후 호환되는 버전을 사용하도록 보장합니다.
  required_version = "~> 1.3"
}

 

 

variables.tf

variable "region" {
  description = "AWS region"
  type        = string
  default     = "ap-northeast-2"
}

 

 

 

 

리소스 삭제

terraform destroy

반응형

'Terraform' 카테고리의 다른 글

[Terraform] 테라폼으로 AWS EC2 프로비저닝 실습(예제)  (3) 2023.12.13

댓글