This Terraform Module manages Kubernetes
Namespaces. In addition to creating
namespaces, this module will create a set of default RBAC roles restricted to that namespace. The following roles will
be provided by this module:
namespace-access-all: Admin level permissions in the namespace. Ability to read, write, and delete all resources in
the namespace.
namespace-access-read-only: Read only permissions to all resources in the namespace.
namespace-tiller-metadata-access: Minimal permissions for Tiller to manage its metadata in this namespace (if this
namespace is where Tiller is deployed).
namespace-tiller-resource-access: Minimal permissions for Tiller to manage resources in this namespace as Helm
charts.
How do you use this module?
See the root README for instructions on using Terraform modules.
See variables.tf
for all the variables you can set on this module.
See outputs.tf
for all the variables that are outputed by this module.
What is a Namespace?
A Namespace is a Kubernetes resource that can be used to create a virtual environment in your cluster to separate
resources. It allows you to scope resources in your cluster to provide finer grained permission control and resource
quotas.
For example, suppose that you have two different teams managing separate services independently, such that the team
should not be allowed to update or modify the other teams' services. In such a scenario, you would use namespaces to
separate the resources between each team, and implement RBAC roles that only grant access to the namespace if you reside
in the team that manages it.
To illustrate this, let's assume that we have a team that manages
the application services related to the core product (named core) and another team managing analytics services (named
analytics). Let's also assume that we have already created RBAC groups for each team, named core-group and
analytics-group.
In addition to creating namespaces, this will also create a set of RBAC roles that can then be bound to user and group
entities to explicitly grant permissions to access that namespace.
We can then use kubectl to bind the roles to the groups:
When we apply this config with kubectl, users that are associated with the core RBAC group can now create and access
resources deployed in the core namespace, and the analytics group can access resources in the analytics namespace.
However, members of the core team can not access resources in the analytics namespace and vice versa.
To summarize, use namespaces to:
Implement finer grained access control over deployed resources.
Implement resource quotas to restrict how much of the
cluster can be utilized by each team.
Why is this a Terraform Module and not a Helm Chart?
This module uses Terraform to manage the Namespace and RBAC role resources instead of using Helm to support the use case of
setting up Helm. When setting up the Helm server, you will want to setup a Namespace and ServiceAccount for the Helm
server to be deployed with. This leads to a chicken and egg problem, where the Namespace and ServiceAccount needs to
be created before Helm is available for use. As such, we rely on Terraform to set these core resources up.
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":".circleci","children":[{"name":"config.yml","path":".circleci/config.yml","sha":"cef3f13f1128f203609bd70491c5789049d97396"}]},{"name":".gitignore","path":".gitignore","sha":"ca31ff35c5b25c686571a0430a14f86a38f15e77"},{"name":".pre-commit-config.yaml","path":".pre-commit-config.yaml","sha":"2dd1a8d4e16b65a1991537d51b5b59b6df1866f8"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"89db2c0afb6268a0fa92d8e841018cef4bc653cb"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","sha":"b12849077d576a7fad88da42db1131bb3369e194"},{"name":"GRUNTWORK_PHILOSOPHY.md","path":"GRUNTWORK_PHILOSOPHY.md","sha":"02d9873a74c99fe6d9b6b26bd9f8eb4a7a699c32"},{"name":"LICENSE","path":"LICENSE","sha":"276620ad6ffbc9954fd6633d167b0501155441d4"},{"name":"README.md","path":"README.md","sha":"444e80d608763aabb990f37a8badbe3bdf24b872"},{"name":"examples","children":[{"name":"k8s-namespace-with-service-account","children":[{"name":"README.md","path":"examples/k8s-namespace-with-service-account/README.md","sha":"cdff492defdaa77f736adc1c1ce9c1db1b3a9e1e"},{"name":"main.tf","path":"examples/k8s-namespace-with-service-account/main.tf","sha":"071b39770653ee2d6d12c80119bb290fff5c35d8"},{"name":"outputs.tf","path":"examples/k8s-namespace-with-service-account/outputs.tf","sha":"71e367b5fa5fc4d940c68b1689d340ab6fa2e17c"},{"name":"variables.tf","path":"examples/k8s-namespace-with-service-account/variables.tf","sha":"f38169a042290747cd6cda6375d99af81b1df97e"}]},{"name":"k8s-tiller-kubergrunt-minikube","children":[{"name":"README.md","path":"examples/k8s-tiller-kubergrunt-minikube/README.md","sha":"f4ee8247319417b5d433017005af1284c2feda71"},{"name":"main.tf","path":"examples/k8s-tiller-kubergrunt-minikube/main.tf","sha":"a2d71286a91c7cf02371ff10336ad6c8c65c5a99"},{"name":"outputs.tf","path":"examples/k8s-tiller-kubergrunt-minikube/outputs.tf","sha":"f839014a1879cfef47954641a01edf7820ac3bdc"},{"name":"variables.tf","path":"examples/k8s-tiller-kubergrunt-minikube/variables.tf","sha":"3da8530a497b5102a1bd8d88c473e15794e7f9d5"}]},{"name":"k8s-tiller-minikube","children":[{"name":"README.md","path":"examples/k8s-tiller-minikube/README.md","sha":"d579c9f2952bb63704def4d2c799a267e2ca3b2a"}]}]},{"name":"main.tf","path":"main.tf","sha":"506f789e6c7b0a9c767a683a4bc101498daef4d2"},{"name":"modules","children":[{"name":"k8s-helm-client-tls-certs","children":[{"name":"README.md","path":"modules/k8s-helm-client-tls-certs/README.md","sha":"4806c8188e5da43941b60b091133ad58f2537532"},{"name":"main.tf","path":"modules/k8s-helm-client-tls-certs/main.tf","sha":"f9727619e0606e5710d81934c541d94d528ee633"},{"name":"outputs.tf","path":"modules/k8s-helm-client-tls-certs/outputs.tf","sha":"59994511786075fe1a930e3ec6b46dd6134fff29"},{"name":"variables.tf","path":"modules/k8s-helm-client-tls-certs/variables.tf","sha":"445e4da760004173140af1176fa80b0cc8722a81"}]},{"name":"k8s-namespace-roles","children":[{"name":"README.md","path":"modules/k8s-namespace-roles/README.md","sha":"9aaca3f9e32408e23c02622d33942e0ce4586e34"},{"name":"main.tf","path":"modules/k8s-namespace-roles/main.tf","sha":"f82819379a8864bd6b9e71a8a18d815dbbc02559"},{"name":"outputs.tf","path":"modules/k8s-namespace-roles/outputs.tf","sha":"ab91d72a436cc5e450795182b4b43b78be207293"},{"name":"variables.tf","path":"modules/k8s-namespace-roles/variables.tf","sha":"0e5be83826073b0f786ff8f9b04826c555208758"}]},{"name":"k8s-namespace","children":[{"name":"README.md","path":"modules/k8s-namespace/README.md","sha":"4fa9469fbbd22faae11ac3f461487b2bfbe167e6","toggled":true},{"name":"main.tf","path":"modules/k8s-namespace/main.tf","sha":"eba9f2b3dbc0191d2d4bfe2931caac9b58122541"},{"name":"outputs.tf","path":"modules/k8s-namespace/outputs.tf","sha":"d8e2f96f44b67f9d0d59431c789b39609a745996"},{"name":"variables.tf","path":"modules/k8s-namespace/variables.tf","sha":"572a62e2ca963233931c527bab99fd9f0a3a048b"}],"toggled":true},{"name":"k8s-service-account","children":[{"name":"README.md","path":"modules/k8s-service-account/README.md","sha":"a53dfad1ff1d991dfed08fb5da77f9c15e3b6d50"},{"name":"main.tf","path":"modules/k8s-service-account/main.tf","sha":"3c5efa6c04722d679f1707ab49c118d39ef6a806"},{"name":"outputs.tf","path":"modules/k8s-service-account/outputs.tf","sha":"c5c2389e4646bb2a16b87bec129330e0c3c4dcf6"},{"name":"variables.tf","path":"modules/k8s-service-account/variables.tf","sha":"4f0cfad5f8a5869ff201fad385ecaa0de7454674"}]},{"name":"k8s-tiller-tls-certs","children":[{"name":"README.md","path":"modules/k8s-tiller-tls-certs/README.md","sha":"bf4e7de237e87459f8f617b6fa60f0ed1d94cd86"},{"name":"main.tf","path":"modules/k8s-tiller-tls-certs/main.tf","sha":"69d3adb8717f12381f0683c0ab37581975b5a8dc"},{"name":"outputs.tf","path":"modules/k8s-tiller-tls-certs/outputs.tf","sha":"1a4038f3a59478a9f2d4b76eef51817dd4200dc7"},{"name":"variables.tf","path":"modules/k8s-tiller-tls-certs/variables.tf","sha":"259ebea616195628a68b8eb8a1da83465cd0c782"}]},{"name":"k8s-tiller","children":[{"name":"README.md","path":"modules/k8s-tiller/README.md","sha":"7dec15a673134ebc488a070dc614d04c2bf538d3"},{"name":"main.tf","path":"modules/k8s-tiller/main.tf","sha":"c278eeebee9bc47d059f59a22916e5cc6dac1335"},{"name":"outputs.tf","path":"modules/k8s-tiller/outputs.tf","sha":"e23f872780e656e4f12578d439eb910692f59a60"},{"name":"variables.tf","path":"modules/k8s-tiller/variables.tf","sha":"5d03e38bfec082950d20c0f48865d7c5107f259f"}]}],"toggled":true},{"name":"outputs.tf","path":"outputs.tf","sha":"e81c16d641a0e30b706292ad37ce8b8ef343becb"},{"name":"test","children":[{"name":"Gopkg.lock","path":"test/Gopkg.lock","sha":"cdae09784de4638a1b0eea0525c3be70cebcf2d7"},{"name":"Gopkg.toml","path":"test/Gopkg.toml","sha":"a8644e81d7acf83db32419833ca1ca318d2559c1"},{"name":"README.md","path":"test/README.md","sha":"c4361f3756f62c10366b7302401e8a53552061bb"},{"name":"k8s_namespace_with_service_account_test.go","path":"test/k8s_namespace_with_service_account_test.go","sha":"8fac6e063e5c03371b681cdd48a98a8d27137712"},{"name":"k8s_tiller_kubergrunt_test.go","path":"test/k8s_tiller_kubergrunt_test.go","sha":"67f31a218feaa2840cdad23308b577f442bd3f4d"},{"name":"k8s_tiller_test.go","path":"test/k8s_tiller_test.go","sha":"7501db1bfc755b2709c688a5bbd1867b4238b44a"},{"name":"kubefixtures","children":[{"name":"curl-kubeapi-as-service-account.yml.tpl","path":"test/kubefixtures/curl-kubeapi-as-service-account.yml.tpl","sha":"12fa119c7e183bb8d35cda86322c92e6a36a5307"},{"name":"namespace-check-create-pod.json.tpl","path":"test/kubefixtures/namespace-check-create-pod.json.tpl","sha":"ba88dfa440d815c221febd455550dd6fdbe7cbac"},{"name":"namespace-check-list-pod.json.tpl","path":"test/kubefixtures/namespace-check-list-pod.json.tpl","sha":"047bb650ac081c5f63d9491cde3ca80b92603489"}]},{"name":"terratest_options.go","path":"test/terratest_options.go","sha":"675f98b4c34be584c9f7eea240f290949f08f460"}]},{"name":"variables.tf","path":"variables.tf","sha":"7efc75a2f7d990de3cdf52c7589e9468da6f4133"}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"k-8-s-namespace-module\">K8S Namespace Module</h1><div class=\"preview__body--border\"></div><p></p>\n<p>This Terraform Module manages Kubernetes\n<a href=\"https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/\" class=\"preview__body--description--blue\" target=\"_blank\"><code>Namespaces</code></a>. In addition to creating\nnamespaces, this module will create a set of default RBAC roles restricted to that namespace. The following roles will\nbe provided by this module:</p>\n<ul>\n<li><code>namespace-access-all</code>: Admin level permissions in the namespace. Ability to read, write, and delete all resources in\nthe namespace.</li>\n<li><code>namespace-access-read-only</code>: Read only permissions to all resources in the namespace.</li>\n<li><code>namespace-tiller-metadata-access</code>: Minimal permissions for Tiller to manage its metadata in this namespace (if this\nnamespace is where Tiller is deployed).</li>\n<li><code>namespace-tiller-resource-access</code>: Minimal permissions for Tiller to manage resources in this namespace as Helm\ncharts.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"how-do-you-use-this-module\">How do you use this module?</h2>\n<ul>\n<li>See the <a href=\"/repos/v0.6.1/terraform-kubernetes-helm/README.md\" class=\"preview__body--description--blue\">root README</a> for instructions on using Terraform modules.</li>\n<li>This module uses <a href=\"https://www.terraform.io/docs/providers/kubernetes/index.html\" class=\"preview__body--description--blue\" target=\"_blank\">the <code>kubernetes</code> provider</a>.</li>\n<li>See the <a href=\"/repos/v0.6.1/terraform-kubernetes-helm/examples\" class=\"preview__body--description--blue\">examples</a> folder for example\nusage.</li>\n<li>See <a href=\"/repos/v0.6.1/terraform-kubernetes-helm/modules/k8s-namespace/variables.tf\" class=\"preview__body--description--blue\">variables.tf</a>\nfor all the variables you can set on this module.</li>\n<li>See <a href=\"/repos/v0.6.1/terraform-kubernetes-helm/modules/k8s-namespace/outputs.tf\" class=\"preview__body--description--blue\">outputs.tf</a>\nfor all the variables that are outputed by this module.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"what-is-a-namespace\">What is a Namespace?</h2>\n<p>A <code>Namespace</code> is a Kubernetes resource that can be used to create a virtual environment in your cluster to separate\nresources. It allows you to scope resources in your cluster to provide finer grained permission control and resource\nquotas.</p>\n<p>For example, suppose that you have two different teams managing separate services independently, such that the team\nshould not be allowed to update or modify the other teams' services. In such a scenario, you would use namespaces to\nseparate the resources between each team, and implement RBAC roles that only grant access to the namespace if you reside\nin the team that manages it.</p>\n<p>To illustrate this, let's assume that we have a team that manages\nthe application services related to the core product (named <code>core</code>) and another team managing analytics services (named\n<code>analytics</code>). Let's also assume that we have already created RBAC groups for each team, named <code>core-group</code> and\n<code>analytics-group</code>.</p>\n<p>We create the namespaces using this module:</p>\n<pre>module <span class=\"hljs-string\">\"core_namespace\"</span> {\n <span class=\"hljs-attr\">source</span> = <span class=\"hljs-string\">\"git::https://github.com/gruntwork-io/terraform-kubernetes-helm.git//modules/k8s-namespace?ref=v0.1.0\"</span>\n <span class=\"hljs-attr\">name</span> = <span class=\"hljs-string\">\"core\"</span>\n}\n\nmodule <span class=\"hljs-string\">\"analytics_namespace\"</span> {\n <span class=\"hljs-attr\">source</span> = <span class=\"hljs-string\">\"git::https://github.com/gruntwork-io/terraform-kubernetes-helm.git//modules/k8s-namespace?ref=v0.1.0\"</span>\n <span class=\"hljs-attr\">name</span> = <span class=\"hljs-string\">\"analytics\"</span>\n}\n</pre>\n<p>In addition to creating namespaces, this will also create a set of RBAC roles that can then be bound to user and group\nentities to explicitly grant permissions to access that namespace.</p>\n<p>We can then use <code>kubectl</code> to bind the roles to the groups:</p>\n<pre><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">RoleBinding</span>\n<span class=\"hljs-attr\">apiVersion:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io/v1</span>\n<span class=\"hljs-attr\">metadata:</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">core-role-binding</span>\n <span class=\"hljs-attr\">namespace:</span> <span class=\"hljs-string\">core</span>\n<span class=\"hljs-attr\">subjects:</span>\n<span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">Group</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">core</span>\n <span class=\"hljs-attr\">apiGroup:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io</span>\n<span class=\"hljs-attr\">roleRef:</span>\n <span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">Role</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">core-access-all</span>\n <span class=\"hljs-attr\">apiGroup:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io</span>\n<span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">RoleBinding</span>\n<span class=\"hljs-attr\">apiVersion:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io/v1</span>\n<span class=\"hljs-attr\">metadata:</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">analytics-role-binding</span>\n <span class=\"hljs-attr\">namespace:</span> <span class=\"hljs-string\">analytics</span>\n<span class=\"hljs-attr\">subjects:</span>\n<span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">Group</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">analytics</span>\n <span class=\"hljs-attr\">apiGroup:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io</span>\n<span class=\"hljs-attr\">roleRef:</span>\n <span class=\"hljs-attr\">kind:</span> <span class=\"hljs-string\">Role</span>\n <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">analytics-access-all</span>\n <span class=\"hljs-attr\">apiGroup:</span> <span class=\"hljs-string\">rbac.authorization.k8s.io</span>\n</pre>\n<p>When we apply this config with <code>kubectl</code>, users that are associated with the <code>core</code> RBAC group can now create and access\nresources deployed in the <code>core</code> namespace, and the <code>analytics</code> group can access resources in the <code>analytics</code> namespace.\nHowever, members of the <code>core</code> team can not access resources in the <code>analytics</code> namespace and vice versa.</p>\n<p>To summarize, use namespaces to:</p>\n<ul>\n<li>Implement finer grained access control over deployed resources.</li>\n<li>Implement <a href=\"https://kubernetes.io/docs/concepts/policy/resource-quotas/\" class=\"preview__body--description--blue\" target=\"_blank\">resource quotas</a> to restrict how much of the\ncluster can be utilized by each team.</li>\n</ul>\n<h2 class=\"preview__body--subtitle\" id=\"why-is-this-a-terraform-module-and-not-a-helm-chart\">Why is this a Terraform Module and not a Helm Chart?</h2>\n<p>This module uses Terraform to manage the <code>Namespace</code> and RBAC role resources instead of using Helm to support the use case of\nsetting up Helm. When setting up the Helm server, you will want to setup a <code>Namespace</code> and <code>ServiceAccount</code> for the Helm\nserver to be deployed with. This leads to a chicken and egg problem, where the <code>Namespace</code> and <code>ServiceAccount</code> needs to\nbe created before Helm is available for use. As such, we rely on Terraform to set these core resources up.</p>\n","repoName":"terraform-kubernetes-helm","repoRef":"v0.6.1","serviceDescriptor":{"serviceName":"Tiller / Helm","serviceRepoName":"terraform-kubernetes-helm","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"Deploy Tiller (Helm Server) to your Kubernetes cluster as a service/package manager. Supports namespaces, service accounts, RBAC roles, and TLS.","imageUrl":"kubernetes.png","licenseType":"subscriber","technologies":["Terraform","Bash","Helm"],"compliance":[],"tags":[""]},"serviceCategoryName":"Docker services","fileName":"README.md","filePath":"/modules/k8s-namespace","title":"Repo Browser: Tiller / Helm","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}