TerraformでAWS EKSを構築する
皆さん、こんにちは。技術開発グループのn-ozawanです。
連日の雨から一転、暑い日が続きますね。観測史上、5月の最高気温は39.5度で、北海道で記録されたそうです。
本題です。
AWSでKubernetesによるコンテナ環境を構築するには、EKSというサービスを利用します。今回はそのEKSをTerraformで構築して、Fargateで動作させるやり方をお話ししたいと思います。
目次
EKSの構築
EKS (Amazon Elastic Kubernetes Service) は、コンテナオーケストレーションであるKubernetesの実行環境です。コンテナの実行環境にはECS (Amazon Elastic Container Service) もありますが、その違いはコンテナのオーケストレーションをAWSで行うのか、Kubernetesで行うのかの差になります。
ロールの作成
初めにEKSに付与するロールを作成します。EKSを構築するには必ずロールを指定する必要があります。
# IAM Role
resource "aws_iam_role" "eks_cluster" {
name = "eks-role"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
# Policy
resource "aws_iam_role_policy_attachment" "eks_cluster_AmazonEKSClusterPolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_cluster.name
}
最初にIAMロールを作成します。ロールはAssumeRoleで、これはEKSが必要な時に、一時的に権限を付与してくれるロール、という意味です。詳細な説明は省きますが、assume_role_policy
の内容は、そのような意味だと思ってください。
次に、先ほど作成したロールにAmazonEKSClusterPolicyポリシーをアタッチしてあげています。これによりロールに権限がアタッチされたことになります。
以上でEKSの構築に必要なロールが出来ました。
EKSの構築
続いてEKSを構築しましょう。
variable "public_subnet_ids" {
description = "Public Subnet のID"
type = list(string)
}
resource "aws_eks_cluster" "main" {
name = "eks-cluster"
role_arn = aws_iam_role.eks_cluster.arn
vpc_config {
subnet_ids = var.public_subnet_ids # 2つ以上のSubnet IDを指定
}
depends_on = [
aws_iam_role_policy_attachment.eks_cluster_AmazonEKSClusterPolicy
]
}
name
はEKSクラスタの名前です。任意につけてOKです。role_arn
には先ほど作成したIAM ロールのARNを指定します。
vpc_config.subnet_ids
にはEKSクラスタを配置するPublic SubnetのIDを指定します。EKSは2つ以上のAZ (アベイラビリティーゾーン) を跨いで配置する必要があります。var.public_subnet_ids
の型はlist(string)
であり、2つ以上のSubnet IDを受け取る文字列型の配列です。
depends_on
には、ロールにポリシーをアタッチしたらEKSを構築するように指定しています。Terraformに限らず構築する順番は大事ですよね。これにより、ポリシーがアタッチされていないロールでEKSを構築する、という状況を無くします。
Fargate
KubernetesのPodをFargateで動かせるようにします。Fargateはいわゆるサーバーレスで、KubernetesのPodが起動するタイミングで、AWSが自動的に仮想環境を充ててくれます。これにより事前にEC2インスタンスなどの仮想環境を用意する必要がなくなります。
EKSでFargateを有効にするには、Fargate Profileというリソースを作成します。このFargate ProfileにもIAMロールを作成する必要があります。
# Role
resource "aws_iam_role" "eks-fargate-profile" {
name = "fargate-profile-role"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks-fargate-pods.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
# Policy
resource "aws_iam_role_policy_attachment" "eks_cluster_AmazonEKSFargatePodExecutionRolePolicy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy"
role = aws_iam_role.eks-fargate-profile.name
}
# variable
variable "private_subnet_ids" {
description = "Private Subnet のID"
type = list(string)
}
# Fargate Profile
resource "aws_eks_fargate_profile" "main" {
cluster_name = aws_eks_cluster.main.name
fargate_profile_name = "main"
pod_execution_role_arn = aws_iam_role.eks-fargate-profile.arn
subnet_ids = var.private_subnet_ids
selector {
namespace = "default"
}
depends_on = [
aws_iam_role_policy_attachment.eks_cluster_AmazonEKSFargatePodExecutionRolePolicy,
]
}
IAMロールとポリシーのついては先ほどとほぼ同じなので説明は省きます。
aws_eks_fargate_profile
のcluster_name
には、Fargate Profileを適用するEKSクラスタの名前を指定します。上記の例では先ほど作成したEKSクラスタの名前を指定しています。fargate_profile_name
にはFargate Profileの名前を、pod_execution_role_arn
には作成したロールのARNを指定します。
subnet_ids
にはFargateが動作するPrivate SubnetのIDを指定します。var.private_subnet_ids
の型はlist(string)
であり、2つ以上のSubnet IDを受け取る文字列型の配列です。
selector.namespace
にはFargateで動作させるPODを指定します。上記の例ではKubernetesのnamespaceで、defaultに属しているPODは、すべてFargateで動作することを示しています。
おわりに
今日はTerraformでEKSを構築する場合のお話をしました。実はこれだけではまだ足りません。実際に構築してみると、AWSのコンソール画面からは、EKSクラスタは構築されていることが確認できるものの、その中身が見れない状態になっています。それはEKSクラスタ自身が、AWSにログインしているユーザー(rootユーザーも含む)に対して参照を許していないからです。
次回はその辺の解決方法をお話ししたいと思います。ではまた。