IAM Roles for Service Accounts を Terraformで手軽に体験してみる
2019年 9月 4日、EKSにIAM Roles for Service Accounts
の機能が追加されました!
このアップデートにより、Kubernetesのサービスアカウントと、AWSのIAMを紐付けて運用することができるようになりました。
これまでと現在
今までは Pod に対して AWS リソースに対するアクセス権限を割り当てたい場合、 Node に IAM ロールを割り当てるしかありませんでした。 この方法を使うと、Node で動く Pod に対してすべての権限が振ってくるのでセキュリティ上問題がありました。
しかし今回のアップデートで Pod に対して IAM ロールを割り当てることが可能になりました。
IAM Role for Podsを用いることで、必要なPodに必要なだけの権限を付与することができるため、最小権限の原則を守ることができます。
手軽に体験する
この記事は、Introducing Fine-Grained IAM Roles for Service Accounts に基づいています。
元記事ではeksctl
を用いてクラスタやIAMの作成を行っているのですが今回はTerraformを用いて環境を構築します。
Terraformを用いて構築することでGitHubなどにインフラの構成を残しておくことができます。
今回使用するコードはGitHubにあるため、適宜参照してください。
IAM Roles for Service Accounts をやるための準備
今回は、以下のバージョンで行いました。 - Terraform v0.12.9
以下の流れに沿って解説をします。
EKSのクラスタを作成する
EKS の OpenID Connect Provider URL を用いて OIDC プロバイダーを作成する
OIDC プロバイダーを利用する IAM ロールをつくる
Kubernetes サービスアカウントを作成する
S3のbucketをつくる
EKSのクラスタを作成する
今回、terraform-aws-modules/eks/aws
というmoduleを使用しています。
module "next-cluster" { source = "terraform-aws-modules/eks/aws" #https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/6.0.0 version = "6.0.0" cluster_name = "${local.cluster_name}" cluster_version = "${local.cluster_version}" cluster_endpoint_private_access = true manage_aws_auth = false subnets = "${module.vpc.public_subnets}" vpc_id = "${module.vpc.vpc_id}" worker_groups = [] write_aws_auth_config = false write_kubeconfig = false tags = "${local.tags}" }
EKS の OpenID Connect Provider URL を用いて OIDC プロバイダーを作成する
resource "aws_iam_openid_connect_provider" "oidc_provider" { client_id_list = ["sts.amazonaws.com"] thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"] # CA thumbprint url = "${module.next-cluster.cluster_oidc_issuer_url}" }
先ほど作成したEKSのoidc_issuer_url
を用いて、 ODIC プロバイダーを作成します。
OIDC プロバイダーを利用する IAM ロールをつくる
1. KMS にアクセスできる IAM policy をつくる
resource "aws_iam_policy" "s3" { name = "s3_read_only" policy = "${data.aws_iam_policy_document.s3.json}" } data "aws_iam_policy_document" "s3" { statement { effect = "Allow" resources = ["*"] actions = [ "s3:*", ] } }
2. IAM Role for Service Accounts に利用する IAM Roleをつくる
resource "aws_iam_role" "s3_service_account" { assume_role_policy = "${data.aws_iam_policy_document.s3_service_account.json}" } data "aws_iam_policy_document" "s3_service_account" { statement { effect = "Allow" actions = [ "sts:AssumeRoleWithWebIdentity" ] principals { type = "Federated" identifiers = ["${aws_iam_openid_connect_provider.oidc_provider.arn}"] } condition { test = "StringEquals" variable = "${replace(aws_iam_openid_connect_provider.oidc_provider.url, "https://", "")}:sub" values = [ "system:serviceaccount:default:vault-unseal" ] } } }
3. IAM Role と IAM Policyを紐付ける
resource "aws_iam_role_policy" "s3_service_account" { policy = "${data.aws_iam_policy_document.s3.json}" role = "${aws_iam_role.s3_service_account.name}" }
Kubernetes サービスアカウントをつくる
terraform apply
すると、3つファイルが出てきます。
aws-auth
kubeconfig
s3_serviceaccount
kubeconfigを用いて、aws-auth
とs3_serviceaccount
をapplyしてください。
S3のbucketをつくる
resource "aws_s3_bucket" "bucket" { bucket = "terraform-bucket-test-hello-hello" acl = "private" tags = { Name = "My bucket" Environment = "Dev" } }
bucketの名前は世界でユニークなので変更しておいてください。
これで準備は完了です。
s3へファイルを保存してみる
https://github.com/mhausenblas/s3-echoer をもちいて、IAM Roles for Service Accounts ができているかテストします。
git clone https://github.com/mhausenblas/s3-echoer.git && cd s3-echoer
s3-echoer-job.yaml.template
をコピーして、s3-echoer-job.yaml
とし、
serviceAccountName
, TARGET_BUDGET
, DEFAULT_AWS_REGION
, をそれぞれ変更します。
変更したあと、kubectl apply -f s3-echoer-job.yaml
でS3に保存するJobが走ります。
ここで、S3を確認してファイルが保存されていることを確認しましょう。
おわりに
今回、 IAM Roles for Service Accounts をeksctl
ではなくTerraform
を用いて実現する方法について紹介しました。
この記事は、HERPでインターンをしているときの成果です。
株式会社HERPは、先日資金調達をしたり、京都と筑波に開発拠点が増えたりと今ノリに乗っている会社だと思います。 また、プロダクトの方もTypeScript + Haskell と面白い技術スタックなので興味ある方はぜひ!
参考
Introducing Fine-Grained IAM Roles for Service Accounts [アップデート] EKSでIAMロールを使ったPod単位のアクセス制御が可能になりました!