티스토리 뷰
결과
서울리전의 A,B,C 3개의 AZ를 사용하는 VPC와 각 AZ별 public,private 서브넷 생성
이후 해당 서브넷을 사용하는 EKS클러스터 를 배포하고 특정IP와 클러스터에서 사용하는 NAT-GW IP만 API접근을 허용 함
생성된 private 서브넷을 사용하는 RDS 배포하고 BASTION과 EKS클러스터의 접근을 허용
클러스터와 RDS에 접근할수 있는 BASTION을 배포
특정IP에서 BASTION으로 ssh접근을 허용함
먼저 variables.tf에 변수를 수정
variable "aws_region" {
default = "ap-northeast-2"
}
variable "cluster-name" {
default = "my-cluster"
type = string
}
variable "dbpassword" {
default = "password"
}
variable "key_name" {
default = "default"
}
클러스터 네임, rds에서 사용할 패스워드, bastion에 적용될 keypair이름 설정
bastion.tf에서 bastion에 ssh를 허용할 IP설정
#클러스터에 접근하거나 관리할때 사용하는 BASTION노드 설정
#BASION에 할당 할 탄력적 ip생성
resource "aws_eip" "bastion-eip" {
vpc = true
tags = {
"Name" = "${var.cluster-name}-bastion-eip"
}
}
#EC2 인스턴스 생성
resource "aws_instance" "bastion" {
ami = "ami-0cbec04a61be382d9" //ami2
instance_type = "t2.medium"
subnet_id = aws_subnet.public-subnet[0].id //pubilc서브넷 할당
vpc_security_group_ids = [aws_security_group.bastion.id]
key_name = "${var.key_name}" //key name
tags = {
Name = "${var.cluster-name}-bastion"
}
}
#생성된 탄력적ip와 인스턴스 연결
resource "aws_eip_association" "eip_assoc" {
instance_id = aws_instance.bastion.id
allocation_id = aws_eip.bastion-eip.id
}
### Bastion에서 사용할 SG및 rule
resource "aws_security_group" "bastion" {
name = "${var.cluster-name}-bastion"
vpc_id = aws_vpc.vpc.id
description = "${var.cluster-name}-bastion-sg"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.cluster-name}-bastion"
}
}
# 아래 아이피 대역에서 ssh접근을 허용함
resource "aws_security_group_rule" "allowssh" {
description = "allow andyhome and 10f"
type = "ingress"
from_port = 22
to_port = 22
protocol = "TCP"
cidr_blocks= ["110.117.232.147/32"]
security_group_id = aws_security_group.bastion.id
}
#아래 아이피 대역에서 모든 접근을 허용함(테스트)
resource "aws_security_group_rule" "allowall" {
description = "allow andyhome"
type = "ingress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks= ["110.117.232.147/32"]
security_group_id = aws_security_group.bastion.id
}
위 코드중 110.117.232.147/32 을 원하는 대역으로 수정
eks-cluster.tf
eks 클러스터를 배포
#EKS 클러스터 구성
# eks 에서 사용할 role 생성
resource "aws_iam_role" "eks" {
name = "${var.cluster-name}"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
#role에 policy add
resource "aws_iam_role_policy_attachment" "AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks.name
}
resource "aws_iam_role_policy_attachment" "AmazonEKSVPCResourceController" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
role = aws_iam_role.eks.name
}
#클러스터에 추가할 SG설정 bastion에서 모든 포트로 ingress허용 정책 rule을 추가한 sg를 추가하여 클러스터 생성시 ADD함
resource "aws_security_group" "cluster-bastion" {
name = "${var.cluster-name}-cluster-bastion"
description = "Cluster communication with bastion nodes"
vpc_id = aws_vpc.vpc.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.cluster-name}-cluster"
}
}
#bastion에서 오는 모든 트래픽 허용 정책
resource "aws_security_group_rule" "ingress-bastion" {
description = "Allow bastion to communicate with the cluster"
from_port = 0
protocol = "-1"
security_group_id = aws_security_group.cluster-bastion.id
source_security_group_id = aws_security_group.bastion.id
to_port = 0
type = "ingress"
}
#애드온 변수 선언
variable "addons" {
type = list(object({
name = string
}))
default = [
{
name = "kube-proxy"
},
{
name = "vpc-cni"
},
{
name = "coredns"
}
]
}
#선언된 애드온 변수 이용하여 애드온 설치
resource "aws_eks_addon" "addons" {
for_each = { for addon in var.addons : addon.name => addon }
cluster_name = aws_eks_cluster.eks.name
addon_name = each.value.name
resolve_conflicts = "OVERWRITE"
}
# 클러스터 로그 cloud watch 보관주기 30일 설정
resource "aws_cloudwatch_log_group" "eks" {
name = "/aws/eks/${var.cluster-name}/cluster"
retention_in_days = 30
}
# 클러스터 기본 설정
resource "aws_eks_cluster" "eks" {
name = var.cluster-name
role_arn = aws_iam_role.eks.arn
version = "1.22" //클러스터 버전 명시
enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"] //로깅
#클러스터 네트워크 설정
vpc_config {
security_group_ids = [aws_security_group.cluster-bastion.id] //클러스터 기본 보안그룹 외 추가할 보안그룹 설정(위에서 만든 BASTION허용 정책을 추가)
subnet_ids = concat(aws_subnet.public-subnet[*].id, aws_subnet.private-subnet[*].id)
endpoint_private_access = true
endpoint_public_access = true
#api access의 cidr제한을 검 허용할 ip외 nat gateway도 허용하여야 exec,logs 등의 명령어를 쓸수 있음
public_access_cidrs = ["110.117.232.147/32", "${aws_eip.eip.public_ip}/32"]
}
# policy의 dependency를 검
depends_on = [
aws_iam_role_policy_attachment.AmazonEKSClusterPolicy,
aws_iam_role_policy_attachment.AmazonEKSVPCResourceController,
]
}
eks-worker-nodes.tf
nodegroup을 배포
#EKS WORKER 노드 설정
# 워커노드에서 사용할 role 생성
resource "aws_iam_role" "node" {
name = "${var.cluster-name}-node"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
#생성한 role에 policy 할당
resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.node.name
}
resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.node.name
}
resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.node.name
}
#asg는 nodegroup으로 인해 자동으로 생성되나 name을 설정해주기 위해 tag만 지정하여줌
resource "aws_autoscaling_group_tag" "c6i-2xlarge" {
autoscaling_group_name = aws_eks_node_group.c6i-2xlarge.resources[0].autoscaling_groups[0].name
tag {
key = "Name"
value = "${var.cluster-name}-node"
propagate_at_launch = true
}
}
# c6i 2xlarge node group
resource "aws_eks_node_group" "c6i-2xlarge" {
cluster_name = aws_eks_cluster.eks.name
node_group_name = "${var.cluster-name}-c6i-2xlarge"
node_role_arn = aws_iam_role.node.arn
subnet_ids = aws_subnet.private-subnet[*].id
instance_types = ["c6i.2xlarge"]
disk_size = 50
labels = {
"role" = "${var.cluster-name}-c6i-2xlarge"
}
scaling_config {
desired_size = 3
min_size = 3
max_size = 10
}
depends_on = [
aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
]
tags = {
"Name" = "${var.cluster-name}-c6i-2xlarge-Node",
"Names" = "${var.cluster-name}-c6i-2xlarge-Node"
}
}
위 예제는 c6i.2xlarge 타입의 인스턴스 노드그룹을 배포 scaling config과 disk_size등 필요하면 수정하여 사용
소스는 아래 github에