首页 > 解决方案 > How do I add a policy the role that EC2 instances assume in an EKS cluster?

问题描述

I'm using Terraform to create an EKS cluster. The worker nodes have an IAM role defined as follows:

resource "aws_iam_role" "eks-node" {
  name = "${local.resource_prefix}-eks-node"

  assume_role_policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
POLICY
}

resource "aws_iam_role_policy_attachment" "eks-node-AmazonEKSWorkerNodePolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = "${aws_iam_role.eks-node.name}"
}

resource "aws_iam_role_policy_attachment" "eks-node-AmazonEKS_CNI_Policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = "${aws_iam_role.eks-node.name}"
}

resource "aws_iam_role_policy_attachment" "eks-node-AmazonEC2ContainerRegistryReadOnly" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = "${aws_iam_role.eks-node.name}"
}

resource "aws_iam_instance_profile" "eks-node" {
  name = "${local.resource_prefix}-eks-node"
  role = "${aws_iam_role.eks-node.name}"
}

This all spins up fine, and I can launch containers into the cluster. Now I want to try and play with allowing the containers to access AWS SSM in order to retrieve sensitive information (like a DB password). I did a quick test by launching a simple alpine instance into the cluster, installing the AWS CLI and running

aws ssm get-parameters --name /tmp/test-001 --region ...

(the /tmp/test-001 parameter does exist in the same region). This spits back a predictable error of:

An error occurred (AccessDeniedException) when calling the GetParameters operation: User: arn:aws:sts::(account-id):assumed-role/(resource-prefix)-eks-node/i-(EC2-instance-id) is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:(region):(account-id):parameter/tmp/test-001

That's good actually - I want this to be rejected until I give that user permission. However note that the user is assumed-role/(resource-prefix)-eks-node/i-(EC2-instance-id) and not simply assumed-role/(resource-prefix)-eks-node - I suspect that has something to do with my actual problem...

So I head back to Terraform and add in the following Policy to the worker nodes:

resource "aws_iam_role_policy" "eks_node_allow_ssm_access" {
  name = "${local.resource_prefix}-eks-node-ssm-access"
  role = "${aws_iam_role.eks-node.name}"

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "ssm:GetParameters"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:ssm:${local.aws_region}:${data.aws_caller_identity.current.account_id}:parameter/tmp/test-001"
    }
  ]
}
EOF
}

This generates what I would expect - an inline Policy on arn:aws:iam::(account-id):role/(resource-prefix)-eks-node that allows acccess to ssm:GetParameters. However when I re-launch the container and try again, I still get the AccessDeniedException error.

I suspect it has something to do with the assumed-role being for (prefix)-eks-node/i-0...............e instead of what the role Terraform creates actually is (prefix)-eks-node. But since that EC2 instance is dynamically created with auto-scaling, I have no idea how I would target that with a policy...

All that brings me back to the question... How do I allow the assumed user role of the EC2 instance in the EKS worker nodes access to another resource (in this case SSM)?

标签: amazon-iamamazon-eks

解决方案


推荐阅读