anchor.diff:            "Resource": ["*"]
           }
         ]
  -----
   
   Update the cluster for changes to take effect:
   
  -----
  -kops update cluster ${CLUSTER_NAME} --yes
  -----
  +  kops update cluster ${CLUSTER_NAME} --yes
   
   In a similar fashion, policies may be applied to all masters by setting the `additionalPolicies.master` property as below:
   
  -----
     additionalPolicies:
       master: |
         [
  
positive.code: = Kubernetes Applying IAM Roles
  :toc:
  
  == Introduction
  
  Out of the box, Kubernetes supports 2 types of roles: a master IAM role and a node IAM role.
  
  In addition, the 3rd party plugin https://github.com/jtblin/kube2iam[kube2iam] can be configured to apply IAM roles at the pod level.
  
  This excerise will walk you through configuring both concepts.
  
  == IAM Master / Node Roles
  
  Out of the box, when deploying Kubernetes on AWS, master nodes require a number of EC2, ELB, ECR, Route53 and KMS policies applied, with worker nodes requiring a number of EC2, ECR and Route53 policies applied.  If using `kops` to install, these will be auotmatically configured for you (see https://github.com/kubernetes/kops/blob/master/docs/iam_roles.md[here] for a full list).
  
  These policies may be augmented via kops.  For example, to allow all nodes ElasticSearch access, perform the following steps:
  
  Edit your cluster via `kops edit cluster ${CLUSTER_NAME}` and add the following to the spec:
  
  ----
    additionalPolicies:
      node: |
        [
  
negative.code:           "Resource": ["*"]
          }
        ]
  
  . Update the cluster for changes to take effect:
  
    kops update cluster cluster.k8s.local --yes
  
  . Deploy kube2iam as a DaemonSet:
  +
      $ kubectl apply -f templates/kube2iam-ds.yaml
      daemonset "kube2iam" created
  +
  Note that the `kube2iam-ds.yaml` is assuming that your network configuration is based on `kubenet`, which is also the default kops configuration. If you have changed this as part of another exercise (e.g. switched to Calico) you will need to change the value of the `--host-interface` arg in the configuration file. For example, set to `cal+` if using Calico.
  
  === Configure IAM Role on a Pod
  
  We need the IAM Role ARN assigned to the worker nodes.  We will need this as part of creating pod roles.  We can obtain this by running the following command:
  
    kubectl get no \
      --selector=kubernetes.io/role==node \
      -o jsonpath='{.items[0].spec.externalID}' | \
      xargs aws ec2 describe-instances \
      --instance-id \
      --region us-east-1 \
      --query 'Reservations[*].Instances[*].IamInstanceProfile.Arn' | \
      sed -e 's/instance-profile/role/g'
  
  This command retrieves the AWS EC2 instance id (stored as `.spec.externalID`) of a worker node. It then uses the AWS CLI to query the ARN for the given EC2 instance id.
  
  It shows an output like:
  
    [
        [
            "arn:aws:iam::<account-id>:role/nodes.cluster.k8s.local"
        ]
    ]
  
  Note down the ARN from this output.
  
  Edit the `templates/pod-role-trust-policy.json` file, replace `{{NodeIamRoleARN}}` with the IAM Role ARN obtained from the previous step.
  
  We will first create a role with no permissions.  By configuring the Trusted Policy of the role, we are allowing kube2iam (via the worker node IAM Instance Profile Role) to assume the pod role.  Make note of the role ARN from the response:
  
    aws iam create-role \
      --role-name MyPodRole \
      --assume-role-policy-document \
      file://templates/pod-role-trust-policy.json
  
  It shows an output as:
  
    {
        "Role": {
            "AssumeRolePolicyDocument": {
                "Version": "2012-10-17", 
                "Statement": [
                    {
                        "Action": "sts:AssumeRole", 
                        "Principal": {
                            "Service": "ec2.amazonaws.com"
                        }, 
                        "Effect": "Allow", 
                        "Sid": ""
                    }, 
                    {
                        "Action": "sts:AssumeRole", 
                        "Principal": {
                            "AWS": "arn:aws:iam::<account-id>:role/nodes.cluster.k8s.local"
                        }, 
                        "Effect": "Allow", 
                        "Sid": ""
                    }
                ]
            }, 
            "RoleId": "AROAJANTQ2EP23B2BE2YQ", 
            "CreateDate": "2017-10-25T01:59:51.585Z", 
            "RoleName": "MyPodRole", 
            "Path": "/", 
            "Arn": "arn:aws:iam::<account-id>:role/MyPodRole"
        }
    }
  
  `iam.amazonaws.com/role` annotation on the pod is used to assign an IAM role to a pod. Let's set this annotation on our pod. The `templates/aws-cli-po.yaml` file looks like:
  
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli
      labels:
        name: aws-cli
      annotations:
        iam.amazonaws.com/role: MyPodRole
    spec:
      containers:
        - image: cgswong/aws:aws
          command:
            - "sleep"
            - "9999999"
          name: aws-cli
  
  Run the following command:
  
    $ kubectl create -f templates/aws-cli-po.yaml
    pod "aws-cli" created
  
  This will create a pod with the AWS CLI already installed, with the `MyPodRole` IAM role assigned.
  
  Log into the `aws-cli` pod that we have just deployed:
  
    $ kubectl exec -it aws-cli /bin/bash
    bash-4.3#
  
  We will use the AWS CLI to attempt to access S3.  Recall that the `MyPodRole` IAM role that we created has no permissions, therefore the following should fail:
  
    bash-4.3# aws s3 ls                                                                                                                              
  
    An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
  
  Exit the pod:
  
    bash-4.3# exit
    exit
    command terminated with exit code 255
  
  Terminate the pod:
  
    $ kubectl delete po aws-cli --force
    pod "aws-cli" deleted
  
  Let's update the role to grant S3 permissions:
  
    aws iam attach-role-policy --role-name MyPodRole --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
  
  Recreate the pod, log into it, then try to access S3 again.  We should now be authorized!
  
    $ kubectl create -f aws-cli-po.yaml
    $ kubectl exec -it aws-cli /bin/bash
    bash-4.3# aws s3 ls
  
  The output should show the list of S3 buckets.
  
  === Additional Notes
  
  