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.


ESSENTIAL

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.

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

OPTIONAL

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

OPTIONAL

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 specified ALBTG (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.

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