Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ti-infinite/GSMInfrastructure/llms.txt

Use this file to discover all available pages before exploring further.

The infrastructure template (devops/infrastructure/template.yml) is the main application stack for the GSM platform. It provisions every layer of the application: a CloudFront distribution backed by an S3 bucket for the React SPA frontend, a private EC2 instance running ECS with bridge networking for the four backend microservices, an ECR repository for container images, an Elastic IP for stable public addressing, AWS Budgets with SNS alerting for cost visibility, and all supporting IAM roles, security groups, and log groups. The stack is designed to run on top of an existing VPC and subnet — no network infrastructure is created here.

Parameters

Environment
String
default:"dev"
The deployment environment. Controls resource naming prefixes and is injected into containers as the ENVIRONMENT variable.Allowed values: dev, qa, prod
AppName
String
default:"gsmapplication"
The application platform name. Combined with Environment to form all resource names.
BudgetLimitUSD
Number
default:"30"
Monthly AWS cost budget limit in USD. When 100% of this threshold is reached an SNS notification is sent to AlertEmail.
AlertEmail
String
required
Email address that receives budget threshold breach notifications via SNS subscription.
CloudFrontHeader
String
required
Secret value injected as the X-CloudFront-Origin custom origin header on requests from CloudFront to the EC2 backend. The ECS gateway service can verify this header to reject direct traffic that bypasses CloudFront.
TaskNumberDesired
Number
default:"0"
Desired number of running tasks for each of the four ECS services. Set to 0 on initial deploy; the Scheduler stack manages scaling during business hours.
TaskMemory
Number
default:"512"
Hard memory limit (MiB) per ECS container task. Each task also receives 256 CPU units.
TaskMemoryReservation
Number
default:"384"
Soft memory reservation (MiB) per ECS container task. The container may exceed this up to TaskMemory.
DBPortParameterName
Number
default:"1433"
SQL Server port number. Used both as a security group egress rule port and passed to containers via secrets.
DBMasterUrlParameterName
String
default:"dev/backend/DB_MASTER_URL"
SSM Parameter Store path for the database master connection URL. Injected into the Auth, Application, and Operations task definitions as the DB_MASTER_URL secret.
SqlServerProviderIp
String
default:"0.0.0.0/0"
CIDR block of the SQL Server provider (e.g. 203.0.113.10/32). The ECS security group allows outbound TCP to the DB port only to this CIDR.
JWTSecretParameterName
String
default:"dev/backend/JWT_SECRET"
SSM Parameter Store path for the JWT signing secret. Injected into all four task definitions as the JWT_SECRET secret.
VpcId
AWS::EC2::VPC::Id
required
ID of the existing VPC where the EC2 instance and security group are placed (e.g. the account default VPC).
VpcIdCidrBlock
String
default:"10.0.0.0/16"
CIDR block of the VPC. Used as a security group ingress rule to allow HTTP traffic from within the VPC.
PrivateSubnet1Id
AWS::EC2::Subnet::Id
required
ID of the existing private subnet (AZ1) where the ECS EC2 instance is launched.
Ec2PenKeyName
String
default:"dev-key-ec2"
Name of the EC2 key pair used for SSH access to the ECS host instance.
Ec2InstanceType
String
default:"t4g.medium"
EC2 instance type for the ECS host. Must be an ARM64-compatible type to match the Amazon Linux 2023 ECS-optimized AMI resolved at deploy time.
ExistingEIPPublicIp
String
default:""
Public IP address of an existing Elastic IP to use as the CloudFront custom origin for the backend. Leave empty to use the newly allocated EIP attached to the EC2 instance (Ec2ElasticIp). When set, the NoExistEIP condition evaluates to false and ECSInstance.PublicDnsName is not used as the backend origin.

Resources

FrontendBucket

FieldValue
TypeAWS::S3::Bucket
Name pattern{Environment}-{AppName}-frontend
Deletion policyDelete
Hosts the compiled React SPA. Versioning is enabled. All public access is blocked — CloudFront is the only authorized reader via an Origin Access Control (OAC). Server-side encryption uses AES-256.

CloudFrontOAC

FieldValue
TypeAWS::CloudFront::OriginAccessControl
Name pattern{Environment}-{AppName}-oac
Signingsigv4, always
Secures access from CloudFront to the S3 origin so bucket objects never need to be public.

FrontendBucketPolicy

FieldValue
TypeAWS::S3::BucketPolicy
Grants s3:GetObject, s3:ListBucket, and s3:GetBucketLocation to cloudfront.amazonaws.com conditioned on the specific CloudFront distribution ARN. All non-HTTPS (aws:SecureTransport: false) requests are explicitly denied for all principals.

SpaRouterFunction

FieldValue
TypeAWS::CloudFront::Function
Name pattern{Environment}-{AppName}-spa-router
Runtimecloudfront-js-2.0
Auto-publishtrue
A CloudFront viewer-request function that rewrites extensionless URL paths (e.g. /dashboard, /login) to /index.html so the React router handles client-side navigation without returning 403/404 from S3.
function handler(event) {
    var request = event.request;
    var lastSegment = request.uri.split('/').pop();
    if (!lastSegment.includes('.')) {
        request.uri = '/index.html';
    }
    return request;
}

CloudFrontDistribution

FieldValue
TypeAWS::CloudFront::Distribution
Price classPriceClass_100 (US, Canada, Europe)
Default root objectindex.html
HTTPSredirect-to-https (default behavior); https-only (API behavior)
Two origins are configured:
Origin IDDomainNotes
s3-originFrontendBucket.RegionalDomainNameOrigin path /admin; uses OAC
BackendEC2OriginEC2 public DNS or ExistingEIPPublicIpHTTP-only; injects X-CloudFront-Origin header
Two cache behaviors:
PathOriginCachingMethods
/* (default)s3-originForwardedValues.QueryString: falseGET, HEAD, OPTIONS
/api/*BackendEC2OriginTTL 0 (pass-through); forwards Authorization, Content-Type, Accept, Origin, Referer, all cookiesDELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT

EcsSecurityGroup

FieldValue
TypeAWS::EC2::SecurityGroup
Name pattern{Environment}-{AppName}-ecs-security-group
VPCVpcId parameter
Ingress rules:
ProtocolPortsSourceDescription
TCP80pl-3b927c52 (CloudFront managed prefix list)CloudFront → Gateway
TCP80VpcIdCidrBlockVPC-internal HTTP
TCP8081–8083172.17.0.0/16 (Docker bridge)Inter-container communication
Egress rules:
ProtocolPortsDestinationDescription
TCP4430.0.0.0/0HTTPS for SSM/ECR
UDP530.0.0.0/0DNS resolution
TCP8081–8083172.17.0.0/16Inter-container communication
TCPDBPortParameterNameSqlServerProviderIpDatabase access

ECRRepository

FieldValue
TypeAWS::ECR::Repository
Name pattern{Environment}-{AppName}-respository
Scan on pushtrue
Single private ECR repository that stores all four microservice images using tag conventions: gateway-latest, auth-latest, application-latest, gsmoperations-latest.

ECSCluster

FieldValue
TypeAWS::ECS::Cluster
Name pattern{Environment}-{AppName}-cluster
The ECS cluster that hosts all four microservice tasks on the single EC2 instance using the EC2 launch type with bridge networking.

BackendLogGroup

FieldValue
TypeAWS::Logs::LogGroup
Name pattern/ecs/{Environment}-{AppName}-backend
Retention7 days
Deletion policyDelete
Shared CloudWatch log group for all four microservice containers. Each container writes to a distinct stream prefix (gmsgateway, gmsauth, gsmapplication, gsmoperations).

ECSExecutionRole

FieldValue
TypeAWS::IAM::Role
Name pattern{Environment}-{AppName}-ecs-role
Managed policyAmazonECSTaskExecutionRolePolicy
The ECS task execution role. Trusted by ecs-tasks.amazonaws.com. Also receives the ECSRoleSSMPolicy managed policy for SSM Parameter Store and KMS access.

ECSTaskRole

FieldValue
TypeAWS::IAM::Role
Name pattern{Environment}-{AppName}-ecs-task-role
The ECS task role (application identity). Trusted by ecs-tasks.amazonaws.com. Also receives the ECSRoleSSMPolicy managed policy.

ECSRoleSSMPolicy

FieldValue
TypeAWS::IAM::ManagedPolicy
Name pattern{Environment}-{AppName}-ecs-ssm-read
Attached toECSExecutionRole, ECSTaskRole
Grants ssm:GetParameter and ssm:GetParameters on /{Environment}/* parameters, and kms:Decrypt on account KMS keys so tasks can resolve secrets at startup.
All four task definitions share the following configuration:
FieldValue
Network modebridge
Launch typeEC2
CPU256 units per container
MemoryTaskMemory (hard) / TaskMemoryReservation (soft)
Log driverawslogsBackendLogGroup
Health checkwget -qO- http://localhost:{port}/[api/]health — interval 30s, timeout 10s, retries 3, start period 120s

GatewayTaskDefinition

FieldValue
TypeAWS::ECS::TaskDefinition
Family{Environment}-{AppName}-gateway-task
Containergsmgateway
Image taggateway-latest
Port80:80 (host:container)
SecretsJWT_SECRET from SSM
Environment varsORIGINS (CloudFront domain), ENVIRONMENT
Health check path/api/health

AuthTaskDefinition

FieldValue
TypeAWS::ECS::TaskDefinition
Family{Environment}-{AppName}-auth-task
Containergmsauth
Image tagauth-latest
Port8081:8081
SecretsJWT_SECRET, DB_MASTER_URL from SSM
Environment varsENVIRONMENT
Health check path/health

ApplicationTaskDefinition

FieldValue
TypeAWS::ECS::TaskDefinition
Family{Environment}-{AppName}-application-task
Containergsmapplication
Image tagapplication-latest
Port8082:8082
SecretsJWT_SECRET, DB_MASTER_URL from SSM
Environment varsENVIRONMENT
Health check path/health

OperationsTaskDefinition

FieldValue
TypeAWS::ECS::TaskDefinition
Family{Environment}-{AppName}-operations-task
Containergsmoperations
Image taggsmoperations-latest
Port8083:8083
SecretsJWT_SECRET, DB_MASTER_URL from SSM
Environment varsENVIRONMENT
Health check path/health
All four services share the following deployment configuration:
FieldValue
Launch typeEC2
Desired countTaskNumberDesired parameter
Max percent100
Min healthy percent0
Circuit breakerEnabled with automatic rollback
Health check grace period60 seconds
Execute commandDisabled

GatewayService

FieldValue
TypeAWS::ECS::Service
Name pattern{Environment}-{AppName}-gateway-service
Task definitionGatewayTaskDefinition

AuthService

FieldValue
TypeAWS::ECS::Service
Name pattern{Environment}-{AppName}-auth-service
Task definitionAuthTaskDefinition

ApplicationService

FieldValue
TypeAWS::ECS::Service
Name pattern{Environment}-{AppName}-application-service
Task definitionApplicationTaskDefinition

OperationsService

FieldValue
TypeAWS::ECS::Service
Name pattern{Environment}-{AppName}-operations-service
Task definitionOperationsTaskDefinition

ECSInstanceRole

FieldValue
TypeAWS::IAM::Role
Name pattern{Environment}-{AppName}-instance-ecs-role
Managed policiesAmazonEC2ContainerServiceforEC2Role, AmazonSSMManagedInstanceCore
Trusted by ec2.amazonaws.com. Includes an inline policy granting ssm:GetParameter* and kms:Decrypt scoped to /{Environment}/* parameters so the ECS agent can pull secrets during task startup.

EC2InstanceProfile

FieldValue
TypeAWS::IAM::InstanceProfile
Name pattern{Environment}-{AppName}-instance-ecs-profile
RoleECSInstanceRole
Instance profile that attaches ECSInstanceRole to the EC2 instance.

ECSInstance

FieldValue
TypeAWS::EC2::Instance
Name tag{Environment}-{AppName}-ec2-instance
Architecturearm64
AMIResolved at deploy time from SSM: /aws/service/ecs/optimized-ami/amazon-linux-2023/arm64/recommended/image_id
Instance typeEc2InstanceType parameter (default t4g.medium)
SubnetPrivateSubnet1Id parameter
Key pairEc2PenKeyName parameter
Security groupEcsSecurityGroup
User data configures the ECS agent at launch:
#!/bin/bash
mkdir -p /etc/ecs
echo ECS_CLUSTER=${Environment}-${AppName}-cluster > /etc/ecs/ecs.config

systemctl enable docker
systemctl start docker
systemctl enable ecs
systemctl daemon-reload
systemctl start ecs

Ec2ElasticIp

FieldValue
TypeAWS::EC2::EIP
Name tag{Environment}-{AppName}-ec2-eip
Domainvpc
Attached toECSInstance
Provides a stable public IP address for the EC2 ECS host. CloudFront uses this IP as the backend custom origin endpoint. The Scheduler stack manages disassociation (before shutdown) and reassociation (after startup) to avoid charges for idle Elastic IPs.

NotificationSNSTopic

FieldValue
TypeAWS::SNS::Topic
Name pattern{Environment}-{AppName}-notification-alerts
SubscriptionEmail to AlertEmail parameter
SNS topic that delivers budget breach notifications. Also allows events.amazonaws.com to publish via the NotificationSNSTopicPolicy.

NotificationSNSTopicPolicy

FieldValue
TypeAWS::SNS::TopicPolicy
Grants sns:Publish to events.amazonaws.com on the notification topic so EventBridge can forward cost alert events.

AwsCostBudget

FieldValue
TypeAWS::Budgets::Budget
Name pattern{Environment}-{AppName}-monthly-budget
Budget typeCOST
Time unitMONTHLY
LimitBudgetLimitUSD USD
Sends an SNS notification to NotificationSNSTopic when actual monthly spend exceeds 100% of the configured limit.

Outputs

OutputDescription
FrontendBucketNameName of the S3 bucket hosting the compiled SPA (e.g. dev-gsmapplication-frontend).
CloudFrontDomainCloudFront distribution domain name (e.g. d1234abcd.cloudfront.net). Use this as the application’s public URL.
ECSClusterNameName of the ECS cluster (e.g. dev-gsmapplication-cluster). Required as input for the Scheduler stack.
BudgetNameName of the AWS Budget resource (e.g. dev--gsmapplication-monthly-budget).

Build docs developers (and LLMs) love