FusionAuth developer image
FusionAuth developer logo
  • Back to site
  • Expert Advice
  • Blog
  • Developers
  • Downloads
  • Account
  • Contact sales
Navigate to...
  • Welcome
  • Getting Started
  • 5-Minute Setup Guide
  • Release Notes
  • Core Concepts
    • Overview
    • Users
    • Roles
    • Groups
    • Entity Management
    • Registrations
    • Applications
    • Tenants
    • Identity Providers
    • Key Master
    • SCIM
    • Search
    • Authentication and Authorization
    • Integration Points
    • Localization and Internationalization
    • Editions and Features
    • Roadmap
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Licensing
    • Monitoring
    • Proxy Setup
    • Securing
    • Technical Support
    • Troubleshooting
    • Upgrading
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Tutorial
  • APIs
    • Overview
    • Authentication
    • Errors
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Kafka
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM EnterpriseUser
      • SCIM Group
      • SCIM Service Provider Config.
      • SCIM User
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • Webhooks
  • Client Libraries
    • Overview
    • Dart
    • Go
    • Java
    • JavaScript
    • .NET Core
    • Node
    • OpenAPI
    • PHP
    • Python
    • Ruby
    • Typescript
  • Themes
    • Overview
    • Examples
    • Helpers
    • Localization
    • Template Variables
  • Email & Templates
    • Overview
    • Configure Email
    • Email Templates
    • Email Variables
    • Message Templates
  • Events & Webhooks
    • Overview
    • Writing a Webhook
    • Securing Webhooks
    • Events
      • Overview
      • Audit Log Create
      • Event Log Create
      • JWT Public Key Update
      • JWT Refresh
      • JWT Refresh Token Revoke
      • Kickstart Success
      • User Action
      • User Bulk Create
      • User Create
      • User Create Complete
      • User Deactivate
      • User Delete
      • User Delete Complete
      • User Email Update
      • User Email Verified
      • User IdP Link
      • User IdP Unlink
      • User Login Failed
      • User Login Id Duplicate Create
      • User Login Id Duplicate Update
      • User Login New Device
      • User Login Success
      • User Login Suspicious
      • User Password Breach
      • User Password Reset Send
      • User Password Reset Start
      • User Password Reset Success
      • User Password Update
      • User Reactivate
      • User Registration Create
      • User Registration Create Complete
      • User Registration Delete
      • User Registration Delete Complete
      • User Registration Update
      • User Registration Update Complete
      • User Registration Verified
      • User Two Factor Method Add
      • User Two Factor Method Remove
      • User Update
      • User Update Complete
  • Example Apps
    • Overview
    • Dart
    • Go
    • Java
    • JavaScript
    • .NET Core
    • PHP
    • Python
    • Ruby
  • Lambdas
    • Overview
    • Apple Reconcile
    • Client Cred. JWT Populate
    • Epic Games Reconcile
    • External JWT Reconcile
    • Facebook Reconcile
    • Google Reconcile
    • HYPR Reconcile
    • JWT Populate
    • LDAP Connector Reconcile
    • LinkedIn Reconcile
    • Nintendo Reconcile
    • OpenID Connect Reconcile
    • SAML v2 Populate
    • SAML v2 Reconcile
    • SCIM Group Req. Converter
    • SCIM Group Resp. Converter
    • SCIM User Req. Converter
    • SCIM User Resp. Converter
    • Sony PSN Reconcile
    • Steam Reconcile
    • Twitch Reconcile
    • Twitter Reconcile
    • Xbox Reconcile
  • Identity Providers
    • Overview
    • Apple
    • Epic Games
    • External JWT
      • Overview
      • Example
    • Facebook
    • Google
    • HYPR
    • LinkedIn
    • Nintendo
    • OpenID Connect
      • Overview
      • Azure AD
      • Discord
      • Github
    • Sony PlayStation Network
    • Steam
    • Twitch
    • Twitter
    • SAML v2
      • Overview
      • ADFS
    • SAML v2 IdP Initiated
      • Overview
      • Okta
    • Xbox
  • Messengers
    • Overview
    • Generic Messenger
    • Kafka Messenger
    • Twilio Messenger
  • Connectors
    • Overview
    • Generic Connector
    • LDAP Connector
    • FusionAuth Connector
  • Self Service Account Mgmt
    • Overview
    • Updating User Data & Password
    • Add Two-Factor Authenticator
    • Add Two-Factor Email
    • Add Two-Factor SMS
    • Customizing
    • Troubleshooting
  • Advanced Threat Detection
    • Overview
  • Integrations
    • Overview
    • CleanSpeak
    • Kafka
    • Twilio
  • OpenID Connect & OAuth 2.0
    • Overview
    • Endpoints
    • Tokens
  • SAML v2 IdP
    • Overview
    • Google
    • Zendesk
  • Plugins
    • Plugins
    • Writing a Plugin
    • Custom Password Hashing
  • Guides
    • Overview
    • Advanced Registration Forms
    • Breached Password Detection
    • Multi-Factor Authentication
    • Multi-Tenant
    • Passwordless
    • Securing Your APIs
    • Silent Mode
    • Single Sign-on
  • Tutorials
    • Overview
    • User Control & Gating
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
    • Setup Wizard & First Login
    • Register/Login a User
    • Start and Stop FusionAuth
    • Authentication Tokens
    • Key Rotation
    • JSON Web Tokens
    • Prometheus Setup
    • Switch Search Engines
    • Two Factor (pre 1.26)
  • Reference
    • CORS
    • Configuration
    • Data Types
    • Known Limitations
    • Password Hashes

    Provision an Amazon Elastic Kubernetes Service (EKS) Kubernetes Cluster

    Overview

    This guide will show you how to quickly set up an EKS cluster in AWS. When completed, you will have a fully functional Kubernetes cluster ready for a FusionAuth deployment. The following method uses the default settings when provisioning the EKS cluster with the required resources and services.

    Required Tools

    • AWS CLI - Amazon Command Line Interface. This allows users to interact with AWS resources and services from the command-line. For more information, see Installing, updating, and uninstalling the AWS CLI. This will need to be installed and configured for a user with IAM permissions to manage EKS.

    • eksctl - For this guide, you will use eksctl, a command line tool for managing EKS clusters. For installation information, see The eksctl command line utility.

    • kubectl - Command line tool that interacts with the Kubernetes API server and is useful for managing Kubernetes clusters. Before proceeding, follow the installation documentation that corresponds to your platform found here. This guide will be using version 1.22

    Architecture

    The resulting EKS cluster will use a dedicated VPC with two availability zones, each consisting of a public and private subnet. It will use an autoscaling node group with a node (Linux EC2 instance) in each private subnet. Additionally, you will provision a PostgreSQL RDS instance to satisfy installation requirements of FusionAuth.

    For the remainder of this guide, the value used for region will be us-west-1.

    EKS Architecture

    Create an EKS Cluster

    Prior to creating the cluster, either create a new key pair or have an existing pair on hand. This is because providing a key when running the create command configures EKS to allow SSH access to the created compute nodes. If a key is not provided, this can not be changed later. Having SSH access allows for easier troubleshooting.

    Create key pair
    aws ec2 create-key-pair --region us-west-1 --key-name eksExampleKeyPair

    If successful, information about your new key will be displayed. Store the private key for future use.

    Now create a new EKS cluster.

    Create EKS cluster
    eksctl create cluster \
    --name fusionauth-example \
    --region us-west-1 \
    --with-oidc \
    --ssh-access \
    --ssh-public-key eksExampleKeyPair

    This command uses CloudFormation to provision all of the necessary resources that your EKS cluster needs. You should see output that looks something like this:

    CloudFormation output
    2021-10-05 14:18:03 [ℹ]  eksctl version 0.66.0
    2021-10-05 14:18:03 [ℹ]  using region us-west-1
    2021-10-05 14:18:03 [ℹ]  setting availability zones to [us-west-1a us-west-1c us-west-1a]
    2021-10-05 14:18:03 [ℹ]  subnets for us-west-1a - public:192.168.0.0/19 private:192.168.96.0/19
    2021-10-05 14:18:03 [ℹ]  subnets for us-west-1c - public:192.168.32.0/19 private:192.168.128.0/19
    2021-10-05 14:18:03 [ℹ]  subnets for us-west-1a - public:192.168.64.0/19 private:192.168.160.0/19
    2021-10-05 14:18:03 [ℹ]  nodegroup "ng-3fa00736" will use "" [AmazonLinux2/1.20]
    2021-10-05 14:18:03 [ℹ]  using EC2 key pair %!q(*string=<nil>)
    2021-10-05 14:18:03 [ℹ]  using Kubernetes version 1.20
    2021-10-05 14:18:03 [ℹ]  creating EKS cluster "fusionauth-example" in "us-west-1" region with managed nodes
    2021-10-05 14:18:03 [ℹ]  will create 2 separate CloudFormation stacks for cluster itself and the initial managed nodegroup
    2021-10-05 14:18:03 [ℹ]  if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=us-west-1 --cluster=fusionauth-example'
    2021-10-05 14:18:03 [ℹ]  CloudWatch logging will not be enabled for cluster "fusionauth-example" in "us-west-1"
    2021-10-05 14:18:03 [ℹ]  you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=us-west-1 --cluster=fusionauth-example'
    2021-10-05 14:18:03 [ℹ]  Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "fusionauth-example" in "us-west-1"
    2021-10-05 14:18:03 [ℹ]  2 sequential tasks: { create cluster control plane "fusionauth-example", 3 sequential sub-tasks: { 4 sequential sub-tasks: { wait for control plane to become ready, associate IAM OIDC provider, 2 sequential sub-tasks: { create IAM role for serviceaccount "kube-system/aws-node", create serviceaccount "kube-system/aws-node" }, restart daemonset "kube-system/aws-node" }, 1 task: { create addons }, create managed nodegroup "ng-3fa00736" } }
    2021-10-05 14:18:03 [ℹ]  building cluster stack "eksctl-fusionauth-example-cluster"
    2021-10-05 14:18:04 [ℹ]  deploying stack "eksctl-fusionauth-example-cluster"
    2021-10-05 14:31:07 [ℹ]  waiting for CloudFormation stack "eksctl-fusionauth-example-cluster"
    2021-10-05 14:35:10 [ℹ]  building iamserviceaccount stack "eksctl-fusionauth-example-addon-iamserviceaccount-kube-system-aws-node"
    2021-10-05 14:35:11 [ℹ]  deploying stack "eksctl-fusionauth-example-addon-iamserviceaccount-kube-system-aws-node"
    2021-10-05 14:35:11 [ℹ]  waiting for CloudFormation stack "eksctl-fusionauth-example-addon-iamserviceaccount-kube-system-aws-node"
    2021-10-05 14:35:27 [ℹ]  waiting for CloudFormation stack "eksctl-fusionauth-example-addon-iamserviceaccount-kube-system-aws-node"
    2021-10-05 14:35:44 [ℹ]  waiting for CloudFormation stack "eksctl-fusionauth-example-addon-iamserviceaccount-kube-system-aws-node"
    2021-10-05 14:35:45 [ℹ]  serviceaccount "kube-system/aws-node" already exists
    2021-10-05 14:35:45 [ℹ]  updated serviceaccount "kube-system/aws-node"
    2021-10-05 14:35:45 [ℹ]  daemonset "kube-system/aws-node" restarted
    2021-10-05 14:37:46 [ℹ]  building managed nodegroup stack "eksctl-fusionauth-example-nodegroup-ng-3fa00736"
    2021-10-05 14:37:46 [ℹ]  deploying stack "eksctl-fusionauth-example-nodegroup-ng-3fa00736"
    2021-10-05 14:37:46 [ℹ]  waiting for CloudFormation stack "eksctl-fusionauth-example-nodegroup-ng-3fa00736"
    2021-10-05 14:41:48 [ℹ]  waiting for the control plane availability...
    2021-10-05 14:41:48 [✔]  saved kubeconfig as "/Users/brettguy/.kube/config"
    2021-10-05 14:41:48 [ℹ]  no tasks
    2021-10-05 14:41:48 [✔]  all EKS cluster resources for "fusionauth-example" have been created
    2021-10-05 14:41:48 [ℹ]  nodegroup "ng-3fa00736" has 2 node(s)
    2021-10-05 14:41:48 [ℹ]  node "ip-192-168-45-153.us-west-1.compute.internal" is ready
    2021-10-05 14:41:48 [ℹ]  node "ip-192-168-91-228.us-west-1.compute.internal" is ready
    2021-10-05 14:41:48 [ℹ]  waiting for at least 2 node(s) to become ready in "ng-3fa00736"
    2021-10-05 14:41:48 [ℹ]  nodegroup "ng-3fa00736" has 2 node(s)
    2021-10-05 14:41:48 [ℹ]  node "ip-192-168-45-153.us-west-1.compute.internal" is ready
    2021-10-05 14:41:48 [ℹ]  node "ip-192-168-91-228.us-west-1.compute.internal" is ready
    2021-10-05 14:43:50 [ℹ]  kubectl command should work with "/Users/myuser/.kube/config", try 'kubectl get nodes'
    2021-10-05 14:43:50 [✔]  EKS cluster "fusionauth-example" in "us-west-1" region is ready

    We now have a fully functional provisioned EKS cluster. You will need additional information, in particular the VPC Id, subnet Ids, and security group Id, all of which are used later in this guide. Use the CLI to describe our newly created cluster to retrieve this configuration data.

    Get cluster information
    aws eks describe-cluster --name fusionauth-example
    Cluster information JSON output
    {
        "cluster": {
            "name": "fusionauth-example",
            "arn": "arn:aws:eks:us-west-1:<ACCOUNT_ID>:cluster/fusionauth-example",
            "createdAt": "2021-10-05T14:19:21.612000-06:00",
            "version": "1.20",
            "endpoint": "https://EC8E2DC8514200E91A4748FA6EE525A4.yl4.us-west-1.eks.amazonaws.com",
            "roleArn": "arn:aws:iam::<ACCOUNT_ID>:role/<role-name>",
            "resourcesVpcConfig": {
                "subnetIds": [
                    "subnet-091347798a21eabe2",
                    "subnet-0cb7540073e8b30aa",
                    "subnet-052f8750345045581",
                    "subnet-040e32678cf7a85da"
                ],
                "securityGroupIds": [
                    "sg-00d13e92c29ed1ecf"
                ],
                "clusterSecurityGroupId": "sg-07cf61370371ba323",
                "vpcId": "vpc-08da2a4800ea6e0e2",
                "endpointPublicAccess": true,
                "endpointPrivateAccess": false,
                "publicAccessCidrs": [
                    "0.0.0.0/0"
                ]
            },
            "kubernetesNetworkConfig": {
                "serviceIpv4Cidr": "10.100.0.0/16"
            }
        }
    }

    Note the VPC Id, subnet Ids, and security group Id.

    Now review the Kubernetes nodes that have been created. This is where kubectl comes in handy. Looking at the previous log, you will notice that one of the last things eksctl did was update the ~/.kube/config file with the new cluster configuration. Go ahead and use kubectl to make requests to the Kubernetes API Server.

    Get EKS cluster nodes
    kubectl get nodes -o wide
    
    NAME                                           STATUS   ROLES    AGE     VERSION              INTERNAL-IP      EXTERNAL-IP    OS-IMAGE         KERNEL-VERSION                CONTAINER-RUNTIME
    ip-192-168-45-153.us-west-1.compute.internal   Ready    <none>   4m57s   v1.20.7-eks-135321   192.168.45.153   50.18.29.248   Amazon Linux 2   5.4.149-73.259.amzn2.x86_64   docker://20.10.7
    ip-192-168-91-228.us-west-1.compute.internal   Ready    <none>   4m54s   v1.20.7-eks-135321   192.168.91.228   3.101.73.65    Amazon Linux 2   5.4.149-73.259.amzn2.x86_64   docker://20.10.7

    Great! We have two instances in a READY status.

    Create a Database

    Create a Postgres RDS instance required for FusionAuth installation. For simplicity, this database will be created in the same VPC and configured with the same security groups applied to the private subnets. Finally, you will modify the inbound rules to the security group to allow traffic on port 5432. This will enable our worker nodes to communicate with the database successfully!

    Since an RDS instance needs to be assigned to a database subnet group, you may either assign it to an existing group with subnets in the same VPC or create a new one. Here, you create a new subnet group using the subnets assigned to your cluster in the cluster creation step.

    Create DB subnet group
    aws rds create-db-subnet-group \
    --db-subnet-group-name fusionauth-example-db-group \
    --db-subnet-group-description "FusionAuth example database subnet group" \
    --subnet-ids "subnet-091347798a21eabe2" "subnet-0cb7540073e8b30aa" "subnet-052f8750345045581" "subnet-040e32678cf7a85da"

    Now create the database. Set db-subnet-group and vpc-security-group-ids to the values for the subnet Id and the VPC Id from the above creation steps.

    Create Postgresql DB instance
    aws rds create-db-instance \
        --db-instance-identifier fusionauth-eks-example \
        --allocated-storage 20 \
        --db-instance-class db.m6g.large \
        --engine postgres \
        --master-username postgres \
        --master-user-password changeMeToSomethingMoreSecure \
        --no-publicly-accessible \
        --vpc-security-group-ids sg-08b95dbacc02ba628 \
        --db-subnet-group fusionauth-example-db-group \
        --availability-zone us-west-1c \
        --port 5432

    Add an inbound rule to the security group to allow nodes to access the database. Again, use the security group Id from above.

    Create inbound rule
    aws ec2 authorize-security-group-ingress \
        --group-id sg-08b95dbacc02ba628 \
        --protocol tcp \
        --port 5432 \
        --source-group sg-08b95dbacc02ba628

    You are done! To confirm the database has been created, simply ask AWS using the db-instance-identifier used on the creation step.

    It may take a few minutes for the provisioning process to complete.

    Get DB instance information
    aws rds describe-db-instances --db-instance-identifier fusionauth-eks-example

    The resulting output should contain an Endpoint attribute. This value will be necessary when configuring your FusionAuth deployment.

    DB instance JSON output
    {
        "DBInstances": [
            {
                "DBInstanceIdentifier": "fusionauth-eks-example",
                "DBInstanceClass": "db.m6g.large",
                "Engine": "postgres",
                "DBInstanceStatus": "available",
                "MasterUsername": "postgres",
                "Endpoint": {
                    "Address": "fusionauth-eks-example.sadkjl222.us-west-1.rds.amazonaws.com",
                    "Port": 5432
                },
        ...

    Create an AWS Elasticsearch Domain

    Define a policy that will enable EKS to talk to the Elasticsearch domain. Copy the following JSON, replacing the value for ACCOUNT_ID, to a local file and save it as eks-policy.json:

    Policy JSON
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Action": [
            "es:*"
          ],
          "Resource": "arn:aws:es:us-west-1:<ACCOUNT_ID>:domain/fusionauth-es",
          "Effect": "Allow"
        }
      ]
    }

    Create the policy:

    Create access policy
    aws iam create-policy \
    --policy-name fusionauth-es-policy \
    --policy-document file://eks-policy.json

    Attach the policy to the service role that assigned to your EKS cluster:

    Assign policy to EKS role
    aws iam attach-role-policy \                                                                                                                                                                               ✔
      --policy-arn arn:aws:iam::<ACCOUNT_ID>:policy/fusionauth-es-policy \
      --role-name <role-name>

    Create a domain access policy to be assigned to the new Elasticsearch cluster. Copy the following, replacing the value for ACCOUNT_ID, to a local file and save it as access-policy.json:

    Create Elasticsearch domain access policy
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "*"
          },
          "Action": "es:*",
          "Resource": "arn:aws:es:us-west-1:<ACCOUNT_ID>:domain/fusionauth-es/*"
        }
      ]
    }

    Create a new cluster, updating the subnet Ids and security group Ids:

    Create the Elasticsearch cluster
    aws es create-elasticsearch-domain \
    --domain-name fusionauth-es-2 \
    --elasticsearch-version 7.10 \
    --elasticsearch-cluster-config InstanceType=m5.large.elasticsearch,InstanceCount=1 \
    --vpc-options SubnetIds=subnet-040e32678cf7a85da,SecurityGroupIds=sg-08b95dbacc02ba628 \
    --ebs-options EBSEnabled=true,VolumeType=standard,VolumeSize=10 \
    --access-policies file://access-policy.json

    Next Steps

    You now are running all the necessary infrastructure to deploy a containerized application to EKS.

    Next up, Deploy FusionAuth in Kubernetes.

    It is recommended that you consult Getting started with Amazon EKS for more EKS documentation, including needed customization for your situation.

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    © 2021 FusionAuth
    Subscribe for developer updates