この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
今回はTerraform Registryにある以下Published Moduleを使ってEKSクラスターを作成したいと思います。
Terraformとprovidersの設定
terraform {
required_version = "= 0.14.7"
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.30.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
Terraform version 0.13以降の書き方ですね。
VPC作成
eksctlはクラスターを稼働させるVPCまで併せて作成してくれました。が、このeksモジュールはそこまではやってくれず、引数で既存VPCの情報を渡す必要があるようです。というわけで先にVPCを作成します。
以下のTerraform RegistryにあるVPCのPublished Moduleを利用します。
vpc.tf
data "aws_availability_zones" "available" {
state = "available"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "2.77.0"
name = "eks-module-test-vpc"
cidr = "10.0.0.0/16"
azs = data.aws_availability_zones.available.names
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
}
以下リソースが作成されます。
$ terraform state list
module.vpc.aws_eip.nat[0]
module.vpc.aws_eip.nat[1]
module.vpc.aws_eip.nat[2]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_nat_gateway.this[0]
module.vpc.aws_nat_gateway.this[1]
module.vpc.aws_nat_gateway.this[2]
module.vpc.aws_route.private_nat_gateway[0]
module.vpc.aws_route.private_nat_gateway[1]
module.vpc.aws_route.private_nat_gateway[2]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.private[1]
module.vpc.aws_route_table.private[2]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.private[2]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_route_table_association.public[2]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.private[2]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_subnet.public[2]
module.vpc.aws_vpc.this[0]
Local Moduleを作る
後の検証で使いたいので、EKSクラスターを作成する部分はChild Module化します。そのModuleの中で前述のEKSのPublished Moduleを使いたいと思います。
$ tree
.
(略)
├── modules
│ └── k8s_cluster
│ ├── eks.tf
│ ├── providers.tf
│ ├── target_group.tf
│ └── variables.tf
(略)
providers
modules/k8s_cluster/providers.tf
provider "kubernetes" {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority.0.data)
exec {
api_version = "client.authentication.k8s.io/v1alpha1"
command = "aws"
args = [
"eks",
"get-token",
"--cluster-name",
data.aws_eks_cluster.cluster.name
]
}
}
data "aws_eks_cluster" "cluster" {
name = module.main.cluster_id
}
EKS published moduleが必要とするprividerには、kubernetes providerも含まれます。作成したEKSクラスター内にaws-auth ConfigMapリソースを作成する際に使われます。EKSクラスターへの接続情報が必要ですので、その情報をkuberetes providerのブロックに記述しています。記述内容は以下を参考にしました。
variables
modules/k8s_cluster/variables.tf
variable "cluster_name" {
type = string
}
variable "k8s_version" {
type = string
}
variable "vpc_id" {
type = string
}
variable "subnet_ids" {
type = list(string)
}
eks
modules/k8s_cluster/eks.tf
module "main" {
source = "terraform-aws-modules/eks/aws"
version = "14.0.0"
cluster_name = var.cluster_name
cluster_version = var.k8s_version
subnets = var.subnet_ids
vpc_id = var.vpc_id
worker_groups = [{
root_volume_type = "gp2"
target_group_arns = [aws_alb_target_group.tg.arn]
}]
}
- workerのroot volume typeのデフォルト値はgp3です。以下エラーが出たためgp2に変更しています。
Worker Node GroupのAutoScaling Groupはこの書き方だと起動設定から作成されるのですが、どうやら起動設定だと現在root_volume_typeにgp3を指定することができないようです。
Error: Error creating launch configuration: ValidationError: gp3 is invalid. Valid volume types are standard, io1, gp2, st1 and sc1.
- Worker Node GroupのAutoScaling Groupに紐づくTarget Groupを指定しています。こちらは今後の検証で利用する予定です。
target group
前述のとおりWorker Node GroupのAutoScaling Groupに紐づくTarget Groupです。
modules/k8s_cluster/target_group.tf
resource "aws_alb_target_group" "tg" {
name = "${var.cluster_name}-tg"
port = 30080
protocol = "HTTP"
vpc_id = var.vpc_id
}
確認
ここまでのコードの状態でterraform init
してterraform apply
します。
以下リソースが作成できました。
$ terraform state list
data.aws_availability_zones.available
module.blue.data.aws_eks_cluster.cluster
module.blue.aws_alb_target_group.tg
module.vpc.aws_eip.nat[0]
module.vpc.aws_eip.nat[1]
module.vpc.aws_eip.nat[2]
module.vpc.aws_internet_gateway.this[0]
module.vpc.aws_nat_gateway.this[0]
module.vpc.aws_nat_gateway.this[1]
module.vpc.aws_nat_gateway.this[2]
module.vpc.aws_route.private_nat_gateway[0]
module.vpc.aws_route.private_nat_gateway[1]
module.vpc.aws_route.private_nat_gateway[2]
module.vpc.aws_route.public_internet_gateway[0]
module.vpc.aws_route_table.private[0]
module.vpc.aws_route_table.private[1]
module.vpc.aws_route_table.private[2]
module.vpc.aws_route_table.public[0]
module.vpc.aws_route_table_association.private[0]
module.vpc.aws_route_table_association.private[1]
module.vpc.aws_route_table_association.private[2]
module.vpc.aws_route_table_association.public[0]
module.vpc.aws_route_table_association.public[1]
module.vpc.aws_route_table_association.public[2]
module.vpc.aws_subnet.private[0]
module.vpc.aws_subnet.private[1]
module.vpc.aws_subnet.private[2]
module.vpc.aws_subnet.public[0]
module.vpc.aws_subnet.public[1]
module.vpc.aws_subnet.public[2]
module.vpc.aws_vpc.this[0]
module.blue.module.main.data.aws_ami.eks_worker
module.blue.module.main.data.aws_ami.eks_worker_windows
module.blue.module.main.data.aws_caller_identity.current
module.blue.module.main.data.aws_iam_policy_document.cluster_assume_role_policy
module.blue.module.main.data.aws_iam_policy_document.cluster_elb_sl_role_creation[0]
module.blue.module.main.data.aws_iam_policy_document.workers_assume_role_policy
module.blue.module.main.data.aws_partition.current
module.blue.module.main.data.template_file.userdata[0]
module.blue.module.main.aws_autoscaling_group.workers[0]
module.blue.module.main.aws_eks_cluster.this[0]
module.blue.module.main.aws_iam_instance_profile.workers[0]
module.blue.module.main.aws_iam_policy.cluster_elb_sl_role_creation[0]
module.blue.module.main.aws_iam_role.cluster[0]
module.blue.module.main.aws_iam_role.workers[0]
module.blue.module.main.aws_iam_role_policy_attachment.cluster_AmazonEKSClusterPolicy[0]
module.blue.module.main.aws_iam_role_policy_attachment.cluster_AmazonEKSServicePolicy[0]
module.blue.module.main.aws_iam_role_policy_attachment.cluster_AmazonEKSVPCResourceControllerPolicy[0]
module.blue.module.main.aws_iam_role_policy_attachment.cluster_elb_sl_role_creation[0]
module.blue.module.main.aws_iam_role_policy_attachment.workers_AmazonEC2ContainerRegistryReadOnly[0]
module.blue.module.main.aws_iam_role_policy_attachment.workers_AmazonEKSWorkerNodePolicy[0]
module.blue.module.main.aws_iam_role_policy_attachment.workers_AmazonEKS_CNI_Policy[0]
module.blue.module.main.aws_launch_configuration.workers[0]
module.blue.module.main.aws_security_group.cluster[0]
module.blue.module.main.aws_security_group.workers[0]
module.blue.module.main.aws_security_group_rule.cluster_egress_internet[0]
module.blue.module.main.aws_security_group_rule.cluster_https_worker_ingress[0]
module.blue.module.main.aws_security_group_rule.workers_egress_internet[0]
module.blue.module.main.aws_security_group_rule.workers_ingress_cluster[0]
module.blue.module.main.aws_security_group_rule.workers_ingress_cluster_https[0]
module.blue.module.main.aws_security_group_rule.workers_ingress_self[0]
module.blue.module.main.kubernetes_config_map.aws_auth[0]
module.blue.module.main.local_file.kubeconfig[0]
module.blue.module.main.null_resource.wait_for_cluster[0]
module.blue.module.main.random_pet.workers[0]
クラスター内リソースも確認します。
このモジュールは引数write_kubeconfig
をtrue(デフォルト値)にすればコンテキストファイルを作成してくれますが、ちょっと扱いづらいので、別途AWS CLIを使って書きます。
$ aws eks update-kubeconfig --name blue-with-module
Updated context arn:aws:eks:ap-northeast-1:123456789012:cluster/blue-with-module in /Users/kazue.masaki/.kube/config
$ kubectl config use-context arn:aws:eks:ap-northeast-1:123456789012:cluster/blue-with-module
Switched to context "arn:aws:eks:ap-northeast-1:123456789012:cluster/blue-with-module".
クラスター内リソースも確認できました。
$ kubectl get all -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/aws-node-54h7s 1/1 Running 0 30h
kube-system pod/coredns-59847d77c8-n9gb6 1/1 Running 0 30h
kube-system pod/coredns-59847d77c8-p6dzd 1/1 Running 0 30h
kube-system pod/kube-proxy-xdrmg 1/1 Running 0 30h
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 30h
kube-system service/kube-dns ClusterIP 172.20.0.10 <none> 53/UDP,53/TCP 30h
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/aws-node 1 1 1 1 1 <none> 30h
kube-system daemonset.apps/kube-proxy 1 1 1 1 1 <none> 30h
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/coredns 2/2 2 2 30h
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/coredns-59847d77c8 2 2 2 30h
起動設定→起動テンプレート
前述のとおり、Worker Node GroupのAutoScaling Groupは起動設定から作成されました。これを起動テンプレートからに変えたいと思います。やり方は簡単で、worker_groups
をworker_groups_launch_template
に変えるだけです。
module "main" {
source = "terraform-aws-modules/eks/aws"
version = "14.0.0"
cluster_name = var.cluster_name
cluster_version = var.k8s_version
subnets = var.subnet_ids
vpc_id = var.vpc_id
- worker_groups = [{
+ worker_groups_launch_template = [{
root_volume_type = "gp2"
target_group_arns = [aws_alb_target_group.tg.arn]
}]
}
起動テンプレートだとroot_volume_typeにgp3を使うこともできます。
module "main" {
source = "terraform-aws-modules/eks/aws"
version = "14.0.0"
cluster_name = var.cluster_name
cluster_version = var.k8s_version
subnets = var.subnet_ids
vpc_id = var.vpc_id
worker_groups_launch_template = [{
- root_volume_type = "gp2" # デフォルトのgp3を使う
target_group_arns = [aws_alb_target_group.tg.arn]
}]
}
セルフマネージド型ノード → マネージド型ノードグループ
worker_groups
及びworker_groups_launch_template
はセルフマネージド型ノードのプロビジョニングに使われるものでした。今回は特にセルフマネージド型ノードにする必要性がなかったので、マネージド型ノードグループに変更します。
node_groups
引数を使います。使い方詳細は以下ページにあります。
modules/k8s_cluster/eks.tf
module "main" {
source = "terraform-aws-modules/eks/aws"
version = "14.0.0"
cluster_name = var.cluster_name
cluster_version = var.k8s_version
subnets = var.subnet_ids
vpc_id = var.vpc_id
- worker_groups_launch_template = [{
- target_group_arns = [aws_alb_target_group.tg.arn]
- }]
+ node_groups = {
+ example = {
+ target_group_arns = [aws_alb_target_group.tg.arn]
+ subnets = var.private_subnet_ids
+ }
+ }
}
modules/k8s_cluster/variables.tf
variable "cluster_name" {
type = string
}
variable "k8s_version" {
type = string
}
variable "vpc_id" {
type = string
}
variable "subnet_ids" {
type = list(string)
}
+variable "private_subnet_ids" {
+ type = list(string)
+}
vpc.tf
module "blue" {
source = "./modules/k8s_cluster"
cluster_name = "blue-with-module"
k8s_version = "1.19"
subnet_ids = concat(module.vpc.private_subnets, module.vpc.public_subnets)
+ private_subnet_ids = module.vpc.private_subnets
vpc_id = module.vpc.vpc_id
}