In the last section, you learned about connecting to your servers using SSH and VPN. In this section,
you'll learn about connecting to your AWS accounts:
All of your AWS resources are deployed into a single account. This makes it easy to manage everything.
In the future, you may want to consider putting each environment (e.g., stage, prod, etc) into a separate AWS account.
This gives you more fine grained control over who can access what and improves isolation and security, as a mistake or
breach in one account is unlikely to affect the others. The downside is overhead: it takes more time to set up multiple
accounts and more time to switch between them during day-to-day work. If you need help with multi-account setup, email
support@gruntwork.io.
Authenticating
Some best practices around authenticating to your AWS account:
Always enable multi-factor authentication (MFA) for your AWS account. That is, in addition to a password, you must
provide a second factor to prove your identity. The best option for AWS is to install Google
Authenticator on your phone and use it to generate a one-time
token as your second factor.
Use a password manager
Never store secrets in plain text. Store your secrets using a secure password manager, such as
pass, OS X Keychain, or
KeePass. You can also use cloud-based password managers, such as
1Password or LastPass, but be aware that since they have
everyone's passwords, they are inherently much more tempting targets for attackers. That said, any reasonable password
manager is better than none at all!
Don't use the root user
AWS uses the Identity and Access Management (IAM) service to manage users and their
permissions. When you first sign up for an AWS account, you are logged in as the root user. This user has permissions
to do everything in the account, so if you compromise these credentials, you’re in deep trouble.
Therefore, right after signing up, you should:
Enable MFA on your root account. Note: we strongly recommend making a copy of the MFA secret key. This way, if you
lose your MFA device (e.g. your iPhone), you don’t lose access to your AWS account. To make the backup, when
activating MFA, AWS will show you a QR code. Click the "show secret key for manual configuration" link and save that
key to a secure password manager.
Make sure you use a very long and secure password. Never share that password with anyone. If you need to store it
(as opposed to memorizing it), only store it in a secure password manager.
Use the root account to create a separate IAM user for yourself and your team members with more limited IAM
permissions. You should manage permissions using IAM groups. See the iam-groups
module for details.
Use IAM roles when you need to give limited permissions to tools (for eg, CI servers or EC2 instances).
Require all IAM users in your account to use MFA.
Never use the root IAM account again.
Kubernetes RBAC Roles and Helm Authentication
Up to this point we focused on accounts and authentication in AWS. However, with EKS, Kubernetes adds another layer of
accounts and authentication that are tied to, but not exactly the same as, AWS IAM.
In this section, you'll learn about Kubernetes RBAC roles and Helm authentication:
Role Based Access Control (RBAC) is a method to regulate
access to resources based on the role that individual users assume in an organization. Kubernetes allows you to define
roles in the system that individual users inherit, and explicitly grant permissions to resources within the system to
those roles. The Control Plane will then honor those permissions when accessing the resources on Kubernetes through
clients such as kubectl. When combined with namespaces, you can implement sophisticated control schemes that limit the
access of resources across the roles in your organization.
The RBAC system is managed using ClusterRole and ClusterRoleBinding resources (or Role and RoleBinding resources
if restricting to a single namespace). The ClusterRole (or Role) object defines a role in the Kubernetes system that
has explicit permissions on what it can and cannot do. These roles are then bound to users and groups using the
ClusterRoleBinding (or RoleBinding) resource. An important thing to note here is that you do not explicitly create
users and groups using RBAC, and instead rely on the authentication system to implicitly create these entities.
EKS manages authentication to Kubernetes based on AWS IAM roles and users. This is done by embedding AWS IAM credentials
(the access key and secret key) into the authentication token used to authenticate to the Kubernetes API. The API server
then forwards this to AWS to validate it, and then reconciles the role / user into an RBAC user and group that is then
used to reconcile authorization rules for the API.
By default all IAM roles and users (except for the role / user that deployed the cluster) has no RBAC user or groups
associated with it. This automatically translates the role / user into an anonymous user on the cluster, who by default
has no permissions. In order to allow access to the cluster, you need to explicitly bind the IAM role / user to an RBAC
entity, and then bind Roles or ClusterRoles that explicitly grants permissions to perform actions on the cluster.
This mapping is handled by the eks-k8s-role-mapping
module, used under the hood
in the eks-cluster infrastructure module.
You can read more about the relationship between IAM roles and RBAC roles in EKS in the official
documentation.
Namespaces and RBAC
Namespaces are Kubernetes resources
that creates virtual partition boundaries in your cluster. The resources in each Namespace are isolated from other
Namespaces, and can only interact with them through Service endpoints, unless explicit permissions are granted. This
allows you to divide the cluster between multiple users in a way that prevents them from seeing each others' resources,
allowing you to share clusters while protecting sensitive information.
RBAC is critical in achieving isolation of Namespaces. The RBAC permissions can be restricted by Namespace. This
allows you to bind permissions to entities such that they can only perform certain actions on resources within a
particular Namespace.
Every EKS cluster comes with two default Namespaces:
kube-system: This Namespace holds admin and cluster level resources. Only cluster administrators ("superusers")
should have access to this Namespace.
default: This is the default Namespace that is used for API calls that don't specify a particular Namespace.
This should primarily be used for development and experimentation purposes.
Additionally, in the Reference Architecture, we create another Namespace: applications. This Namespace is used to
house the deployed sample applications and its associated resources.
Most Kubernetes tools will let you set the Namespace as CLI args. For example, kubectl supports a -n parameter for
specifying which Namespace you intend to run the command against. kubectl additionally supports overriding the
default Namespace for your commands by binding a Namespace to your authentication context.
Accessing the cluster
As mentioned in Relation to IAM Roles, EKS proxies Kubernetes authentication through AWS IAM
credentials. This means that you need to be authenticated to AWS first in order to authenticate to Kubernetes. Refer to
the previous section on AWS authentication for information on how to authenticate to AWS.
There are three main ways to interact with Kubernetes in the Reference Architecture:
When deploying Kubernetes resources using Terragrunt / Terraform, all the authentication is handled inside of Terraform
using a combination of EKS data sources and provider logic. What this means is that you don't have to worry about
explicitly authenticating to Kubernetes when going through Terraform, as long as you are authenticating to an IAM role
that has a valid mapping to an RBAC entity in the cluster.
The one exception to this is the modules that depend on helm, which requires additional configuration. See the
section on helm for more info.
Kubectl
Most manual operations in Kubernetes are handled through the kubectl command line
utility. kubectl requires an explicit authentication
configuration to access the cluster.
You can use kubergrunt to configure your local kubectl client to authenticate against a deployed EKS cluster. After
authenticating to AWS, run:
This will add a new entry to your kubectl config file (defaults to $HOME/.kube/config) with the logic for
authenticating to EKS, registering it under the context name $EKS_CLUSTER_ARN. You can modify the name of the context
using the --kubectl-context-name CLI arg.
You can verify the setup by running:
kubectl cluster-info
This will report information about the Kubernetes endpoints for the cluster only if you are authorized to access to the
cluster. Note that you will need to be authenticated to AWS for kubectl to successfully authenticate to the cluster.
If you have multiple clusters, you can switch the kubectl context using the use command. For example, to switch the
current context to the dev EKS cluster from the prod cluster and back:
kubectl use arn:aws:eks:us-east-1:$DEV_ACCOUNT_ID:cluster/eks-dev
kubectl cluster-info # Should target the dev EKS cluster
kubectl use arn:aws:eks:us-east-1:$PROD_ACCOUNT_ID:cluster/eks-prod
kubectl cluster-info # Should target the prod EKS cluster
Helm
Helm relies on TLS based authentication and authorization to access Tiller (the Helm Server). This is separate from the
RBAC based authorization native to Kubernetes. Intuitively, RBAC is used to manage whether or not someone can lookup the
Pod endpoint address, while the TLS authentication and authorization scheme manages whether or not you can establish a
connection to the Tiller server. All deployments of Tiller in the Reference Architecture uses kubergrunt to manage the
TLS certificates.
We highly recommend reading Gruntwork's guide to
helm to understand the security model surrounding
Helm and Tiller.
kubergrunt manages the TLS certificates using Kubernetes Secrets, guarded by RBAC roles. A cluster administrator can
grant access to any RBAC entity to any Tiller deployment using the kubergrunt helm grant command. For example, to
grant access to a Tiller server deployed in the namespace applications-tiller to the RBAC user
allow-full-access-from-other-accounts:
Note on RBAC users: The RBAC user username (--rbac-user) corresponds to the IAM Role or User name of the
authenticating AWS credentials.
This generates new TLS certificate key pairs that grant access to the Tiller deployed in the applications-tiller
Namespace. In addition, this creates and binds RBAC roles that allow users of the RBAC group developers to be able to
read the necessary Secrets to download the generated TLS certificate key pairs.
Now anyone who maps to the developers RBAC group can use the kubergrunt helm configure command to setup their
helm client to access the deployed Tiller:
Download the client TLS certificate key pair generated with the grant command.
Install the TLS certificate key pair in the helm home directory (defaults to $HOME/.helm).
Install an environment file that sets up environment variables to target the specific helm server (defaults to
$HELM_HOME/env). This environment file needs to be loaded before issuing any commands, at it sets the necessary
environment variables to signal to the helm client which helm server to use. The environment variables it sets are:
HELM_HOME: The helm client home directory where the TLS certs are located.
TILLER_NAMESPACE: The namespace where the helm server is installed.
HELM_TLS_VERIFY: This will be set to true to enable TLS verification.
HELM_TLS_ENABLE: This will be set to true to enable TLS authentication.
Once this is setup, Terraform modules that need to access helm will be able to use the downloaded credentials to
authenticate to Tiller. Additionally, once you source the environment file, you will be able to use the helm client to
directly work with Tiller.
If you have the helm client installed, you can verify your configuration setup using the helm version command:
helm version
If your helm client is configured correctly, the version command will output information about the deployed Tiller
instance that it connected to.
Next steps
Now that you know how to authenticate, you may want to take a look through this list of Gruntwork
Tools.
Questions? Ask away.
We're here to talk about our services, answer any questions, give advice, or just to chat.
{"treedata":{"name":"root","toggled":true,"children":[{"name":".gitignore","path":".gitignore","sha":"1c27fc6013cba46cd301a7c8bf951694670153a3"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"6bddb3ff6e1b3dfaba7cf180e56bca12c245be56"},{"name":"README.md","path":"README.md","sha":"74507349a9d5cd784540410365adc61ba68000f1"},{"name":"_docs","children":[{"name":"01-architecture-overview.md","path":"_docs/01-architecture-overview.md","sha":"fa091294c3f4cfb2e7bd1d7df78907faf076996b"},{"name":"02-whats-deployed.md","path":"_docs/02-whats-deployed.md","sha":"8bf4519132e2ea43cbcf1e1d67eff3f961471af2"},{"name":"03-security-compliance-compatibility.md","path":"_docs/03-security-compliance-compatibility.md","sha":"9342617f42adb28e440cc2161f3fee56205c150e"},{"name":"04-how-code-is-organized.md","path":"_docs/04-how-code-is-organized.md","sha":"64b9396f54fb0b791d39b93919a6416ab8215f0d"},{"name":"05-dev-environment.md","path":"_docs/05-dev-environment.md","sha":"9209da466b0f9afee5e1afb36f01a2ba8149012f"},{"name":"06-ci-cd.md","path":"_docs/06-ci-cd.md","sha":"0685cbe746fa0271357db34ebd39d76397ea19c4"},{"name":"07-monitoring-alerting-logging.md","path":"_docs/07-monitoring-alerting-logging.md","sha":"619c810c6e60418b3a46fa3d903bc76dc6d48e41"},{"name":"08-ssh-vpn.md","path":"_docs/08-ssh-vpn.md","sha":"0f526549f4b0d08cf2a914def239f8ff872ec2d1"},{"name":"09-accounts-and-auth.md","path":"_docs/09-accounts-and-auth.md","sha":"9e6d2c1f8b9a7cc7c5b3ce3386eea22daac6cc17","toggled":true},{"name":"10-gruntwork-tools.md","path":"_docs/10-gruntwork-tools.md","sha":"d08b1fe7cfbb9ad91155bfff9e3a05525c39c127"},{"name":"11-deploying-a-docker-service.md","path":"_docs/11-deploying-a-docker-service.md","sha":"d2123b688287557c1c38cd415a729b3a445a45ad"},{"name":"12-migration.md","path":"_docs/12-migration.md","sha":"6e46bf752f330de978a8927858a716f04db13f60"},{"name":"13-deploying-the-reference-architecture-from-scratch.md","path":"_docs/13-deploying-the-reference-architecture-from-scratch.md","sha":"9eb702bb6da48a97b2c9eead594a3474a1ee6703"},{"name":"14-undeploying-the-reference-architecture.md","path":"_docs/14-undeploying-the-reference-architecture.md","sha":"3ed0569cdd0e3d32079ab537e1697fbcb3ee27d8"},{"name":"15-adding-new-environments-regions-and-accounts.md","path":"_docs/15-adding-new-environments-regions-and-accounts.md","sha":"6a0372a843a9245570379e1beaad452e67d234c3"},{"name":"README.md","path":"_docs/README.md","sha":"785d2b0b36b10e75c96e4eaa7414c1c71d78e222"},{"name":"_images","children":[{"name":"cw-logs-1.png","path":"_docs/_images/cw-logs-1.png","sha":"84c86f014751844fbd777b5139ed61f749b5ed32"},{"name":"cw-logs-2.png","path":"_docs/_images/cw-logs-2.png","sha":"9a0a80b20490fdc1b9014040cc0bbc87c9cf6f68"},{"name":"cw-logs-3.png","path":"_docs/_images/cw-logs-3.png","sha":"bda49dc4e947658e0ceb9ba592b4e314d9db61e9"},{"name":"cw-logs-4.png","path":"_docs/_images/cw-logs-4.png","sha":"54bcc44c4b0701620b7f20c4e6fc0a9fd8f38049"},{"name":"ecs-console-1.png","path":"_docs/_images/ecs-console-1.png","sha":"afe452278d5f107e6ec225a235c587de7cb53510"},{"name":"ecs-console-2.png","path":"_docs/_images/ecs-console-2.png","sha":"40609b98015d781b9e1de801c131fadc323337ae"},{"name":"ecs-console-3.png","path":"_docs/_images/ecs-console-3.png","sha":"87ad40d291b7e9e6f6caa0389b846392bdb93ee0"},{"name":"ref-arch-full.png","path":"_docs/_images/ref-arch-full.png","sha":"8c17eef52be06757553a1f3ee4e387e6dc820016"},{"name":"ref-arch-icon.png","path":"_docs/_images/ref-arch-icon.png","sha":"05876962e6877df911674237ca1b793d9f4f04b3"},{"name":"terraform-code-provenance.png","path":"_docs/_images/terraform-code-provenance.png","sha":"e2a9d6bfbd8b963b057d4341dd0ec93e3823d834"}]}],"toggled":true},{"name":"main","children":[{"name":"_global","children":[{"name":"README.md","path":"main/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"main/_global/cloudtrail/README.md","sha":"7bf54b13e60f80416bbe3ee5b22328ee47a2532a"},{"name":"terragrunt.hcl","path":"main/_global/cloudtrail/terragrunt.hcl","sha":"5d4953cb81dc711c1f5641e26b54b2de8dedf62e"}]},{"name":"iam-groups","children":[{"name":"README.md","path":"main/_global/iam-groups/README.md","sha":"b6797c786d3c914257fc0e0bb4680e9fc861ab38"},{"name":"terragrunt.hcl","path":"main/_global/iam-groups/terragrunt.hcl","sha":"f14f3f59fb104ffc4f9925dd8565f43d665600c7"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"main/_global/iam-user-password-policy/README.md","sha":"1ddbc02253cb2fb3971fdbf1b3e09758f8eede9a"},{"name":"terragrunt.hcl","path":"main/_global/iam-user-password-policy/terragrunt.hcl","sha":"482cdc172a7e5f033acf9d808bef3e8bd3ef8f1e"}]},{"name":"machine-user","children":[{"name":"README.md","path":"main/_global/machine-user/README.md","sha":"0d676a50c24d954dab8a57794e6790eb03d03e4e"},{"name":"terragrunt.hcl","path":"main/_global/machine-user/terragrunt.hcl","sha":"50b845d531ee85c0a109c6abba695a3fe7d5b89e"}]},{"name":"region.yaml","path":"main/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"},{"name":"route53-public","children":[{"name":"README.md","path":"main/_global/route53-public/README.md","sha":"4757db7a8adde3d4af6a86f3ea20e050ae946a08"},{"name":"terragrunt.hcl","path":"main/_global/route53-public/terragrunt.hcl","sha":"06c315b032005358d2a3e6c5774f5b99ab64e681"}]},{"name":"service-linked-roles","children":[{"name":"README.md","path":"main/_global/service-linked-roles/README.md","sha":"45c1919cc5667b8d8ae25f09b3baf3078a7b36f9"},{"name":"terragrunt.hcl","path":"main/_global/service-linked-roles/terragrunt.hcl","sha":"398538ac8d92ed0160f303b029720592f81af280"}]}]},{"name":"empty.yaml","path":"main/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"main/terragrunt.hcl","sha":"3f362bb353e2d6e02f59294d7f7044da3a62b565"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"main/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"},{"name":"ecr-repos","children":[{"name":"README.md","path":"main/us-east-1/_global/ecr-repos/README.md","sha":"e7215127ffcf141002796e83ed1b9e9647ddbe22"},{"name":"terragrunt.hcl","path":"main/us-east-1/_global/ecr-repos/terragrunt.hcl","sha":"20c8ae6bd26f8cfd8fddcb8676cc109201bc49eb"}]},{"name":"sns-topics","children":[{"name":"README.md","path":"main/us-east-1/_global/sns-topics/README.md","sha":"05eb8a853eccf6465dc558bb9c57637fb4e9ccd3"},{"name":"terragrunt.hcl","path":"main/us-east-1/_global/sns-topics/terragrunt.hcl","sha":"81c92f821daf7077881a43678c717d485fc36401"}]}]},{"name":"mgmt","children":[{"name":"README.md","path":"main/us-east-1/mgmt/README.md","sha":"8a131a11632b97fec18a5e344d5c721fce24b652"},{"name":"env.yaml","path":"main/us-east-1/mgmt/env.yaml","sha":"b514ab3187ebfb5bf467c632f27a21f5a9611bfc"},{"name":"kms-master-key","children":[{"name":"README.md","path":"main/us-east-1/mgmt/kms-master-key/README.md","sha":"2affa3417a1b76f670e407330cb9dc62d01a521e"},{"name":"terragrunt.hcl","path":"main/us-east-1/mgmt/kms-master-key/terragrunt.hcl","sha":"5e24ee41d1565d3e026354e71a5ae7a362a206ea"}]},{"name":"openvpn-server","children":[{"name":"README.md","path":"main/us-east-1/mgmt/openvpn-server/README.md","sha":"93a2465ed5c720dd30b434aa36a2d28c4e0c7fcf"},{"name":"terragrunt.hcl","path":"main/us-east-1/mgmt/openvpn-server/terragrunt.hcl","sha":"aaf206a2c80987a888872ef7812bb93984cf26d1"}]},{"name":"vpc","children":[{"name":"README.md","path":"main/us-east-1/mgmt/vpc/README.md","sha":"495e2b8828a490c03ea7e153e695239f2bb92512"},{"name":"terragrunt.hcl","path":"main/us-east-1/mgmt/vpc/terragrunt.hcl","sha":"d6fad3a7e2397ea7bc62fa77ea6e138ec27e4335"}]}]},{"name":"prod","children":[{"name":"README.md","path":"main/us-east-1/prod/README.md","sha":"f15da18661ef3624d5f63deb288bad072e93df57"},{"name":"cloudwatch-dashboard","children":[{"name":"README.md","path":"main/us-east-1/prod/cloudwatch-dashboard/README.md","sha":"766cff97af8b2bbbdb90c2262c150b4d0bc88c62"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/cloudwatch-dashboard/terragrunt.hcl","sha":"ff055251d5427c0116d0e382f38c537b09db96ee"}]},{"name":"data-stores","children":[{"name":"elasticsearch","children":[{"name":"README.md","path":"main/us-east-1/prod/data-stores/elasticsearch/README.md","sha":"de10ddf77c3ae0b341ebbd7152f8d3c086d7ba20"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/data-stores/elasticsearch/terragrunt.hcl","sha":"736a4bdbdcc1b54dcd909671a76f09988c226436"}]},{"name":"kafka","children":[{"name":"README.md","path":"main/us-east-1/prod/data-stores/kafka/README.md","sha":"3681db5950b18676e92d6f00df190ff553c06404"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/data-stores/kafka/terragrunt.hcl","sha":"89d57ee0e689e1f28141c383924b03937b46fb3b"}]},{"name":"mysql","children":[{"name":"README.md","path":"main/us-east-1/prod/data-stores/mysql/README.md","sha":"3ff802dea2beeb94b34a9d2087fa1ce332702ba0"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/data-stores/mysql/terragrunt.hcl","sha":"681f993523ec8336c4f6be26a41ab1148b127ce8"}]},{"name":"redis","children":[{"name":"README.md","path":"main/us-east-1/prod/data-stores/redis/README.md","sha":"7f5426659066280ce18fad93eb14dd573e3de1b0"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/data-stores/redis/terragrunt.hcl","sha":"e7d7171695ad1ca039db9171ac31f1fb210f51f5"}]},{"name":"zookeeper","children":[{"name":"README.md","path":"main/us-east-1/prod/data-stores/zookeeper/README.md","sha":"3aa643354b946d75610e3a8d10e616e1080717bc"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/data-stores/zookeeper/terragrunt.hcl","sha":"ed94a3d0277beb71cd9500f1d29053e2f5b99f28"}]}]},{"name":"env.yaml","path":"main/us-east-1/prod/env.yaml","sha":"90e2d18e481b6e35ddc57391f752874ffc0058cf"},{"name":"kms-master-key","children":[{"name":"README.md","path":"main/us-east-1/prod/kms-master-key/README.md","sha":"7bf1a8da34427b8314d99904b01c20937604e1e0"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/kms-master-key/terragrunt.hcl","sha":"fb4afa8978a7b719c852756ac51883c5e87f5ab8"}]},{"name":"lambda","children":[{"name":"long-running-scheduled","children":[{"name":"README.md","path":"main/us-east-1/prod/lambda/long-running-scheduled/README.md","sha":"a6a7503b1168dd015618028f30b74aeb1ba7baf3"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/lambda/long-running-scheduled/terragrunt.hcl","sha":"c05243749ec7d3bd386c0563936b0f5e0b4bbbe6"}]},{"name":"s3-image-processing","children":[{"name":"README.md","path":"main/us-east-1/prod/lambda/s3-image-processing/README.md","sha":"1b149a62078c71549d77e59b0ea995f7181a7d8b"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/lambda/s3-image-processing/terragrunt.hcl","sha":"68b62dc42154055b1eaf522fd2240992df4d7814"}]}]},{"name":"networking","children":[{"name":"alb-internal","children":[{"name":"README.md","path":"main/us-east-1/prod/networking/alb-internal/README.md","sha":"5880e9468a3bf336b613dc7132b052ea89a0f99a"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/networking/alb-internal/terragrunt.hcl","sha":"7ad684cfd8fc90140bf149e0f7fa689a2bd6ace0"}]},{"name":"alb-public","children":[{"name":"README.md","path":"main/us-east-1/prod/networking/alb-public/README.md","sha":"5880e9468a3bf336b613dc7132b052ea89a0f99a"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/networking/alb-public/terragrunt.hcl","sha":"ad8fd584b78fdd026ac76554e60653f2c23cf765"}]},{"name":"route53-private","children":[{"name":"README.md","path":"main/us-east-1/prod/networking/route53-private/README.md","sha":"9160c66a0b04a407981db7bf9ee40dad8c5d9434"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/networking/route53-private/terragrunt.hcl","sha":"df4f82c4dc568fbe251eef10adbc28f1b1ccc263"}]}]},{"name":"services","children":[{"name":"ecs-cluster","children":[{"name":"README.md","path":"main/us-east-1/prod/services/ecs-cluster/README.md","sha":"560d730485383f188833313b77599681d146bdd7"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/ecs-cluster/terragrunt.hcl","sha":"38c41c4c8583f8569c2d37e51321acf4a0af6f5f"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"main/us-east-1/prod/services/eks-cluster/README.md","sha":"84d53a02559d844d8c62ee9d11a558265b3ae5b5"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/eks-cluster/terragrunt.hcl","sha":"e80ff0c733463d17c33d8c7062121e985d1cd1e8"}]},{"name":"eks-core-services","children":[{"name":"README.md","path":"main/us-east-1/prod/services/eks-core-services/README.md","sha":"298969aaf6db9c7e972cd735cef2d43cda899e3f"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/eks-core-services/terragrunt.hcl","sha":"1e8a88f4c8330f10848fea04daa719ab92c74d53"}]},{"name":"k8s-applications-namespace","children":[{"name":"README.md","path":"main/us-east-1/prod/services/k8s-applications-namespace/README.md","sha":"5e0a3640be89e96aece9e4ac8f8b7967e4d57056"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/k8s-applications-namespace/terragrunt.hcl","sha":"120cab356ca4590c262bd3b727d60f6c8294792b"}]},{"name":"k8s-sample-app-backend-acme","children":[{"name":"README.md","path":"main/us-east-1/prod/services/k8s-sample-app-backend-acme/README.md","sha":"4737c31d75b6d6c7565fa3d391177c9d3d022a5e"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/k8s-sample-app-backend-acme/terragrunt.hcl","sha":"c4e9d2aaad8a61ebcb1148800e50858e1023d959"}]},{"name":"k8s-sample-app-frontend-acme","children":[{"name":"README.md","path":"main/us-east-1/prod/services/k8s-sample-app-frontend-acme/README.md","sha":"43161374e0c977f15e8af04913e3554894ed2a82"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/k8s-sample-app-frontend-acme/terragrunt.hcl","sha":"9ab415e18bdf994e3b78f9a6ade6cd3b0fb87e5f"}]},{"name":"sample-app-backend-acme-asg","children":[{"name":"README.md","path":"main/us-east-1/prod/services/sample-app-backend-acme-asg/README.md","sha":"90c4b69a937239b4b51e99c4404360f4aba4edde"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/sample-app-backend-acme-asg/terragrunt.hcl","sha":"940d42befd46a394d63124cfd0d5830c6cea44b2"}]},{"name":"sample-app-backend-acme","children":[{"name":"README.md","path":"main/us-east-1/prod/services/sample-app-backend-acme/README.md","sha":"db3e1635aae0577080a9e2518633d4b5830a259a"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/sample-app-backend-acme/terragrunt.hcl","sha":"c2f4509348ff2f45c10901bbd06f7e409b888e14"}]},{"name":"sample-app-beanstalk","children":[{"name":"README.md","path":"main/us-east-1/prod/services/sample-app-beanstalk/README.md","sha":"27f6c3930f0621262b5dd0400f59e1122631da65"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/sample-app-beanstalk/terragrunt.hcl","sha":"2eaf051ae2cb3f4871be2cb78d3c9edec2da212e"}]},{"name":"sample-app-frontend-acme-asg","children":[{"name":"README.md","path":"main/us-east-1/prod/services/sample-app-frontend-acme-asg/README.md","sha":"ab9db3714676828cb0b766b5a3329f37115b1729"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/sample-app-frontend-acme-asg/terragrunt.hcl","sha":"2d6811f17d17c94bdf9f06c74bf74a3424555c3b"}]},{"name":"sample-app-frontend-acme","children":[{"name":"README.md","path":"main/us-east-1/prod/services/sample-app-frontend-acme/README.md","sha":"c0bc1f93aef1ab1bcf3e22aaec14a1744da74dfb"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/sample-app-frontend-acme/terragrunt.hcl","sha":"84c663da537b9e7485f4e3eff18ffaabfc90ff4b"}]},{"name":"static-website","children":[{"name":"README.md","path":"main/us-east-1/prod/services/static-website/README.md","sha":"16d262eab6ca158ae60d84010bc4804a948673cf"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/services/static-website/terragrunt.hcl","sha":"bb0530a96785e00136cb13da4dd2aca6583ba393"}]}]},{"name":"vpc","children":[{"name":"README.md","path":"main/us-east-1/prod/vpc/README.md","sha":"eb0cfd86345b2983b4a9c9572501728493bfcde4"},{"name":"terragrunt.hcl","path":"main/us-east-1/prod/vpc/terragrunt.hcl","sha":"5a5f20f83d3935f43b48c71b88c0f44443eb11ed"}]}]},{"name":"region.yaml","path":"main/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"},{"name":"stage","children":[{"name":"README.md","path":"main/us-east-1/stage/README.md","sha":"b24ba21bf01baf19ff84a2de457697a757d905c5"},{"name":"cloudwatch-dashboard","children":[{"name":"README.md","path":"main/us-east-1/stage/cloudwatch-dashboard/README.md","sha":"766cff97af8b2bbbdb90c2262c150b4d0bc88c62"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/cloudwatch-dashboard/terragrunt.hcl","sha":"feb471fd97d340798fd7ea565195faf4c4328f82"}]},{"name":"data-stores","children":[{"name":"elasticsearch","children":[{"name":"README.md","path":"main/us-east-1/stage/data-stores/elasticsearch/README.md","sha":"de10ddf77c3ae0b341ebbd7152f8d3c086d7ba20"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/data-stores/elasticsearch/terragrunt.hcl","sha":"b65b647edff6298b3a5a010d8ebe13f022b7c54d"}]},{"name":"kafka","children":[{"name":"README.md","path":"main/us-east-1/stage/data-stores/kafka/README.md","sha":"3681db5950b18676e92d6f00df190ff553c06404"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/data-stores/kafka/terragrunt.hcl","sha":"5ba7184e22ee433462c2d05c97ad6bb47c13786b"}]},{"name":"mysql","children":[{"name":"README.md","path":"main/us-east-1/stage/data-stores/mysql/README.md","sha":"3ff802dea2beeb94b34a9d2087fa1ce332702ba0"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/data-stores/mysql/terragrunt.hcl","sha":"d5d7ac741e73afbce47d99af1cbb16219e8af208"}]},{"name":"redis","children":[{"name":"README.md","path":"main/us-east-1/stage/data-stores/redis/README.md","sha":"7f5426659066280ce18fad93eb14dd573e3de1b0"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/data-stores/redis/terragrunt.hcl","sha":"224dc41a716053b231af5c557d7fe95a67af6d51"}]},{"name":"zookeeper","children":[{"name":"README.md","path":"main/us-east-1/stage/data-stores/zookeeper/README.md","sha":"3aa643354b946d75610e3a8d10e616e1080717bc"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/data-stores/zookeeper/terragrunt.hcl","sha":"c084625c9b909a6e5c7cc45995752645e1a9a577"}]}]},{"name":"env.yaml","path":"main/us-east-1/stage/env.yaml","sha":"5767506e27e978f52524dadbbd8fb9f8ad115599"},{"name":"kms-master-key","children":[{"name":"README.md","path":"main/us-east-1/stage/kms-master-key/README.md","sha":"0fc848e518ff6551caae5f234b89f3f2c2a3b015"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/kms-master-key/terragrunt.hcl","sha":"49762d286ee1ed5b999973a5f82688c01bdcf679"}]},{"name":"lambda","children":[{"name":"long-running-scheduled","children":[{"name":"README.md","path":"main/us-east-1/stage/lambda/long-running-scheduled/README.md","sha":"a6a7503b1168dd015618028f30b74aeb1ba7baf3"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/lambda/long-running-scheduled/terragrunt.hcl","sha":"c05243749ec7d3bd386c0563936b0f5e0b4bbbe6"}]},{"name":"s3-image-processing","children":[{"name":"README.md","path":"main/us-east-1/stage/lambda/s3-image-processing/README.md","sha":"1b149a62078c71549d77e59b0ea995f7181a7d8b"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/lambda/s3-image-processing/terragrunt.hcl","sha":"2ab4fe1b159bfe0797662dee0c24aba8b9b3e106"}]}]},{"name":"networking","children":[{"name":"alb-internal","children":[{"name":"README.md","path":"main/us-east-1/stage/networking/alb-internal/README.md","sha":"c1c8edd637ebd686cc5d7675013d750b8ca4ad52"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/networking/alb-internal/terragrunt.hcl","sha":"d90749b2f63ce2187c0fb1ee95723a57fb7e4097"}]},{"name":"alb-public","children":[{"name":"README.md","path":"main/us-east-1/stage/networking/alb-public/README.md","sha":"c1c8edd637ebd686cc5d7675013d750b8ca4ad52"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/networking/alb-public/terragrunt.hcl","sha":"fc8f137af22da522f85614dc22de19f962bdb285"}]},{"name":"route53-private","children":[{"name":"README.md","path":"main/us-east-1/stage/networking/route53-private/README.md","sha":"9160c66a0b04a407981db7bf9ee40dad8c5d9434"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/networking/route53-private/terragrunt.hcl","sha":"df4f82c4dc568fbe251eef10adbc28f1b1ccc263"}]}]},{"name":"services","children":[{"name":"ecs-cluster","children":[{"name":"README.md","path":"main/us-east-1/stage/services/ecs-cluster/README.md","sha":"94916a4be4208e4c1e1e7b7ee0d6dfa2fbfaf38c"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/ecs-cluster/terragrunt.hcl","sha":"744840965cbe10f02eb8d363ee2407201be2baf9"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"main/us-east-1/stage/services/eks-cluster/README.md","sha":"6db608bd68f9b1d4ee2741d72b2949d0dcf3e33d"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/eks-cluster/terragrunt.hcl","sha":"40da930fe85423d42896eac63f0a084847d85f53"}]},{"name":"eks-core-services","children":[{"name":"README.md","path":"main/us-east-1/stage/services/eks-core-services/README.md","sha":"0311f74f5aca78b831407ac5396907ae792d2297"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/eks-core-services/terragrunt.hcl","sha":"b8d6845c4bbca33df0a3cde51cbe1ef597095050"}]},{"name":"k8s-applications-namespace","children":[{"name":"README.md","path":"main/us-east-1/stage/services/k8s-applications-namespace/README.md","sha":"c96645baedf7aba16fc04d003608c61f9353ff4a"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/k8s-applications-namespace/terragrunt.hcl","sha":"dbd60d465e5cbb46c8a9d21620dca06f9b70dd63"}]},{"name":"k8s-sample-app-backend-acme","children":[{"name":"README.md","path":"main/us-east-1/stage/services/k8s-sample-app-backend-acme/README.md","sha":"430e8d870a1f1895093df8cb4e88e0bf2bb82bc1"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/k8s-sample-app-backend-acme/terragrunt.hcl","sha":"479f85df9855c21e4f095d6251ce4ca6d127b08c"}]},{"name":"k8s-sample-app-frontend-acme","children":[{"name":"README.md","path":"main/us-east-1/stage/services/k8s-sample-app-frontend-acme/README.md","sha":"3efad94b3379996e29355319fbe2de5c426c71dc"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/k8s-sample-app-frontend-acme/terragrunt.hcl","sha":"e0035433fce291da1ce64e77370c20790a4f063d"}]},{"name":"sample-app-backend-acme-asg","children":[{"name":"README.md","path":"main/us-east-1/stage/services/sample-app-backend-acme-asg/README.md","sha":"e2d00c960fa47118b3010550ecddf1133518d5fa"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/sample-app-backend-acme-asg/terragrunt.hcl","sha":"91940573b9a659202289c6815bd9871e50ac4d20"}]},{"name":"sample-app-backend-acme","children":[{"name":"README.md","path":"main/us-east-1/stage/services/sample-app-backend-acme/README.md","sha":"4d0bc076e9d8a51bde996c7c9f77e91bcc3e6125"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/sample-app-backend-acme/terragrunt.hcl","sha":"e240269caa4c5e60e932ebed487cf688a4c22227"}]},{"name":"sample-app-beanstalk","children":[{"name":"README.md","path":"main/us-east-1/stage/services/sample-app-beanstalk/README.md","sha":"1b3f68cb5baac277414f45585221f7048b801c26"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/sample-app-beanstalk/terragrunt.hcl","sha":"4deb3dbc95ed927e33211e473868915c1f86b5b3"}]},{"name":"sample-app-frontend-acme-asg","children":[{"name":"README.md","path":"main/us-east-1/stage/services/sample-app-frontend-acme-asg/README.md","sha":"c4df19131aafdf152f08998a2d1121ccd58c4207"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/sample-app-frontend-acme-asg/terragrunt.hcl","sha":"1d8aaccc8608aa1c2b46338c592a10f27e5b3aea"}]},{"name":"sample-app-frontend-acme","children":[{"name":"README.md","path":"main/us-east-1/stage/services/sample-app-frontend-acme/README.md","sha":"20e39909320df4775e21dd2cea70f3dabdd94c1e"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/sample-app-frontend-acme/terragrunt.hcl","sha":"2597d32b7c9d865e9f3701aa7c02a30ee4deeb01"}]},{"name":"static-website","children":[{"name":"README.md","path":"main/us-east-1/stage/services/static-website/README.md","sha":"16d262eab6ca158ae60d84010bc4804a948673cf"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/services/static-website/terragrunt.hcl","sha":"9a9cb3c9830902ef05fd497bfd21028a7fac38df"}]}]},{"name":"vpc","children":[{"name":"README.md","path":"main/us-east-1/stage/vpc/README.md","sha":"d1e3f82de82c4b8f4eaca81b3a8ec63ed040a0b5"},{"name":"terragrunt.hcl","path":"main/us-east-1/stage/vpc/terragrunt.hcl","sha":"c2429ca5412fd6f0ff00e89dc4a1541e46b07d00"}]}]}]}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"accounts-and-auth\">Accounts and Auth</h1><div class=\"preview__body--border\"></div><p>In the last section, you learned about connecting to your servers using <a href=\"/repos/v0.0.1-01172020/infrastructure-live-acme/_docs/08-ssh-vpn.md\" class=\"preview__body--description--blue\">SSH and VPN</a>. In this section,\nyou'll learn about connecting to your AWS accounts:</p>\n<ul>\n<li><a href=\"#auth-basics\" class=\"preview__body--description--blue\">Auth basics</a></li>\n<li><a href=\"#account-setup\" class=\"preview__body--description--blue\">Account setup</a></li>\n<li><a href=\"#authenticating\" class=\"preview__body--description--blue\">Authenticating</a></li>\n<li><a href=\"#kubernetes-rbac-roles-and-helm-authentication\" class=\"preview__body--description--blue\">Kubernetes RBAC Roles and Helm Authentication</a>\n<ul>\n<li><a href=\"#rbac-basics\" class=\"preview__body--description--blue\">RBAC basics</a></li>\n<li><a href=\"#relation-to-iam-roles\" class=\"preview__body--description--blue\">Relation to IAM roles</a></li>\n<li><a href=\"#namespaces-and-rbac\" class=\"preview__body--description--blue\">Namespaces and RBAC</a></li>\n<li><a href=\"#accessing-the-cluster\" class=\"preview__body--description--blue\">Accessing the cluster</a>\n<ul>\n<li><a href=\"#terragrunt--terraform\" class=\"preview__body--description--blue\">Terragrunt / Terraform</a></li>\n<li><a href=\"#kubectl\" class=\"preview__body--description--blue\">Kubectl</a></li>\n<li><a href=\"#helm\" class=\"preview__body--description--blue\">Helm</a></li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"auth-basics\">Auth basics</h2>\n<p>For an overview of AWS authentication, including how to authenticate on the command-line, we <strong>strongly</strong> recommend\nreading <a href=\"https://blog.gruntwork.io/a-comprehensive-guide-to-authenticating-to-aws-on-the-command-line-63656a686799\" class=\"preview__body--description--blue\" target=\"_blank\">A Comprehensive Guide to Authenticating to AWS on the Command\nLine</a>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"account-setup\">Account setup</h2>\n<p>All of your AWS resources are deployed into a single account. This makes it easy to manage everything.</p>\n<p>In the future, you may want to consider putting each environment (e.g., stage, prod, etc) into a separate AWS account.\nThis gives you more fine grained control over who can access what and improves isolation and security, as a mistake or\nbreach in one account is unlikely to affect the others. The downside is overhead: it takes more time to set up multiple\naccounts and more time to switch between them during day-to-day work. If you need help with multi-account setup, email\nsupport@gruntwork.io.</p>\n<h2 class=\"preview__body--subtitle\" id=\"authenticating\">Authenticating</h2>\n<p>Some best practices around authenticating to your AWS account:</p>\n<ul>\n<li><a href=\"#enable-mfa\" class=\"preview__body--description--blue\">Enable MFA</a></li>\n<li><a href=\"#use-a-password-manager\" class=\"preview__body--description--blue\">Use a password manager</a></li>\n<li><a href=\"#dont-user-the-root-user\" class=\"preview__body--description--blue\">Don't use the root user</a></li>\n</ul>\n<p>Note that most of this section comes from the <a href=\"https://docs.google.com/document/d/e/2PACX-1vTikva7hXPd2h1SSglJWhlW8W6qhMlZUxl0qQ9rUJ0OX22CQNeM-91w4lStRk9u2zQIn6lPejUbe-dl/pub\" class=\"preview__body--description--blue\" target=\"_blank\">Gruntwork Security Best Practices\ndocument</a>, so make sure to read through that for more info.</p>\n<h3 class=\"preview__body--subtitle\" id=\"enable-mfa\">Enable MFA</h3>\n<p>Always enable multi-factor authentication (MFA) for your AWS account. That is, in addition to a password, you must\nprovide a second factor to prove your identity. The best option for AWS is to install <a href=\"https://support.google.com/accounts/answer/1066447?hl=en\" class=\"preview__body--description--blue\" target=\"_blank\">Google\nAuthenticator</a> on your phone and use it to generate a one-time\ntoken as your second factor.</p>\n<h3 class=\"preview__body--subtitle\" id=\"use-a-password-manager\">Use a password manager</h3>\n<p>Never store secrets in plain text. Store your secrets using a secure password manager, such as\n<a href=\"https://www.passwordstore.org/\" class=\"preview__body--description--blue\" target=\"_blank\">pass</a>, <a href=\"https://en.wikipedia.org/wiki/Keychain_(software)\" class=\"preview__body--description--blue\" target=\"_blank\">OS X Keychain</a>, or\n<a href=\"http://keepass.info/\" class=\"preview__body--description--blue\" target=\"_blank\">KeePass</a>. You can also use cloud-based password managers, such as\n<a href=\"https://1password.com/\" class=\"preview__body--description--blue\" target=\"_blank\">1Password</a> or <a href=\"https://www.lastpass.com/\" class=\"preview__body--description--blue\" target=\"_blank\">LastPass</a>, but be aware that since they have\neveryone's passwords, they are inherently much more tempting targets for attackers. That said, any reasonable password\nmanager is better than none at all!</p>\n<h3 class=\"preview__body--subtitle\" id=\"dont-use-the-root-user\">Don't use the root user</h3>\n<p>AWS uses the <a href=\"https://aws.amazon.com/iam/\" class=\"preview__body--description--blue\" target=\"_blank\">Identity and Access Management (IAM)</a> service to manage users and their\npermissions. When you first sign up for an AWS account, you are logged in as the <em>root user</em>. This user has permissions\nto do everything in the account, so if you compromise these credentials, you’re in deep trouble.</p>\n<p>Therefore, right after signing up, you should:</p>\n<ol>\n<li>\n<p>Enable MFA on your root account. Note: we strongly recommend making a copy of the MFA secret key. This way, if you\nlose your MFA device (e.g. your iPhone), you don’t lose access to your AWS account. To make the backup, when\nactivating MFA, AWS will show you a QR code. Click the "show secret key for manual configuration" link and save that\nkey to a secure password manager.</p>\n</li>\n<li>\n<p>Make sure you use a very long and secure password. Never share that password with anyone. If you need to store it\n(as opposed to memorizing it), only store it in a secure password manager.</p>\n</li>\n<li>\n<p>Use the root account to create a separate IAM user for yourself and your team members with more limited IAM\npermissions. You should manage permissions using IAM groups. See the <a href=\"/repos/module-security/modules/iam-groups\" class=\"preview__body--description--blue\">iam-groups\nmodule</a> for details.</p>\n</li>\n<li>\n<p>Use IAM roles when you need to give limited permissions to tools (for eg, CI servers or EC2 instances).</p>\n</li>\n<li>\n<p>Require all IAM users in your account to use MFA.</p>\n</li>\n<li>\n<p>Never use the root IAM account again.</p>\n</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"kubernetes-rbac-roles-and-helm-authentication\">Kubernetes RBAC Roles and Helm Authentication</h2>\n<p>Up to this point we focused on accounts and authentication in AWS. However, with EKS, Kubernetes adds another layer of\naccounts and authentication that are tied to, but not exactly the same as, AWS IAM.</p>\n<p>In this section, you'll learn about Kubernetes RBAC roles and Helm authentication:</p>\n<ul>\n<li><a href=\"#rbac-basics\" class=\"preview__body--description--blue\">RBAC basics</a></li>\n<li><a href=\"#relation-to-iam-roles\" class=\"preview__body--description--blue\">Relation to IAM roles</a></li>\n<li><a href=\"#namespaces-and-rbac\" class=\"preview__body--description--blue\">Namespaces and RBAC</a></li>\n<li><a href=\"#accessing-the-cluster\" class=\"preview__body--description--blue\">Accessing to the cluster</a>\n<ul>\n<li><a href=\"#terragrunt--terraform\" class=\"preview__body--description--blue\">Terragrunt / Terraform</a></li>\n<li><a href=\"#kubectl\" class=\"preview__body--description--blue\">Kubectl</a></li>\n<li><a href=\"#helm\" class=\"preview__body--description--blue\">Helm</a></li>\n</ul>\n</li>\n</ul>\n<h3 class=\"preview__body--subtitle\" id=\"rbac-basics\">RBAC basics</h3>\n<p><a href=\"https://kubernetes.io/docs/reference/access-authn-authz/rbac/\" class=\"preview__body--description--blue\" target=\"_blank\">Role Based Access Control (RBAC)</a> is a method to regulate\naccess to resources based on the role that individual users assume in an organization. Kubernetes allows you to define\nroles in the system that individual users inherit, and explicitly grant permissions to resources within the system to\nthose roles. The Control Plane will then honor those permissions when accessing the resources on Kubernetes through\nclients such as <code>kubectl</code>. When combined with namespaces, you can implement sophisticated control schemes that limit the\naccess of resources across the roles in your organization.</p>\n<p>The RBAC system is managed using <code>ClusterRole</code> and <code>ClusterRoleBinding</code> resources (or <code>Role</code> and <code>RoleBinding</code> resources\nif restricting to a single namespace). The <code>ClusterRole</code> (or <code>Role</code>) object defines a role in the Kubernetes system that\nhas explicit permissions on what it can and cannot do. These roles are then bound to users and groups using the\n<code>ClusterRoleBinding</code> (or <code>RoleBinding</code>) resource. An important thing to note here is that you do not explicitly create\nusers and groups using RBAC, and instead rely on the authentication system to implicitly create these entities.</p>\n<p>You can refer to <a href=\"/repos/terraform-aws-eks/modules/eks-k8s-role-mapping#examples\" class=\"preview__body--description--blue\">Gruntwork's RBAC example\nscenarios</a> for use\ncases.</p>\n<h3 class=\"preview__body--subtitle\" id=\"relation-to-iam-roles\">Relation to IAM Roles</h3>\n<p>EKS manages authentication to Kubernetes based on AWS IAM roles and users. This is done by embedding AWS IAM credentials\n(the access key and secret key) into the authentication token used to authenticate to the Kubernetes API. The API server\nthen forwards this to AWS to validate it, and then reconciles the role / user into an RBAC user and group that is then\nused to reconcile authorization rules for the API.</p>\n<p>By default all IAM roles and users (except for the role / user that deployed the cluster) has no RBAC user or groups\nassociated with it. This automatically translates the role / user into an anonymous user on the cluster, who by default\nhas no permissions. In order to allow access to the cluster, you need to explicitly bind the IAM role / user to an RBAC\nentity, and then bind <code>Roles</code> or <code>ClusterRoles</code> that explicitly grants permissions to perform actions on the cluster.\nThis mapping is handled by the <a href=\"/repos/terraform-aws-eks/modules/eks-k8s-role-mapping\" class=\"preview__body--description--blue\">eks-k8s-role-mapping\nmodule</a>, used under the hood\nin the <a href=\"/repos/infrastructure-modules-acme/services/eks-cluster\" class=\"preview__body--description--blue\">eks-cluster infrastructure module</a>.</p>\n<p>You can read more about the relationship between IAM roles and RBAC roles in EKS in <a href=\"https://docs.aws.amazon.com/eks/latest/userguide/managing-auth.html\" class=\"preview__body--description--blue\" target=\"_blank\">the official\ndocumentation</a>.</p>\n<h3 class=\"preview__body--subtitle\" id=\"namespaces-and-rbac\">Namespaces and RBAC</h3>\n<p><a href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\" class=\"preview__body--description--blue\" target=\"_blank\">Namespaces</a> are Kubernetes resources\nthat creates virtual partition boundaries in your cluster. The resources in each <code>Namespace</code> are isolated from other\n<code>Namespaces</code>, and can only interact with them through <code>Service</code> endpoints, unless explicit permissions are granted. This\nallows you to divide the cluster between multiple users in a way that prevents them from seeing each others' resources,\nallowing you to share clusters while protecting sensitive information.</p>\n<p>RBAC is critical in achieving isolation of <code>Namespaces</code>. The RBAC permissions can be restricted by <code>Namespace</code>. This\nallows you to bind permissions to entities such that they can only perform certain actions on resources within a\nparticular <code>Namespace</code>.</p>\n<p>Refer to the <a href=\"/repos/terraform-aws-eks/modules/eks-k8s-role-mapping#restricting-by-namespace\" class=\"preview__body--description--blue\">eks-k8s-role-mapping module\ndocs</a>\nfor an example on using RBAC to restrict actions to a particular <code>Namespace</code>.</p>\n<p>Every EKS cluster comes with two default <code>Namespaces</code>:</p>\n<ul>\n<li><code>kube-system</code>: This <code>Namespace</code> holds admin and cluster level resources. Only cluster administrators ("superusers")\nshould have access to this <code>Namespace</code>.</li>\n<li><code>default</code>: This is the default <code>Namespace</code> that is used for API calls that don't specify a particular <code>Namespace</code>.\nThis should primarily be used for development and experimentation purposes.</li>\n</ul>\n<p>Additionally, in the Reference Architecture, we create another <code>Namespace</code>: <code>applications</code>. This <code>Namespace</code> is used to\nhouse the deployed sample applications and its associated resources.</p>\n<p>Most Kubernetes tools will let you set the <code>Namespace</code> as CLI args. For example, <code>kubectl</code> supports a <code>-n</code> parameter for\nspecifying which <code>Namespace</code> you intend to run the command against. <code>kubectl</code> additionally supports overriding the\ndefault <code>Namespace</code> for your commands by binding a <code>Namespace</code> to your authentication context.</p>\n<h3 class=\"preview__body--subtitle\" id=\"accessing-the-cluster\">Accessing the cluster</h3>\n<p>As mentioned in <a href=\"#relation-to-iam-roles\" class=\"preview__body--description--blue\">Relation to IAM Roles</a>, EKS proxies Kubernetes authentication through AWS IAM\ncredentials. This means that you need to be authenticated to AWS first in order to authenticate to Kubernetes. Refer to\n<a href=\"#authenticating\" class=\"preview__body--description--blue\">the previous section on AWS authentication</a> for information on how to authenticate to AWS.</p>\n<p>There are three main ways to interact with Kubernetes in the Reference Architecture:</p>\n<ul>\n<li><a href=\"#terragrunt--terraform\" class=\"preview__body--description--blue\">Using Terragrunt / Terraform</a></li>\n<li><a href=\"#kubectl\" class=\"preview__body--description--blue\">Using kubectl</a></li>\n<li><a href=\"#helm\" class=\"preview__body--description--blue\">Using Helm</a></li>\n</ul>\n<h4 id=\"terragrunt-terraform\">Terragrunt / Terraform</h4>\n<p>When deploying Kubernetes resources using Terragrunt / Terraform, all the authentication is handled inside of Terraform\nusing a combination of EKS data sources and provider logic. What this means is that you don't have to worry about\nexplicitly authenticating to Kubernetes when going through Terraform, as long as you are authenticating to an IAM role\nthat has a valid mapping to an RBAC entity in the cluster.</p>\n<p>The one exception to this is the modules that depend on <code>helm</code>, which requires additional configuration. See the\n<a href=\"#helm\" class=\"preview__body--description--blue\">section on helm</a> for more info.</p>\n<h4 id=\"kubectl\">Kubectl</h4>\n<p>Most manual operations in Kubernetes are handled through <a href=\"https://kubernetes.io/docs/reference/kubectl/overview/\" class=\"preview__body--description--blue\" target=\"_blank\">the kubectl command line\nutility</a>. <code>kubectl</code> requires an explicit authentication\nconfiguration to access the cluster.</p>\n<p>You can use <code>kubergrunt</code> to configure your local <code>kubectl</code> client to authenticate against a deployed EKS cluster. After\nauthenticating to AWS, run:</p>\n<pre>kubergrunt eks configure --eks-<span class=\"hljs-keyword\">cluster</span>-arn $EKS_CLUSTER_ARN\n</pre>\n<p>This will add a new entry to your <code>kubectl</code> config file (defaults to <code>$HOME/.kube/config</code>) with the logic for\nauthenticating to EKS, registering it under the context name <code>$EKS_CLUSTER_ARN</code>. You can modify the name of the context\nusing the <code>--kubectl-context-name</code> CLI arg.</p>\n<p>You can verify the setup by running:</p>\n<pre><span class=\"hljs-attribute\">kubectl</span> cluster-<span class=\"hljs-literal\">info</span>\n</pre>\n<p>This will report information about the Kubernetes endpoints for the cluster only if you are authorized to access to the\ncluster. Note that you will need to be authenticated to AWS for <code>kubectl</code> to successfully authenticate to the cluster.</p>\n<p>If you have multiple clusters, you can switch the <code>kubectl</code> context using the <code>use</code> command. For example, to switch the\ncurrent context to the <code>dev</code> EKS cluster from the <code>prod</code> cluster and back:</p>\n<pre>kubectl use arn:aws:eks:us-east-<span class=\"hljs-number\">1</span>:$DEV_ACCOUNT_ID:cluster/eks-dev\nkubectl cluster-info <span class=\"hljs-comment\"># Should target the dev EKS cluster</span>\nkubectl use arn:aws:eks:us-east-<span class=\"hljs-number\">1</span>:$PROD_ACCOUNT_ID:cluster/eks-prod\nkubectl cluster-info <span class=\"hljs-comment\"># Should target the prod EKS cluster</span>\n</pre>\n<h4 id=\"helm\">Helm</h4>\n<p>Helm relies on TLS based authentication and authorization to access Tiller (the Helm Server). This is separate from the\nRBAC based authorization native to Kubernetes. Intuitively, RBAC is used to manage whether or not someone can lookup the\n<code>Pod</code> endpoint address, while the TLS authentication and authorization scheme manages whether or not you can establish a\nconnection to the Tiller server. All deployments of Tiller in the Reference Architecture uses <code>kubergrunt</code> to manage the\nTLS certificates.</p>\n<p>We highly recommend reading <a href=\"/repos/kubergrunt/HELM_GUIDE.md\" class=\"preview__body--description--blue\">Gruntwork's guide to\nhelm</a> to understand the security model surrounding\nHelm and Tiller.</p>\n<p><code>kubergrunt</code> manages the TLS certificates using Kubernetes <code>Secrets</code>, guarded by RBAC roles. A cluster administrator can\ngrant access to any RBAC entity to any Tiller deployment using the <code>kubergrunt helm grant</code> command. For example, to\ngrant access to a Tiller server deployed in the namespace <code>applications-tiller</code> to the RBAC user\n<code>allow-full-access-from-other-accounts</code>:</p>\n<pre>kubergrunt helm grant <span class=\"hljs-string\">\\</span>\n --tls-common-name allow-full-access-<span class=\"hljs-keyword\">from</span>-other-accounts <span class=\"hljs-string\">\\</span>\n --tls-org Acme <span class=\"hljs-string\">\\</span>\n --tiller-namespace applications <span class=\"hljs-string\">\\</span>\n --rbac-user allow-full-access-<span class=\"hljs-keyword\">from</span>-other-accounts\n</pre>\n<p><strong>Note on RBAC users</strong>: The RBAC user username (<code>--rbac-user</code>) corresponds to the IAM Role or User name of the\nauthenticating AWS credentials.</p>\n<p>This generates new TLS certificate key pairs that grant access to the Tiller deployed in the <code>applications-tiller</code>\nNamespace. In addition, this creates and binds RBAC roles that allow users of the RBAC group <code>developers</code> to be able to\nread the necessary <code>Secrets</code> to download the generated TLS certificate key pairs.</p>\n<p>Now anyone who maps to the <code>developers</code> RBAC group can use the <code>kubergrunt helm configure</code> command to setup their\nhelm client to access the deployed Tiller:</p>\n<pre>kubergrunt helm configure <span class=\"hljs-string\">\\</span>\n --tiller-namespace applications-tiller <span class=\"hljs-string\">\\</span>\n --resource-namespace applications <span class=\"hljs-string\">\\</span>\n --rbac-user allow-full-access-<span class=\"hljs-keyword\">from</span>-other-accounts\n</pre>\n<p>This will:</p>\n<ul>\n<li>Download the client TLS certificate key pair generated with the <code>grant</code> command.</li>\n<li>Install the TLS certificate key pair in the helm home directory (defaults to <code>$HOME/.helm</code>).</li>\n<li>Install an environment file that sets up environment variables to target the specific helm server (defaults to\n<code>$HELM_HOME/env</code>). This environment file needs to be loaded before issuing any commands, at it sets the necessary\nenvironment variables to signal to the helm client which helm server to use. The environment variables it sets are:\n<ul>\n<li><code>HELM_HOME</code>: The helm client home directory where the TLS certs are located.</li>\n<li><code>TILLER_NAMESPACE</code>: The namespace where the helm server is installed.</li>\n<li><code>HELM_TLS_VERIFY</code>: This will be set to true to enable TLS verification.</li>\n<li><code>HELM_TLS_ENABLE</code>: This will be set to true to enable TLS authentication.</li>\n</ul>\n</li>\n</ul>\n<p>Once this is setup, Terraform modules that need to access <code>helm</code> will be able to use the downloaded credentials to\nauthenticate to Tiller. Additionally, once you source the environment file, you will be able to use the <code>helm</code> client to\ndirectly work with Tiller.</p>\n<p>If you have the <code>helm</code> client installed, you can verify your configuration setup using the <code>helm version</code> command:</p>\n<pre>helm <span class=\"hljs-built_in\">version</span>\n</pre>\n<p>If your <code>helm</code> client is configured correctly, the <code>version</code> command will output information about the deployed Tiller\ninstance that it connected to.</p>\n<h2 class=\"preview__body--subtitle\" id=\"next-steps\">Next steps</h2>\n<p>Now that you know how to authenticate, you may want to take a look through this list of <a href=\"/repos/v0.0.1-01172020/infrastructure-live-acme/_docs/10-gruntwork-tools.md\" class=\"preview__body--description--blue\">Gruntwork\nTools</a>.</p>\n","repoName":"infrastructure-live-acme","repoRef":"v0.0.1-01172020","serviceDescriptor":{"serviceName":"Single-account Reference Architecture","serviceRepoName":"infrastructure-live-acme","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"End-to-end tech stack designed to deploy into a single AWS account. Includes VPCs, EKS, ALBs, CI / CD, monitoring, alerting, VPN, DNS, and more.","imageUrl":"grunt.png","licenseType":"subscriber","technologies":["Terraform","Go","Bash","Python"],"compliance":[],"tags":[""]},"serviceCategoryName":"Reference Architecture","fileName":"09-accounts-and-auth.md","filePath":"/_docs/09-accounts-and-auth.md","title":"Repo Browser: Single-account Reference Architecture","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}