Skip to content

Using Terraform and Ansible to provision an EKS version of the AWS architecture referenced in the whitepaper "Best Practices For WordPress on AWS"

Notifications You must be signed in to change notification settings

mjamalg/wp-project

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WP Project (EKS Version)

Disclaimer/Notice:

** IF YOU PROVISION THIS ARCHITECTURE THIS WILL COST MONEY!!! THIS WILL TAKE YOU OUT OF THE FREE TIER!!! I'VE TRIED MY BEST TO KEEP COSTS LOW BY USING THE SMALLEST INSTANCE CLASSES ALLOWED AND THE CHEAPEST CONFIGURATIONS. HOWEVER THERE WILL STILL BE COSTS ASSOCIATED. YOU'VE BEEN WARNED!!!!! **

About

This was a project I did for a prospective client to highlight the advantages of AWS EKS over the use of ECS to improve their deployment process. I also wanted to demonstrate how Ansible and Terraform could work in tandem for provisiong, configuation management, and security compliance. Most of all, I wanted to do all of this with as close to a "Production" level architecture as I could provision without spending the few coins I have AND the provisioning had to be automated.

The project is based on the AWS Whitepaper "Best Practices for WordPress on AWS" which you can download as a PDF here:

AWS Whitepaper: Best Practices for WordPress

https://docs.aws.amazon.com/pdfs/whitepapers/latest/best-practices-wordpress/best-practices-wordpress.pdf#welcome

Here's the original reference diagram from the whitepaper:

aws-presentation

I decided to modify the whitepaper architecture by adding an extra AZ, replacing EC2 instances with an EKS cluster, removing the Bastion Host (LOL) and adding extra functionality with helm charts for ExternalDNS, the AWS Load Balancer Controller, the External Secrets Operator for Kubernetes, and Bitnami's Wordpress for Kubernetes. Here's my version:

wp-project jpg

Additional services leveraged not included in the whitepaper:

  • AWS Certificate Manager (ACM)
  • AWS Secrets Manager (AWSSM)

Prerequisites

  • Intermediate level knowledge of:
    • AWS (especially IAM Roles for Service Accounts (IRSA))
    • Kubernetes
  • Novice level experience working with Wordpress.
