{"id":28586912,"url":"https://github.com/ariesyous/terraform-eks-demo","last_synced_at":"2026-04-12T17:05:07.150Z","repository":{"id":294068936,"uuid":"985011099","full_name":"ariesyous/terraform-eks-demo","owner":"ariesyous","description":"Terraform scripts to deploy an AWS EKS cluster with self‑managed EC2 worker nodes enforcing SELinux, plus a simple nginx demo app.","archived":false,"fork":false,"pushed_at":"2025-05-18T19:11:07.000Z","size":55,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-11T07:09:38.649Z","etag":null,"topics":["aws","eks","kubernetes","nginx","selinux","terraform"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ariesyous.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-16T22:44:05.000Z","updated_at":"2025-05-19T13:26:00.000Z","dependencies_parsed_at":"2025-05-18T19:45:49.517Z","dependency_job_id":null,"html_url":"https://github.com/ariesyous/terraform-eks-demo","commit_stats":null,"previous_names":["ariesyous/terraform-eks-demo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ariesyous/terraform-eks-demo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariesyous%2Fterraform-eks-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariesyous%2Fterraform-eks-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariesyous%2Fterraform-eks-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariesyous%2Fterraform-eks-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ariesyous","download_url":"https://codeload.github.com/ariesyous/terraform-eks-demo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ariesyous%2Fterraform-eks-demo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270149345,"owners_count":24535728,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","eks","kubernetes","nginx","selinux","terraform"],"created_at":"2025-06-11T07:01:08.986Z","updated_at":"2026-04-12T17:05:07.116Z","avatar_url":"https://github.com/ariesyous.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-eks-demo\nThis GitHub repository contains files that you can use to set up an EKS cluster with self managed EC2 worker nodes in an AWS region of your choice (by default, it's us-east-1). The worker nodes have a few system utilities installed via cloud-init, and have SELinux set to Enforce mode prior to the nodes joining the cluster. \n\nIt also contains a simple application you can deploy into the Kubernetes cluster to test it out (it's a simple nginx server). \n\nInstructions are below on how you can get this setup and running. For an FAQ, scroll down or click [here](#FAQ).\n\n# How to get up and running\n\nStep 1. Install [terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli), [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html), and [kubectl](https://kubernetes.io/docs/tasks/tools/) on your local machine. \n\nStep 2. Clone this git repo to your local machine. \n\nStep 3. Set up the proper AWS IAM role in your AWS account first (this is the role you'll assume when you're running the Terraform, and when you are administering the EKS cluster). \n\nEasiest way to do this is via the AWS Management Console CloudShell in your AWS account if you're logged in as root, or with a user account that has the AdministratorAccess role. Use the existing `terraform.json` file in the `/scripts/` folder which contains all needed permissions. You can copy and paste the entire `terraform.json` file into your AWS CloudShell, and run the commands below in order to reference them when setting up your `TerraformRole` credentials.\n\nNote your AWS account ID, we will use 0123456789012 as a placeholder. Change this to your AWS account's ID. \n\n    aws iam create-role \\\n      --role-name TerraformRole \\\n      --assume-role-policy-document '{\n        \"Version\": \"2012-10-17\",\n        \"Statement\": [{\n          \"Effect\":\"Allow\",\n          \"Principal\":{ \"AWS\":\"arn:aws:iam::0123456789012:user/TerraformUser\" },\n          \"Action\":\"sts:AssumeRole\"\n        }]\n      }'\n    \n    # Attach the policy\n\n    # Make sure you have the terraform.json from the /scripts/ folder present in CloudShell before running this command\n    \n    aws iam put-role-policy \\\n      --role-name TerraformRole \\\n      --policy-name TerraformPolicy \\\n      --policy-document file://terraform.json\n    \n    aws iam create-user --user-name TerraformUser\n    \n    # Allow it to sts:AssumeRole on TerraformRole\n    \n    aws iam put-user-policy \\\n      --user-name TerraformUser \\\n      --policy-name AllowAssumeTerraformRole \\\n      --policy-document '{\n        \"Version\": \"2012-10-17\",\n        \"Statement\":[ {\n          \"Effect\":\"Allow\",\n          \"Action\":\"sts:AssumeRole\",\n          \"Resource\":\"arn:aws:iam::0123456789012:role/TerraformRole\"\n        }]\n      }'\n      \n      # Finally, generate access keys\n      aws iam create-access-key --user-name TerraformUser\n      # note the AccessKeyId and SecretAccessKey output here\n\nIt's also useful to update your local `~/.aws/config` file, where your profile can be stored. One way to do this is by `aws configure` and following the interactive prompts. Below is a sample `~/.aws/config` file you can also reference.\n\n    [default]\n    region = us-east-1\n    output = json\n    \n    [profile terraform-role]\n    role_arn = arn:aws:iam::0123456789012:role/TerraformRole\n    source_profile = default\n    region = us-east-1\n\n\n\nStep 4. This step is *optional*, but **highly recommended**.  For security, it's worth changing the `cluster_endpoint_public_access_cidr` to your local IP address, to prevent the Kubernetes cluster endpoint from being accessible to anyone. Determine your IPv4 address by going to https://whatismyipaddress.com/. Under `module eks` in `main.tf`, change the value for `cluster_endpoint_public_access_cidr` to your IP address and use `/32` as the mask. \n   \n    cluster_endpoint_public_access_cidrs  =  [\"1.2.3.4/32\"]\n\n\nStep 5. Step 5. From the root of the repository folder, do a terraform init to pull all needed Terraform modules, followed by terraform plan and apply to deploy the AWS infrastructure. You can optionally specify a unique environment for each cluster if you'd prefer (eg, dev, stage, prod), but default will be dev if you omit the variable.\n\n    terraform init\n    \n    terraform plan -var=\"env=dev\"\n    \n    terraform apply -var=\"env=dev\" \n\nThis will take about 5-10 minutes to set up all necessary components, including the Kubernetes cluster itself.\n\nStep 6. Once cluster is up, refresh your kubectl credentials check the nodes being online through kubectl get nodes, include instructions on how to set this up locally.\n\n    # Get fresh credentials\n    \n    unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN\n    \n    aws sts assume-role \\\n      --role-arn arn:aws:iam::0123456789012:role/TerraformRole \\\n      --role-session-name eks-admin \u003e credentials.json\n    \n    export AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId credentials.json)\n    export AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey credentials.json)\n    export AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken credentials.json)\n    \n    # Update kubeconfig with explicit role credentials\n    # Change --name and --region to your desired settings if they were different from the default\n    \n    aws eks update-kubeconfig --name dev-eks --region us-east-1\n\n    # Check to see if your worker nodes are online\n    \n    kubectl get nodes\n\nStep 7. Now once the nodes are online, go ahead and deploy the sample app through kubectl apply.\n\n    kubectl apply -f app.yaml\n\nStep 8. Check the deployment and service (kubectl get services), and go to the URL to make sure its online\n\n    kubectl get services\n\nStep 9. **You're done**. To clean up, delete your deployment (kubectl delete -f app.yaml), and then terraform destroy.\n\n    # Clean up \n    kubectl delete -f app.yaml\n    terraform destroy\n\n  \n  \n  \n\n# To refresh your kubectl credentials\n\nYou'll need do this after bringing up your EKS cluster for the first time, and periodically depending on how long you're working on the cluster. If you ever get an error preventing you from authenticating with the kubectl cluster, this is likely why.\n\n    # Clear existing config\n    rm ~/.kube/config\n    \n    # Get fresh credentials\n    unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN\n    \n    aws sts assume-role \\\n      --role-arn arn:aws:iam::0123456789012:role/TerraformRole \\\n      --role-session-name eks-admin \u003e credentials.json\n    \n    export AWS_ACCESS_KEY_ID=$(jq -r .Credentials.AccessKeyId credentials.json)\n    export AWS_SECRET_ACCESS_KEY=$(jq -r .Credentials.SecretAccessKey credentials.json)\n    export AWS_SESSION_TOKEN=$(jq -r .Credentials.SessionToken credentials.json)\n    \n    # Update kubeconfig with explicit role credentials\n    # Change --name and --region to your desired settings if they were different from the default\n    aws eks update-kubeconfig --name dev-eks --region us-east-1\n\nNow you should be able to issue kubectl commands again without encountering authentication issues!\n\n## FAQ\n\n### Q: What is Terraform and why are we using it here?\n\n**A:** Terraform is an “infrastructure as code” tool that lets you describe AWS resources (VPCs, EKS clusters, IAM roles, etc.) in simple configuration files. When you run `terraform apply`, Terraform creates, updates, or destroys those resources for you—so you never have to click around in the Console. It keeps track of what’s been applied and shows you a plan before making changes.\n\n### Q: What is Amazon EKS?\n\n**A:** EKS (Elastic Kubernetes Service) is AWS’s managed Kubernetes control plane. It runs `etcd`, `kube‑apiserver`, `controller-manager`, etc., in AWS‑managed accounts, and exposes a highly available API endpoint. You still need to supply “worker nodes” (EC2 instances) to actually run your containers.\n\n### Q: What is **cloud‑init** and how does it work with EC2?\n\n**A:** Cloud‑init is the “user‑data” engine on most AWS AMIs. When an EC2 instance first boots, it looks at the `user_data` you provided (our bootstrap script) and executes it. We inject our security updates, custom tooling installs, and SELinux configuration here _before_ the node runs `kubeadm join`.\n\n### Q: Why do we use **self‑managed** worker nodes instead of EKS **managed node groups**?\n\n**A:** Self‑managed nodes give you full control over the EC2 instances, the AMI they use, and their user‑data (e.g. SELinux enforcement, custom tools, etc.). Managed node groups are easier to stand up, but less flexible if you need to run custom bootstrap logic.\n\n### Q: What is **SELinux**, and why enforce it on EKS nodes?\n\n**A:** SELinux is a Linux kernel feature that confines processes to strict security policies. By switching from “permissive” to “enforcing” mode, we reduce the blast radius if one of our processes is compromised. Enforcing mode ensures `kubelet`, `containerd`, and your workloads only have the minimal permissions they need.\n\n### Q: How much will running this EKS cluster cost me?\n\n**A:** Rough estimates (prices at May 2025, US‑East 1):\n\n-   Control plane: **$0.10/hour** (~$72 USD/month)\n    \n-   EC2 t3.medium nodes: **$0.0416/hour** each (~$30 USD/month per node)\n    \n-   NAT Gateway, Data Transfer, EBS volumes, etc., will add extra.  \n    Always tear down with `terraform destroy` when you’re not using it!\n\n### Q: Approximately how long does deployment take?\n\n**A:**\n\n-   **Terraform apply**: 5–10 minutes to create VPC, IAM, and control plane.\n    \n-   **Node boot \u0026 join**: another 5–7 minutes per node (cloud‑init, security updates, SELinux enforcement, kubeadm join).  \n    Total: roughly 10–15 minutes.\n\n### Q: I’m seeing `Error: Unauthorized` or `AccessDenied`; what do I check?\n\n1.  **Are you using the right AWS credentials?**\n    \n    -   Confirm you’ve `aws sts assume-role` into the `TerraformRole`.\n        \n    -   Check `echo $AWS_ACCESS_KEY_ID` matches what you expect.\n        \n2.  **Does your role have the necessary policies?**\n    \n    -   Review the attached IAM policy in the bootstrap role; make sure it includes `eks:*`, `ec2:*`, `iam:PassRole`, etc.\n\n### Q: How can I customize the cluster name or environment?\n\nEdit the `-var=\"env=dev\"` on the command line (e.g. `-var=\"env=staging\"`), and Terraform will automatically prefix the VPC, cluster, and node‑group names with that string.\n\n### Q: Where do I find the sample application manifests?\n\nThey live in the repo at **`app.yaml`** (an Nginx Deployment + Service). You can modify that file or point to your own `.yaml` under **Step 7**.\n\n### Q: How do I access the sample application once it’s deployed?\n\n1.  Run `kubectl get svc nginx-svc -o wide` to see its **EXTERNAL-IP**.\n    \n2.  Open that IP in your browser on port 80.\n    \n    -   If you see a default Nginx page, you’re all set!\n\n### Q: How do I update the bootstrap script or install additional tools?\n\n-   Edit your shell snippet in the `cloudinit_pre_nodeadm` (or inline HEREDOC) block in `main.tf`.\n    \n-   Set `force_update_version = true` under your node‑group to roll out a new launch template version.\n    \n-   Run `terraform apply` again; your nodes will be replaced with the updated user‑data.\n\n\n\n### Q: Which AWS credentials does Terraform use?\n\nTerraform will use the AWS CLI’s default credential chain. You can either export `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (and `AWS_SESSION_TOKEN` if you’re assuming a role), or configure a profile in `~/.aws/config` and run:\n\n`AWS_PROFILE=terraform-role terraform plan ‑var=\"env=dev\"`\n\n### Q: Why do I need to assume an IAM role before running Terraform?\n\nFollowing best practices, we create a dedicated **TerraformRole** (with exactly the permissions your scripts need). You assume that role to get short‑lived credentials, instead of using long‑lived root or user keys. See **Step 3** in the README for how to `sts assume-role`.\n\n### Q: How do I restrict access to my EKS control plane?\n\nEdit the `cluster_endpoint_public_access_cidrs` list in `main.tf` to only include your IP (e.g. `[\"1.2.3.4/32\"]`). Then `terraform apply`—the API server will refuse connections from any other source.\n\n### Q: How can I change the AWS region or account?\n\n-   **Region**: either set `AWS_DEFAULT_REGION`, configure it in `~/.aws/config`, or pass `-var=\"region=us-west-2\"` if you add a `region` variable.\n    \n-   **Account**: Terraform writes resources into whichever AWS account your credentials point at; switch profiles or assume a different role for another account.\n\n\n### Q: How do I tear everything down?\n\n1.  Delete your test app:\n    \n    `kubectl delete -f app.yaml` \n    \n2.  Destroy all Terraform‑managed resources:\n    \n    `terraform destroy -var=\"env=dev\"` \n    \n    This will remove the EKS cluster, nodes, VPC, and IAM roles you created.\n\n### Q: Where can I go for more help?\n\n-   **Terraform docs**: [https://registry.terraform.io/](https://registry.terraform.io/)\n    \n-   **AWS EKS User Guide**: [https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html)\n    \n-   **Kubernetes docs**: [https://kubernetes.io/docs/](https://kubernetes.io/docs/)\n    \n-   **Cloud‑Init reference**: [https://cloudinit.readthedocs.io/](https://cloudinit.readthedocs.io/)\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariesyous%2Fterraform-eks-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fariesyous%2Fterraform-eks-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fariesyous%2Fterraform-eks-demo/lists"}