/terraform-eks

Primary LanguageHCLMIT LicenseMIT

Terraform EKS app

In this repository, a simple Python app is stored along with infrastructure for its deployment. Once installed, the app responds with{"Hello":"World"} json at root, allows simple querying at /items endpoint (e.g. /items/5?q=somequery) and provides documentation at /docs endpoint.

Prerequirements


IMPORTANT: this setup is tested on Ubuntu 22.04 but should work on most Linux machines.

  • All operations and processes are intended to be performed on a local Linux machine with the following toolset installed:

    Tool Version
    Docker 20.10.21
    kubectl v1.25.4
    helm v3.10.2
    terraform v1.3.5
    aws-cli 2.9.0
    jq 1.6
  • AWS CLI must be configured as per the documentation.

    IMPORTANT: an IAM user with Administrator permissions must be used for this setup to work correctly.

  • To work locally with a dummy app Python ~> 3.11.0 is required as well as modules from requirements.txt.

Quick start


To bring up all infrastructure and install the application run the following command:

make up-all

The following infrastructure in AWS is created as a result:

  • VPC with subnets
  • Security group
  • EKS cluster with:
    • A single node of t3.small size
    • NGINX ingress controller with corresponding NLB
    • Namespace for the application (default name: dummy-app)
  • Private repository in ECR (default repository name: dummy-app)

After all the infrastructure is deployed successfully, the application is installed via Helm-chart into the namespace for the application.

To check the application locally run:

make local-check

This command will create port forwarding from the app inside EKS to local port 8080, open http://localhost:8080/.

Check ingress with custom domain name


To check that ingress is functional use the output of the command:

make get-lb-ip

to set up a CNAME record in DNS zone of a custom domain and then reinstall the application with this domain specified as follows (APP_HOSTNAME variable can also be exported):

make APP_HOSTNAME=app.example.com helm-deploy

For more details see the documentation.

Repository structure and components


Application code and configuration are placed into separate folders per component. The following is the description of each component.

Python dummy application


Stored at ./app/

This is an example application taken directly from FastAPI documentaion.

It has been tested with Python 3.11.0 and thus doesn't require a typing module manual installation.

To run the app locally create and activate venv:

python -m venv ./
source bin/activate

Then install requirements.txt:

pip install -r ./requirements.txt

And start uvicorn:

uvicorn main:app --reload

Dockerfile


Stored at ./docker/

Consists of a single Dockerfile that's build and pushed to ECR.

Application Helm-chart


The dummy application Helm-chart is based on default Nginx-chart that is generated via helm create command.

Deployment with a single replica and corresponding service and ingress are created by default.

Only default values are provided with repository and tag being set during deploy. Simple liveness and readiness probes are configured for the deployment.

Terraform configuration


All terraform files are placed in the root module with local namespaces module. Detailed information about providers, resources etc. can be found in the subfolder's README file.

Makefile reference


  • up-all - brings up the entire infrastructure and installs the application
  • up-infra - brings up entire infrastructure
  • up-app - builds app-image, pushes it to ECR and install the app via Helm-chart
  • build-and-push - builds app-image and pushes it to ECR
  • docker-build - builds app-image (requires docker-login)
  • docker-login - logs into a previously created repository in ECR (requires configure-kubectl)
  • docker-push - pushes app-image to ECR (requires docker-build)
  • helm-dry-run - dry-runs Helm chart without installation
  • helm-deploy - deploys Helm-chart
  • local-check - creates port forwarding from app in EKS to local port 8080
  • get-lb-ip - returns NLB address
  • configure-kubectl - auto-configures kubectl to work with created EKS
  • auto-terraform-% - wrapper for auto-approved terraform commands (apply, destroy)