AWS:
  • Administror level access to an AWS account and a user that has permissions to provision all services in AWS. Whatever user you use for Terraform should be sufficient.
  • A domain in Route 53 that you control with a public zone.
  • A FREE certificate created with the ACM for your domain (It's FREE).
System:
  • Python ≥ 3.10
  • pip and the following python libraries:
    • boto3
    • pyyaml
    • kubernetes
  • ansible-core ≥ 2.17
  • terraform ≥ 1.9.3
  • helm ≥ 3.16.1
  • eksctl ≥ 0.189.0
  • awscli ≥ v2
  • kubectl ≥ 1.30.5
  • k9s ≥ 0.30.4 (optional: only if you have experience using it to manage Kubernetes clusters)
System Alternative:

Feel free to use my Ubuntu based image that contains all the packages and libraries needed. I've also added my Dockerfile for you to create your own conatiner if you desire.

docker run -it mjsmoov97/wp-project-runenv:latest 

How To Provision

1. Clone the Repo
git clone git@github.com:mjamalg/wp-project.git
2. Update the following files:
  • In vpc-terraform
    • providers.tf:
      • Change to your desired region
      • Add your preferred AWS authentication information to the AWS provider definition.
  • In eks-ansible
    • roles/bitnami-wordpress-install/
      • defaults/main.yml:
        • Change "cert_domain" to your CERTIFICATE domain name.
        • Change "hostname" to whatever you want your wordpress domain to be. It could be your .com or a subdomain. It's your party!
      • templates/bitnami-wp-values.j2:
        • You can change the wordpress admin default username and password in this file.
    • roles/eks-addon-config/
      • files/external-dns-sa-config.yml:
        • Chage the external-dns image version to the latest if desired. v0.15.0 was the latest at the time of publishing. You can find the latest version here: ExternalDNS
        • Change the "-domain-filter" value to your domain name.
        • Change the Deployment "spec.template.spec.containers.env.name.value" to your desired region.
      • defaults/main.yml:
        • Change "cert_manager_helm_chart_version" to the desired version. 1.15.3 was the latest at the time of publishing. You can find the lastest version here: cert-manager
3. Provision the AWS architecture (total time betwen 30 - 50 minutes):
VPC

Run the following commands in the vpc-terraform directory:

terraform init && terraform apply -auto-approve

After Terraform is finished provisiong you should have the following resources and services:

  • A VPC Resource map that looks similar to this: wp-project-vpc-readme-1
  • A List of Security groups that look similar to this: wp-project-sgr-list-readme-1
  • An Aurora DB cluster using db.t3.medium instances: wp-project-aurora-readme-1
  • An EFS file system and 2 Access points: wp-project-efs-fs-readme-1 wp-project-efs-ap-readme-1
  • A 3 node Elasticache/Memcache cluster using cache.t3.micro instances wp-project-memcached-list-readme-2
  • A secret in Secrets Manager containing the Aurora DB password wp-project-secrets-mgr-list-readme
  • The folowing users creted in IAM:
    • external-secrets with an attached policy called "ESOSecretsManagerPolicy"
    • wpcdn with the AWS managed CloudFrontFullAccess policy attached

EKS

Run the following commands in the eks-ansible directory to deploy EKS:

ansible-playbook eksctl-config-file-create.yml
eksctl create cluster -f eksctl-config-files/eksctl-config.yml

After EKS is deployed, verify it's running and that you have access to it by running the following commands:

kubectl get nodes

wp-project-kubectl-check-readme-1

kubectl get namespaces

wp-project-kubectl-check-readme-2

Bitnami WP Install

Run the following command in the eks-ansible directory

ansible-playbook wp-eks-install.yml

The playbook has installed the AWS Load Balancer Controller, the External Secrets Operator (allows access to the Secrets Manager secret as a kubernetes secret), cert-manager, ExternalDNS (synchronizes exposed Kubernetes Services and Ingresses with Route 53) and Bitnami Wordpress for Kubernetes. There are a few things you should see:

Route 53

  • A TXT entry created by ExternalDNS
  • An A record (with and additional CNAME if you specified a subdomain for your hostname) created by ExternalDNS with an alias pointing to an ALB created by the AWS Load Balancer Controllers wp-project-route53-readme

ALB

  • There will be 2 load balancers created by the AWS Load Balancer Controller based on the ingress rules in the eks-ansible/roles/bitnami-wordpress-install/files/bitnami-wp-values.yml chart. An application load balancer and a network load balancer. wp-proejct-loadbalancers-README

EKS

  • There should be 3 wordpress pods running in the wordpress namespace:
    kubectl get pods -n wordpress
    
    wp-project-bitnami-kubectl-readme-1

After verifying the pods are running check the pod log to make sure apache has started and the pods are accepting connectins from the Wordpress service:

kubectl logs [enter a pod listed from the previous command] -n wordpress

wp-project-bitnami-readme-2

Depending on DNS, your TTL's, or how long it takes for the load balancers status to change to "Active", it may take between 10 minutes and even 2 hours before you'll be able to see the default WP page when you go to your browser: wp-project-home-page A full tutorial on how to use and configure Wordpress is beyond the scope of this project. However I will add a couple of pointers for you to help you get started.

  • Wordpress uses the W3 Total Cache plugin for Memcached and CDN configuration. The plugin will not work with AWS Elasticache out of the box. A way forward may be found here:
  • Here's a link to an excellent tutorial on how to configure the plugin to work with CloudFront. The wpcdn user has been created for you to do this. The Access Key and Secret Access Key for the user will be located in eks-ansible/roles/bitnami-wordpress-install/files/wpcdn-user-credentials.json provided you ran the wp-eks-install.yml playbook successfully.

Removing All Resources

1. Uninstall the Bitnami WordPress helm chart

This gracefully removes the entry made in the Route 53 host zone by ExternalDNS. If you know anything about DNS you know this comes under MUST DO!

helm uninstall my-release --namespace wordpress
2. Use eskctl to delete the EKS cluster (will take between 15 - 30 minutes)

Run the following command in the eks-ansible directory:

eksctl delete cluster -f eksctl-config-files/eksctl-config.yml
3. Terraform destory (will take between 15 - 30 minutes)

Run the following command the vpc-terraform directory:

terraform destory -auto-approve

Q.E.D

About

Using Terraform and Ansible to provision an EKS version of the AWS architecture referenced in the whitepaper "Best Practices For WordPress on AWS"

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published