Terraform Cloud를 통해 동적 자격 증명에 대한 간략한 내용 및 AWS Provider 동적 자격 증명 구성 실습을 이 전 글에서 다루었다.
이번 글에서는 Kubernetes 동적 자격 증명 구성을 통해 Kubernetes RBAC권한을 이용하여 테라폼에서 Kubernetes Provider를 사용하여 Kubernetes 리소스를 배포하는 실습을 다룰 것이다.
Kubernetes Dynamic Provider Credentials의 인증 워크플로우는 아래와 같다.
- 사용자가 Terraform Cloud를 통해 Plan & Apply를 실행한다.
- Terraform Cloud는 JWT Token을 EKS API서버에 전달하여 검증한다.
- EKS API 서버에서 임시 자격 증명을 발급한다.
- Terraform Cloud는 임시 자격 증명 + EKS RBAC 권한을 통해 EKS Resources를 생성한다.
구성도는 아래와 같다.
전제 조건
- Terraform Cloud 계정
- AWS 계정
- EKS 클러스터
- [Terraform Cloud + Github 연동]
1. EKS OIDC 생성
AWS Console을 통해 아래와 같이 설정하여 생성한다.
- AWS Console > EKS > 클러스터 > {클러스터 이름} > 액세스 > ID 제공업체 연결
정상 생성 확인
만약 테라폼 코드로 생성할 경우 아래와 같이 설정 후 생성하면 된다.
## eks_oidc.tf
resource "aws_eks_identity_provider_config" "oidc_config" {
cluster_name = var.cluster_name
oidc {
identity_provider_config_name = "terraform-cloud"
client_id = "kubernetes"
issuer_url = "https://app.terraform.io"
username_claim = "sub"
groups_claim = "terraform_organization_name"
}
}
OIDC Token 검증할 때 토큰 구조는 아래와 같다.
## header
{
"typ" : "JWT" ,
"alg" : "RS256" ,
"kid" : "j-fFp9evPJAzV5I2_58HY5UvdCK6Q4LLB1rnPOUfQAk"
}
## payload
{
"jti": "1192426d-b525-4fde-9d42-f238be437bbd",
"iss": "https://app.terraform.io",
"aud": "my-example-audience",
"iat": 1650486122,
"nbf": 1650486117,
"exp": 1650486422,
"sub": "https://app.terraform.io#organization:my-org:project:Default Project:workspace:my-workspace:run_phase:apply",
"terraform_organization_id": "org-GRNbCjYNpBB6NEH9",
"terraform_organization_name": "my-org",
"terraform_project_id": "prj-vegSA59s1XPwMr2t",
"terraform_project_name": "Default Project",
"terraform_workspace_id": "ws-mbsd5E3Ktt5Rg2Xm",
"terraform_workspace_name": "my-workspace",
"terraform_full_workspace": "organization:my-org:project:Default Project:workspace:my-workspace",
"terraform_run_id": "run-X3n1AUXNGWbfECsJ",
"terraform_run_phase": "apply"
}
Terraform Cloud에서 토큰을 전달할 때 위 구조로 전달하는데 "terraform_organization_name" 값에 Terraform Cloud의 organization 이름을 넣어 전달한다. EKS API는 해당 값이 유효한지 판단 후 자격 증명을 부여하고 RBAC의 "Group"권한을 통해 EKS 리소스에 접근할 수 있게 되는 것이다.
2. Terraform 코드 설정
Kubernetes Provider 코드 작성
## provider.tf
data "aws_eks_cluster" "eks" {
name = var.cluster_name
}
provider "kubernetes" {
host = data.aws_eks_cluster.eks.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks.certificate_authority[0].data)
}
Kubernetes Provider를 사용하여 namespace를 생성하는 테라폼 코드 생성
## namespace.tf
resource "kubernetes_namespace" "test" {
metadata {
annotations = {
name = "test"
}
name = "test"
}
}
3. EKS RBAC 설정
Kubernetes Provider가 실행될 때 사용할 RBAC 권한 설정을 EKS 환경에 배포한다.
Group 권한
$ kubectl apply -f - <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odic-identity
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: Group
name: {TFC_Organization_name}
apiGroup: rbac.authorization.k8s.io
EOF
Group에 넣을 내용은 위 EKS OIDC 생성 때 지정한 그룹 클레임(terraform_organization_name)의 값인 "Terraform Cloud(TFC)의 Organization 이름"으로 지정하여 할당한다.
User 권한
$ kubectl apply -f - <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odic-identity
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: User
name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:plan
apiGroup: rbac.authorization.k8s.io
- kind: User
name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:apply
apiGroup: rbac.authorization.k8s.io
EOF
4. Terraform Cloud 변수 설정
아래 위치로 이동하여 Terraform Cloud 워크스페이스의 variables를 설정한다.
- https://app.terraform.io/ 로그인 > Organization > Projects & workspaces > {Workspace} > Variables
- TFC_KUBERNETES_PROVIDER_AUTH : true
- TFC_KUBERNETES_WORKLOAD_IDENTITY_AUDIENCE : kubernetes
5. EKS 권한 검증
위 설정한 테라폼 코드를 github에 push 하여 Terraform Cloud Plan & Apply 트리거하여 정상 생성되는지 확인한다.
Group 권한으로 생성
정상적으로 namespace가 생성된 걸 확인할 수 있다.
만약 Terraform Cloud 변수 설정 중 " TFC_KUBERNETES_PROVIDER_AUTH" 값을 "false"로 변경하여 Plan & Apply 하면 아래와 같은 인증 에러가 발생하고 실패한다.
User 권한으로 “Plan”에만 권한 부여하여 생성
- Kubernetes RBAC
$ kubectl apply -f - <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odic-identity
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: User
name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:plan
apiGroup: rbac.authorization.k8s.io
#- kind: User
# name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:apply
# apiGroup: rbac.authorization.k8s.io
EOF
아래와 그림과 같이 Plan은 통과하고, Apply 오류가 발생한다.
User 권한으로 “plan & apply”권한을 부여하여 생성
- Kubernetes RBAC
$ kubectl apply -f - <<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: odic-identity
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: User
name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:plan
apiGroup: rbac.authorization.k8s.io
- kind: User
name: https://app.terraform.io#organization:{TFC_조직_이름}:project:{TFC_프로젝트_이름}:workspace:{TFC_워크스페이스_이름}:run_phase:apply
apiGroup: rbac.authorization.k8s.io
EOF
아래와 같이 Plan & Apply 모두 정상 실행되는 것을 확인할 수 있다.
'IaC > Terraform' 카테고리의 다른 글
Terraform Cloud Drift Detection이란? (0) | 2024.03.05 |
---|---|
Terraform Cloud Agent 개념 및 사용 방법 (0) | 2024.02.29 |
Terraform Cloud를 활용한 AWS Provider 동적 자격 증명 구성(Dynamic Provider Credentials) (0) | 2024.01.09 |
Terraform + Vault AWS AssumeRole 연동 (0) | 2023.04.24 |
Terraform Local -> Terraform Cloud로 마이그레이션 (0) | 2023.04.06 |
댓글