# Terraform을 활용하여 EKS 클러스터를 구축하는 방법에 대해서 알아보자.
1. 일단 Terraform 설치는 아래의 링크로 이동하여 설치
2021.08.29 - [Terraform(테라폼)] - AWS CLI 및 Terraform 설치
AWS CLI 및 Terraform 설치
1. AWS CLI 설치 curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 2. 다운받은 CLI 파일을 압축해제 unzip awscliv2.zip sudo ./aws/install 3. Terraform 설치 # 테라폼 다..
may9noy.tistory.com
2. 설치 후 Terraform의 폴더 구조는 아래와 같게 한다.
:~/environment/terraform $ ls -l
eks-cluster.tf
eks-worker-nodes.tf
providers.tf
variables.tf
vpc.tf
workstation-external-ip.tf
3. 이제 세부 구성에 대해서 알아보자.
- providers.tf
# providers.tf
provider "aws" {
region = "ap-northeast-2"
}
provider "http" {}
프로바이더는 서비스 제공자라고 할수 있다. 테라폼은 멀티 플랫폼 서비스를 지원하므로 애저나 GCP, 네이버 클라우드등 다양한 프로바이더를 선택하여 인프라를 구축 할 수 있다.
- workstation-external-ip.tf
# workstation-external-ip.tf
data "http" "workstation-external-ip" {
url = "http://ipv4.icanhazip.com"
}
locals {
workstation-external-cidr = "${chomp(data.http.workstation-external-ip.body)}/32"
}
나의 공인ip 주소를 확인하고 입력한다고 보면 된다.
- vpc.tf
# create VPC
resource "aws_vpc" "terraform-eks-vpc" {
cidr_block = "10.110.0.0/16"
tags = {
"Name" = "terraform-eks-node"
"kubernetes.io/cluster/${var.cluster-name}" = "shared"
}
}
...
# create subnet
resource "aws_subnet" "terraform-eks-public-subnet" {
count = 2
availability_zone = data.aws_availability_zones.available.names[count.index]
cidr_block = "10.110.${count.index+1}.0/24"
map_public_ip_on_launch = true
vpc_id = aws_vpc.terraform-eks-vpc.id
tags = {
"Name" = "terraform-eks-public-${count.index+1 == 1 ? "a" : "c"}"
"kubernetes.io/cluster/${var.cluster-name}" = "shared"
}
}
...
# create route table
resource "aws_route_table" "terraform-eks-public-route" {
vpc_id = aws_vpc.terraform-eks-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.terraform-eks-igw.id
}
tags = {
"Name" = "terraform-eks-public"
}
}
...
# create route table association
# Subnet 과 Route table 을 연결
resource "aws_route_table_association" "terraform-eks-public-routing" {
count = 2
subnet_id = aws_subnet.terraform-eks-public-subnet.*.id[count.index]
route_table_id = aws_route_table.terraform-eks-public-route.id
}
생성시 주의할 점, aws_subnet.tags 중에 "kubernetes.io/cluster/${var.cluster-name}" = "shared"가 aws_vpc.tags 와 동일해야 한다. 이게 다를 경우 같은 클러스터인지 인식을 못해 정상적인 네트워크가 형성되지 않는다.
eks-cluster.tf
# IAM Role을 생성하고
resource "aws_iam_role" "terraform-eks-cluster" {
name = "terraform-eks-cluster"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
# 위에서 생성한 IAM Role에 policy를 추가한다.
resource "aws_iam_role_policy_attachment" "terraform-eks-cluster-AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.terraform-eks-cluster.name
}
# 위에서 생성한 IAM Role에 policy를 추가한다.
resource "aws_iam_role_policy_attachment" "terraform-eks-cluster-AmazonEKSVPCResourceController" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
role = aws_iam_role.terraform-eks-cluster.name
}
# security group을 생성하고
resource "aws_security_group" "terraform-eks-cluster" {
name = "terraform-eks-cluster"
description = "Cluster communication with worker nodes"
vpc_id = aws_vpc.terraform-eks-vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "terraform-eks-cluster"
}
}
# security group의 ingress 룰을 추가한다.
resource "aws_security_group_rule" "terraform-eks-cluster-ingress-workstation-https" {
cidr_blocks = [local.workstation-external-cidr]
description = "Allow workstation to communicate with the cluster API Server"
from_port = 443
protocol = "tcp"
security_group_id = aws_security_group.terraform-eks-cluster.id
to_port = 443
type = "ingress"
}
# 마지막으로 cluster를 생성
resource "aws_eks_cluster" "terraform-eks-cluster" {
name = var.cluster-name
role_arn = aws_iam_role.terraform-eks-cluster.arn
version = "1.20"
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
vpc_config {
security_group_ids = [aws_security_group.terraform-eks-cluster.id]
subnet_ids = concat(aws_subnet.terraform-eks-public-subnet[*].id, aws_subnet.terraform-eks-private-subnet[*].id)
endpoint_private_access = true
endpoint_public_access = true
}
depends_on = [
aws_iam_role_policy_attachment.terraform-eks-cluster-AmazonEKSClusterPolicy,
aws_iam_role_policy_attachment.terraform-eks-cluster-AmazonEKSVPCResourceController,
]
}
이렇게 IAM Role, Policy, Security Group, Cluster를 생성한다.
eks-worker-nodes.tf
# 여기서는 EC2관련 IAM Role을 생성해주고
resource "aws_iam_role" "terraform-eks-node" {
name = "terraform-eks-node"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
# 위에서 생성한 IAM Role에 Policy를 추가한다
resource "aws_iam_role_policy_attachment" "terraform-eks-node-AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.terraform-eks-node.name
}
# 위에서 생성한 IAM Role에 Policy를 추가한다
resource "aws_iam_role_policy_attachment" "terraform-eks-node-AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.terraform-eks-node.name
}
# 위에서 생성한 IAM Role에 Policy를 추가한다
resource "aws_iam_role_policy_attachment" "terraform-eks-node-AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.terraform-eks-node.name
}
# 마지막으로 Node Group을 생성한다.
resource "aws_eks_node_group" "terraform-eks-m5-large" {
cluster_name = aws_eks_cluster.terraform-eks-cluster.name
node_group_name = "terraform-eks-m5-large"
node_role_arn = aws_iam_role.terraform-eks-node.arn
subnet_ids = aws_subnet.terraform-eks-private-subnet[*].id
instance_types = ["m5.large"]
disk_size = 50
labels = {
"role" = "terraform-eks-m5-large"
}
scaling_config {
desired_size = 1
min_size = 1
max_size = 3
}
depends_on = [
aws_iam_role_policy_attachment.terraform-eks-node-AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.terraform-eks-node-AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.terraform-eks-node-AmazonEC2ContainerRegistryReadOnly,
]
tags = {
"Name" = "${aws_eks_cluster.terraform-eks-cluster.name}-terraform-eks-m5-large-Node"
}
}
위의 내용에서는 노드그룹을 생성하여 클러스터와 연결해 준다.
aws의 모듈 속성은 아래의 링크를 참조한다.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs
Terraform Registry
registry.terraform.io
'♻ Terraform(테라폼) > Terraform 활용' 카테고리의 다른 글
테라폼을 활용한 S3 버킷 저장소 생성 (lock) (0) | 2022.04.14 |
---|---|
테라폼을 활용한 웹서버 클러스터(ASG) 배포 (0) | 2022.04.13 |
테라폼을 활용한 단일 웹 서버 배포 (0) | 2022.04.13 |
테라폼을 활용한 단일서버 배포 (0) | 2022.04.13 |
Terraform 을 활용하여 IAM 설정하기 (0) | 2021.08.31 |