I created an EC2 instance in a private subnet with a VPC endpoint, with hope of connecting to it through Systems Manager. In the AWS Systems Manager, the instance shows online and running.
However, when I try to execute a command on the instance, it just hangs with a Status of "Pending - Delayed" (I tried very simple Linux commands such as 'pwd')
Here's my CloudFormation template:
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates an EC2 instance for processing raw data.
################################################################################
#
# PARAMETERS
#
################################################################################
Parameters:
Prefix:
Description: This prefix will be prepended to all resource names.
Type: String
Default: my-company
EnvironmentName:
Description: An environment name that will be prefixed to resource names
Type: String
AllowedValues:
- dev
- stg
- uat
- prod
Default: prod
VpcStackName:
Description: The VPC stack name
Type: String
Default: vpc-stack
EC2InstanceType:
Description: The pipeline EC2 instance type
Type: String
Default: t2.micro
EC2ImageId:
Description: An Amazon Machine Image (AMI) ID
Type: String
Default: ami-0e731c8a588258d0d
SSHKeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: SSH Key for the EC2 Instance
ConstraintDescription: Must be the name of an existing EC2 KeyPair
Default: pipeline-key
################################################################################
#
# RESOURCES
#
################################################################################
Resources:
##############################################################################
#
# SECURITY
#
##############################################################################
PipelineEc2Role:
Type: AWS::IAM::Role
Properties:
RoleName: !Join [ '-', [ !Ref Prefix, !Ref EnvironmentName, 'ec2-ssm-role', !Select [ 7, !Split [ '-', !Ref AWS::StackId ] ] ] ]
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
PipelineEc2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: PipelineEc2Role
SsmSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join [ '-', [ !Ref Prefix, !Ref EnvironmentName, 'sg-raw-pipeline-ssm', !Select [ 7, !Split [ '-', !Ref AWS::StackId ] ] ] ]
GroupDescription: Security group for pipeline EC2 access
SecurityGroupIngress:
- CidrIp: 10.0.0.0/16
FromPort: 443
IpProtocol: tcp
ToPort: 443
Description: 'SSM access for EC2'
SecurityGroupEgress:
- CidrIp: 0.0.0.0/0
FromPort: -1
IpProtocol: -1
ToPort: -1
Tags:
- Key: Name
Value: !Join [ '-', [ !Ref Prefix, !Ref EnvironmentName, 'sg-raw-pipeline-ssm', !Select [ 7, !Split [ '-', !Ref AWS::StackId ] ] ] ]
VpcId:
Fn::ImportValue:
!Sub "${VpcStackName}-VpcId"
##############################################################################
#
# INSTANCES
#
##############################################################################
PipelineInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: !Select [ 0, !GetAZs '' ]
IamInstanceProfile: !Ref PipelineEc2InstanceProfile
InstanceType: !Ref EC2InstanceType
ImageId: !Ref EC2ImageId
KeyName: !Ref SSHKeyName
SecurityGroupIds:
- !GetAtt PipelineSecurityGroup.GroupId
SubnetId:
Fn::ImportValue:
!Sub "${VpcStackName}-PrivateSubnet4"
Tags:
- Key: Name
Value: !Join [ '-', [ !Ref Prefix, !Ref EnvironmentName, 'ec2-raw-pipeline', !Select [ 7, !Split [ '-', !Ref AWS::StackId ] ] ] ]
UserData:
Fn::Base64: !Sub |
#!/bin/bash
cd /tmp
sudo yum update -y
sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
sudo systemctl enable amazon-ssm-agent
sudo systemctl start amazon-ssm-agent
VpcEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: True
SecurityGroupIds:
- !GetAtt SsmSecurityGroup.GroupId
ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm"
SubnetIds:
- Fn::ImportValue:
!Sub "${VpcStackName}-PrivateSubnet4"
VpcEndpointType: 'Interface'
VpcId:
Fn::ImportValue:
!Sub "${VpcStackName}-VpcId"
################################################################################
#
# OUTPUTS
#
################################################################################
Outputs:
PipelineEc2PrivateUrl:
Description: Private DNS name of the newly created EC2 instance
Value: !GetAtt [ PipelineInstance, PrivateDnsName ]
PipelineEc2PrivateIp:
Description: Private IP address of the newly created EC2 instance
Value: !GetAtt [ PipelineInstance, PrivateIp ]