TheArchitect

EKS Microservices

AWS architecture template · SAA-C03: CloudFront → ALB → EKS control plane → Aurora + ElastiCache

EKS Microservices is a free AWS architecture template built with Aurora, CloudFront, EKS, ElastiCache, IAM and Load Balancer. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.

Public edge A/BPrivate cluster A/BPrivate data A/BEKS VPC 10.10.0.0/16CloudFrontAPI ALBEKS RoleEKS ClusterAurora ClusterRedis Cache
EKS Microservices architecture diagram

AWS services in this template

  • Aurora
  • CloudFront
  • EKS
  • ElastiCache
  • IAM
  • Load Balancer

Deployment notes

Needs input

  • Add worker node IAM role and launch template to the EKS node group before deployment.
  • Uses demo VPC with public/private subnets.

Generated CloudFormation — 36 resources

Logical IDResource type
CloudFrontcloudfrontAWS::CloudFront::Distribution
EKSVPC10100016vpcAWS::EC2::VPC
EKSVPC10100016vpcedgewebsgSecurityGroupAWS::EC2::SecurityGroup
EKSVPC10100016vpcappruntimesgSecurityGroupAWS::EC2::SecurityGroup
EKSVPC10100016vpcappruntimesgSecurityGroupIngressRuleAWS::EC2::SecurityGroupIngress
EKSVPC10100016vpcworkersgSecurityGroupAWS::EC2::SecurityGroup
EKSVPC10100016vpcdatastoresgSecurityGroupAWS::EC2::SecurityGroup
EKSVPC10100016vpcdatastoresgSecurityGroupIngressRuleAWS::EC2::SecurityGroupIngress
EKSVPC10100016vpccontrolplanesgSecurityGroupAWS::EC2::SecurityGroup
EKSVPC10100016vpcPublicSubnet1AWS::EC2::Subnet
EKSVPC10100016vpcPublicSubnet2AWS::EC2::Subnet
EKSVPC10100016vpcPrivateSubnet1AWS::EC2::Subnet
EKSVPC10100016vpcPrivateSubnet2AWS::EC2::Subnet
EKSVPC10100016vpcPrivateSubnet3AWS::EC2::Subnet
EKSVPC10100016vpcPrivateSubnet4AWS::EC2::Subnet
EKSVPC10100016vpcInternetGatewayAWS::EC2::InternetGateway
EKSVPC10100016vpcGatewayAttachmentAWS::EC2::VPCGatewayAttachment
EKSVPC10100016vpcPublicRouteTableAWS::EC2::RouteTable
EKSVPC10100016vpcPublicRouteAWS::EC2::Route
EKSVPC10100016vpcPublicSubnet1RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcPublicSubnet2RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcNatEIPAWS::EC2::EIP
EKSVPC10100016vpcNatGatewayAWS::EC2::NatGateway
EKSVPC10100016vpcPrivateRouteTableAWS::EC2::RouteTable
EKSVPC10100016vpcPrivateRouteAWS::EC2::Route
EKSVPC10100016vpcPrivateSubnet1RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcPrivateSubnet2RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcPrivateSubnet3RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcPrivateSubnet4RTAAWS::EC2::SubnetRouteTableAssociation
EKSVPC10100016vpcDbSubnetGroupAWS::RDS::DBSubnetGroup
EKSVPC10100016vpcCacheSubnetGroupAWS::ElastiCache::SubnetGroup
APIALBelbAWS::ElasticLoadBalancingV2::LoadBalancer
EKSRoleiamAWS::IAM::Role
EKSClustereksAWS::EKS::Cluster
AuroraClusterauroraAWS::RDS::DBCluster
RedisCacheelasticacheAWS::ElastiCache::CacheCluster
View the full CloudFormation template
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
  "Metadata": {
    "TheArchitect": {
      "Edges": [
        {
          "From": "CloudFrontcloudfront",
          "To": "APIALBelb"
        },
        {
          "From": "EKSRoleiam",
          "To": "EKSClustereks",
          "Label": "cluster role"
        }
      ]
    }
  },
  "Resources": {
    "CloudFrontcloudfront": {
      "Type": "AWS::CloudFront::Distribution",
      "Properties": {
        "DistributionConfig": {
          "Enabled": true,
          "Comment": "CDN for the microservices API.",
          "PriceClass": "PriceClass_100",
          "HttpVersion": "http2",
          "DefaultCacheBehavior": {
            "TargetOriginId": "LoadBalancerOrigin",
            "ViewerProtocolPolicy": "redirect-to-https",
            "ForwardedValues": {
              "QueryString": false,
              "Cookies": {
                "Forward": "none"
              }
            }
          },
          "ViewerCertificate": {
            "CloudFrontDefaultCertificate": true
          },
          "Origins": [
            {
              "DomainName": {
                "Fn::GetAtt": [
                  "APIALBelb",
                  "DNSName"
                ]
              },
              "Id": "LoadBalancerOrigin",
              "CustomOriginConfig": {
                "HTTPPort": 80,
                "HTTPSPort": 443,
                "OriginProtocolPolicy": "http-only",
                "OriginSSLProtocols": [
                  "TLSv1.2"
                ]
              }
            }
          ]
        }
      }
    },
    "EKSVPC10100016vpc": {
      "Type": "AWS::EC2::VPC",
      "Properties": {
        "CidrBlock": "10.10.0.0/16",
        "EnableDnsHostnames": true,
        "EnableDnsSupport": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc"
          }
        ]
      }
    },
    "EKSVPC10100016vpcedgewebsgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "edge-web-sg",
        "GroupDescription": "Allow HTTPS from the internet to public load balancers",
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "edge-web-sg"
          }
        ],
        "SecurityGroupIngress": [
          {
            "IpProtocol": "tcp",
            "FromPort": 443,
            "ToPort": 443,
            "CidrIp": "0.0.0.0/0"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "EKSVPC10100016vpcappruntimesgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "app-runtime-sg",
        "GroupDescription": "Allow application traffic from the edge tier",
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "app-runtime-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "EKSVPC10100016vpcappruntimesgSecurityGroupIngressRule": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {
          "Ref": "EKSVPC10100016vpcappruntimesgSecurityGroup"
        },
        "IpProtocol": "tcp",
        "FromPort": 80,
        "ToPort": 80,
        "SourceSecurityGroupId": {
          "Ref": "EKSVPC10100016vpcedgewebsgSecurityGroup"
        }
      }
    },
    "EKSVPC10100016vpcworkersgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "worker-sg",
        "GroupDescription": "Private worker runtime egress only",
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "worker-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "EKSVPC10100016vpcdatastoresgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "data-store-sg",
        "GroupDescription": "Allow PostgreSQL from application runtimes",
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "data-store-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "EKSVPC10100016vpcdatastoresgSecurityGroupIngressRule": {
      "Type": "AWS::EC2::SecurityGroupIngress",
      "Properties": {
        "GroupId": {
          "Ref": "EKSVPC10100016vpcdatastoresgSecurityGroup"
        },
        "IpProtocol": "tcp",
        "FromPort": 5432,
        "ToPort": 5432,
        "SourceSecurityGroupId": {
          "Ref": "EKSVPC10100016vpcappruntimesgSecurityGroup"
        }
      }
    },
    "EKSVPC10100016vpccontrolplanesgSecurityGroup": {
      "Type": "AWS::EC2::SecurityGroup",
      "Properties": {
        "GroupName": "control-plane-sg",
        "GroupDescription": "Private EKS control plane attachment group",
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "control-plane-sg"
          }
        ],
        "SecurityGroupEgress": [
          {
            "IpProtocol": "-1",
            "CidrIp": "0.0.0.0/0"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPublicSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.1.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "public-edge-a"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPublicSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.2.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": true,
        "Tags": [
          {
            "Key": "Name",
            "Value": "public-edge-b"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateSubnet1": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.11.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-app-a"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateSubnet2": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.12.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-app-b"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateSubnet3": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.21.0/24",
        "AvailabilityZone": "us-east-1a",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-data-a"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateSubnet4": {
      "Type": "AWS::EC2::Subnet",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "CidrBlock": "10.10.22.0/24",
        "AvailabilityZone": "us-east-1b",
        "MapPublicIpOnLaunch": false,
        "Tags": [
          {
            "Key": "Name",
            "Value": "private-data-b"
          }
        ]
      }
    },
    "EKSVPC10100016vpcInternetGateway": {
      "Type": "AWS::EC2::InternetGateway",
      "Properties": {
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-igw"
          }
        ]
      }
    },
    "EKSVPC10100016vpcGatewayAttachment": {
      "Type": "AWS::EC2::VPCGatewayAttachment",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "InternetGatewayId": {
          "Ref": "EKSVPC10100016vpcInternetGateway"
        }
      }
    },
    "EKSVPC10100016vpcPublicRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-public-rt"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPublicRoute": {
      "Type": "AWS::EC2::Route",
      "DependsOn": [
        "EKSVPC10100016vpcGatewayAttachment"
      ],
      "Properties": {
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPublicRouteTable"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "GatewayId": {
          "Ref": "EKSVPC10100016vpcInternetGateway"
        }
      }
    },
    "EKSVPC10100016vpcPublicSubnet1RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPublicSubnet1"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPublicRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcPublicSubnet2RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPublicSubnet2"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPublicRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcNatEIP": {
      "Type": "AWS::EC2::EIP",
      "DependsOn": [
        "EKSVPC10100016vpcGatewayAttachment"
      ],
      "Properties": {
        "Domain": "vpc"
      }
    },
    "EKSVPC10100016vpcNatGateway": {
      "Type": "AWS::EC2::NatGateway",
      "Properties": {
        "AllocationId": {
          "Fn::GetAtt": [
            "EKSVPC10100016vpcNatEIP",
            "AllocationId"
          ]
        },
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPublicSubnet1"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-nat"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateRouteTable": {
      "Type": "AWS::EC2::RouteTable",
      "Properties": {
        "VpcId": {
          "Ref": "EKSVPC10100016vpc"
        },
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-private-rt"
          }
        ]
      }
    },
    "EKSVPC10100016vpcPrivateRoute": {
      "Type": "AWS::EC2::Route",
      "Properties": {
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPrivateRouteTable"
        },
        "DestinationCidrBlock": "0.0.0.0/0",
        "NatGatewayId": {
          "Ref": "EKSVPC10100016vpcNatGateway"
        }
      }
    },
    "EKSVPC10100016vpcPrivateSubnet1RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPrivateSubnet1"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPrivateRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcPrivateSubnet2RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPrivateSubnet2"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPrivateRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcPrivateSubnet3RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPrivateSubnet3"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPrivateRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcPrivateSubnet4RTA": {
      "Type": "AWS::EC2::SubnetRouteTableAssociation",
      "Properties": {
        "SubnetId": {
          "Ref": "EKSVPC10100016vpcPrivateSubnet4"
        },
        "RouteTableId": {
          "Ref": "EKSVPC10100016vpcPrivateRouteTable"
        }
      }
    },
    "EKSVPC10100016vpcDbSubnetGroup": {
      "Type": "AWS::RDS::DBSubnetGroup",
      "Properties": {
        "DBSubnetGroupDescription": "Private subnets for saa-eks-vpc",
        "SubnetIds": [
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet1"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet2"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet3"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet4"
          }
        ],
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-db-subnet-group"
          }
        ]
      }
    },
    "EKSVPC10100016vpcCacheSubnetGroup": {
      "Type": "AWS::ElastiCache::SubnetGroup",
      "Properties": {
        "Description": "Private subnets for saa-eks-vpc",
        "SubnetIds": [
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet1"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet2"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet3"
          },
          {
            "Ref": "EKSVPC10100016vpcPrivateSubnet4"
          }
        ],
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks-vpc-cache-subnet-group"
          }
        ]
      }
    },
    "APIALBelb": {
      "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer",
      "Properties": {
        "Name": "saa-eks-api-alb",
        "Type": "application",
        "Scheme": "internet-facing",
        "IpAddressType": "ipv4",
        "Subnets": [
          {
            "Ref": "EKSVPC10100016vpcPublicSubnet1"
          },
          {
            "Ref": "EKSVPC10100016vpcPublicSubnet2"
          }
        ],
        "SecurityGroups": [
          {
            "Ref": "EKSVPC10100016vpcedgewebsgSecurityGroup"
          }
        ]
      }
    },
    "EKSRoleiam": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": "saa-eks-cluster-role",
        "Description": "EKS cluster control-plane IAM role.",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "eks.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
        ]
      }
    },
    "EKSClustereks": {
      "Type": "AWS::EKS::Cluster",
      "DependsOn": [
        "EKSRoleiam"
      ],
      "Properties": {
        "Name": "saa-eks-cluster",
        "Version": "1.35",
        "Tags": [
          {
            "Key": "Name",
            "Value": "saa-eks"
          }
        ],
        "ResourcesVpcConfig": {
          "SubnetIds": [
            {
              "Ref": "EKSVPC10100016vpcPublicSubnet1"
            },
            {
              "Ref": "EKSVPC10100016vpcPublicSubnet2"
            },
            {
              "Ref": "EKSVPC10100016vpcPrivateSubnet1"
            },
            {
              "Ref": "EKSVPC10100016vpcPrivateSubnet2"
            }
          ],
          "SecurityGroupIds": [
            {
              "Ref": "EKSVPC10100016vpccontrolplanesgSecurityGroup"
            }
          ],
          "EndpointPublicAccess": true,
          "EndpointPrivateAccess": true
        },
        "AccessConfig": {
          "AuthenticationMode": "API_AND_CONFIG_MAP"
        },
        "Logging": {
          "ClusterLogging": {
            "EnabledTypes": [
              {
                "Type": "api"
              },
              {
                "Type": "audit"
              },
              {
                "Type": "authenticator"
              },
              {
                "Type": "controllerManager"
              },
              {
                "Type": "scheduler"
              }
            ]
          }
        },
        "RoleArn": {
          "Fn::GetAtt": [
            "EKSRoleiam",
            "Arn"
          ]
        }
      }
    },
    "AuroraClusteraurora": {
      "Type": "AWS::RDS::DBCluster",
      "Properties": {
        "DBClusterIdentifier": "saa-eks-db",
        "Engine": "aurora-postgresql",
        "EngineVersion": "16.2",
        "VpcSecurityGroupIds": [
          {
            "Ref": "EKSVPC10100016vpcdatastoresgSecurityGroup"
          }
        ],
        "MasterUsername": "clusteradmin",
        "ManageMasterUserPassword": true,
        "StorageEncrypted": true,
        "BackupRetentionPeriod": 7,
        "DBSubnetGroupName": {
          "Ref": "EKSVPC10100016vpcDbSubnetGroup"
        }
      }
    },
    "RedisCacheelasticache": {
      "Type": "AWS::ElastiCache::CacheCluster",
      "Properties": {
        "Engine": "redis",
        "CacheNodeType": "cache.t4g.micro",
        "NumCacheNodes": 1,
        "CacheSubnetGroupName": {
          "Ref": "EKSVPC10100016vpcCacheSubnetGroup"
        },
        "VpcSecurityGroupIds": [
          {
            "Fn::GetAtt": [
              "EKSVPC10100016vpc",
              "DefaultSecurityGroup"
            ]
          }
        ]
      }
    }
  }
}

Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.

Related templates