From c1ebc7726f441cd085b67a0934f09ac0452681ef Mon Sep 17 00:00:00 2001 From: "Michael S. Fischer" Date: Fri, 17 Jan 2020 22:44:50 -0600 Subject: [PATCH] Update AWS documentation Using EC2 Instance Roles to provide Route 53 permissions is overly permissive and dangerous. Emphasize using alternatives such as EKS IAM Roles for Service Accounts, kiam, or kube2iam that limit access to the ExternalDNS pod. --- docs/tutorials/aws.md | 111 +++++++++++++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index c4614b1bb..23cd0c77b 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -2,36 +2,86 @@ This tutorial describes how to setup ExternalDNS for usage within a Kubernetes cluster on AWS. Make sure to use **>=0.4** version of ExternalDNS for this tutorial -## IAM Permissions +## IAM Policy + +The following IAM Policy document allows ExternalDNS to update Route53 Resource +Record Sets and Hosted Zones. You'll want to create this Policy in IAM first. In +our example, we'll call the policy AllowExternalDNSUpdates (but you can call +it whatever you prefer). + +If you prefer, you may fine-tune the policy to permit updates only to explicit +Hosted Zone IDs. ```json { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "route53:ChangeResourceRecordSets" - ], - "Resource": [ - "arn:aws:route53:::hostedzone/*" - ] - }, - { - "Effect": "Allow", - "Action": [ - "route53:ListHostedZones", - "route53:ListResourceRecordSets" - ], - "Resource": [ - "*" - ] - } - ] + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "route53:ChangeResourceRecordSets" + ], + "Resource": [ + "arn:aws:route53:::hostedzone/*" + ] + }, + { + "Effect": "Allow", + "Action": [ + "route53:ListHostedZones", + "route53:ListResourceRecordSets" + ], + "Resource": [ + "*" + ] + } + ] } ``` -When running on AWS, you need to make sure that your nodes (on which External DNS runs) have the IAM instance profile with the above IAM role assigned (either directly or via something like [kube2iam](https://github.com/jtblin/kube2iam)). +## Create IAM Role + +You'll need to create an IAM Role that can be assumed by the ExternalDNS Pod. +Note the role name; you'll need to refer to it in the K8S manifest below. + +Attach the AllowExternalDNSUpdates IAM Policy (above) to the role. + +The trust relationship associated with the IAM Role will vary depending on how +you've configured your Kubernetes cluster: + +### Amazon EKS + +If your EKS-managed cluster is >= 1.13 and was created after 2019-09-04, refer +to the [Amazon EKS +documentation](https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html) +for instructions on how to create the IAM Role. Otherwise, you will need to use +kiam or kube2iam. + +### kiam + +If you're using [kiam](https://github.com/uswitch/kiam), follow the +[instructions](https://github.com/uswitch/kiam/blob/master/docs/IAM.md) for +creating the IAM role. + +### kube2iam + +If you're using [kube2iam](https://github.com/jtblin/kube2iam), follow the +instructions for creating the IAM Role. + +### EC2 Instance Role (not recommended) + +**:warning: WARNING: This will grant all pods on the node the ability to +manipulate Route 53 Resource Record Sets. If exploited by an attacker, this +could lead to a serious security and/or availability incident. For this reason, +it is not recommended.** + +Create an IAM Role for your EC2 instances as described in the [Amazon EC2 +documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html). +Then, attach the associated Instance Profile to the EC2 instances that comprise +your K8S cluster. + +For this method to work, you must permit your pods the ability to access the EC2 +instance metadata service (169.254.169.254). This is allowed by default. ## Set up a hosted zone @@ -84,6 +134,10 @@ spec: metadata: labels: app: external-dns + # If you're using kiam or kube2iam, specify the following annotation. + # Otherwise, you may safely omit it. + annotations: + iam.amazonaws.com/role: arn:aws:iam::ACCOUNT-ID:role/IAM-SERVICE-ROLE-NAME spec: containers: - name: external-dns @@ -106,6 +160,11 @@ apiVersion: v1 kind: ServiceAccount metadata: name: external-dns + # If you're using Amazon EKS with IAM Roles for Service Accounts, specify the following annotation. + # Otherwise, you may safely omit it. + annotations: + # Substitute your account ID and IAM service role name below. + eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT-ID:role/IAM-SERVICE-ROLE-NAME --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole @@ -152,6 +211,10 @@ spec: metadata: labels: app: external-dns + # If you're using kiam or kube2iam, specify the following annotation. + # Otherwise, you may safely omit it. + annotations: + iam.amazonaws.com/role: arn:aws:iam::ACCOUNT-ID:role/IAM-SERVICE-ROLE-NAME spec: serviceAccountName: external-dns containers: