EC2-Stackset
A setup for deploying EC2 instances across multiple AWS accounts and regions from a single template. This setup provides centralized control, ensuring consistent instance configurations across environments, making it ideal for managing EC2 resources at scale in multi-account, multi-region AWS architectures.
Basic Configuration
This is a straightforward setup for deploying an EC2 instance with necessary access and network settings in AWS.
Required resource
- Name
Bastion
- Description
Launches an EC2 instance, using a specified AMI ID and t2.micro instance type. The instance is deployed in the public subnet and is associated with the security group
BastionSG
(which we have defined here) to allow controlled SSH access.
Note:
- The AMI ID constantly change and must be copied from the console to spin up desired AMI.
- AWS recommends any instance created to be associated with a keypair; which I've defined in the template, but the keypair must be manually created first in the console.
Instance Configuration
Bastion:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-060e277c0d4cce553 # copy desired AMI ID in AWS console
SubnetId: !Ref PublicSubnet
KeyName: server-keypair # need to be manually created first in AWS console
SecurityGroupIds:
- !Ref BastionSG
Tags:
- Key: Name
Value: EC2-Bastion
Launch Template
This setup deploys an EC2 instance using a Launch Template for easier management. An Instance Profile
is also configured to enable the EC2 instance to communicate with other AWS services.
Required resources
- Name
InstanceRole
- Description
Defines an IAM role for the EC2 instance, allowing it to interact with AWS services. The role includes an example of AWS managed policies and a custom policy.
- Name
InstanceProfile
- Description
Creates an IAM Instance Profile associated with the
InstanceRole
, enabling EC2 instances launched with this profile to assume the specified role and access resources according to its permissions.
- Name
ServerLT
- Description
Defines a Launch Template for the EC2 instance making it reusable for launching instances with consistent configurations.
- Name
Instance
- Description
Deploys an EC2 instance using the Launch Template, which provides configuration details like instance type, image, and security group.
EC2 Permission Configuration
InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: InstanceRole
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns: # AWS managed policy example
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
Policies: # custom policy example
- PolicyName: InstancePolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- elasticfilesystem:ClientMount
- elasticfilesystem:ClientWrite
Resource:
- "*"
InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: InstanceProfile
Roles:
- !Ref InstanceRole
Launch Template Configuration
ServerLT:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: server-LT
LaunchTemplateData:
InstanceType: t3.micro
ImageId: ami-060e277c0d4cce553
KeyName: server-keypair
IamInstanceProfile:
Name: !Ref InstanceProfile
SecurityGroupIds:
- !Ref GlobalSG
Instance Configuration
Instance:
Type: AWS::EC2::Instance
Properties:
LaunchTemplate:
LaunchTemplateId: !Ref ServerLT
Version: !GetAtt ServerLT.LatestVersionNumber
SubnetId: !Ref PrivateSubnet
Tags:
- Key: Name
Value: EC2-Server
Auto-Scaling Group
This ASG setup manages EC2 instances, adjusting their count based on demand. It uses a launch template for instance settings and works with a load balancer for balanced load distribution. The ASG scales with policies based on CPU usage.
Required resources
- Name
ASG
- Description
Configures an ASG to manage EC2 instances within the specified private subnet. The ASG uses the
ServerLT
to define instance settings, with a minimum capacity of 1 instance and a maximum of 5. It automatically scales to maintain a desired capacity of 1 instance, attaching instances to the specifiedALBTG
(which has been defined here) for load balancing.
- Name
ScaleOutPolicy
- Description
Defines a scaling policy to increase the capacity of the ASG by 1 instance when triggered. This policy has a cooldown period of 5 minuts to prevent rapid scaling adjustments.
- Name
ScaleInPolicy
- Description
Defines a scaling policy to decrease the capacity of the ASG by 1 instance when triggered. The policy includes a cooldown period of 5 minutes to prevent excessive scaling adjustments.
- Name
CPUHigh
- Description
Configures a CloudWatch Alarm that monitors CPU utilization within the ASG. The alarm triggers if the average CPU usage is above 66% for two consecutive 1 minute periods, activating the
ScaleOutPolicy
to increase the instance count within the ASG.
- Name
CPULow
- Description
Configures a CloudWatch Alarm to monitor CPU utilization within the ASG. If the average CPU usage falls below 33% for two consecutive 1 minute periods, the alarm triggers the
ScaleInPolicy
to reduce the instance count within the ASG.
Note:
- While it’s possible to use an ASG without a load balancer for special use cases, this is not standard practice. Here, I included a target group to ensure that instances in the ASG are balanced and managed by a load balancer for optimal distribution.
- The scaling policy is not restricted to only based on CPU utilization. It may also be configured with another metric of monitoring like memory, network, etc.
Auto-Scaling Group Configuration
ASG:
Type: "AWS::AutoScaling::AutoScalingGroup"
Properties:
VPCZoneIdentifier:
- !Ref PrivateSubnet
# should add another subnet here for HA setup
LaunchTemplate:
LaunchTemplateId: !Ref ServerLT
Version: !GetAtt ServerLT.LatestVersionNumber
MinSize: 1
MaxSize: 5
DesiredCapacity: 1
TargetGroupARNs:
- !Ref ALBTG
Tags:
- Key: Name
Value: ASG-Server
PropagateAtLaunch: true
Scaling Configuration
ScaleOutPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref ASG
Cooldown: 300
PolicyType: SimpleScaling
ScalingAdjustment: 1
ScaleInPolicy:
Type: AWS::AutoScaling::ScalingPolicy
Properties:
AdjustmentType: ChangeInCapacity
AutoScalingGroupName: !Ref ASG
Cooldown: 300
PolicyType: SimpleScaling
ScalingAdjustment: -1
Scaling Trigger Configuration
CPUHigh:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Alarm if CPU is above 66% for 2 minutes
Namespace: AWS/EC2
MetricName: CPUUtilization
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref ASG
Statistic: Average
Period: 60
EvaluationPeriods: 2
Threshold: 66
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref ScaleOutPolicy
CPULow:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Alarm if CPU is below 33% for 2 minutes
Namespace: AWS/EC2
MetricName: CPUUtilization
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref ASG
Statistic: Average
Period: 60
EvaluationPeriods: 2
Threshold: 33
ComparisonOperator: LessThanThreshold
AlarmActions:
- !Ref ScaleInPolicy