I'm working with CloudFormation trying to deploy an EC2 and an RDS into security groups, with the EC2 SG as a WebDMZ group and the RDS SG only open to traffic from the EC2 group.
The security groups are working correctly, but the EC2 and RDS instances both give me the same error that they can't find the security group in VPC XYZ123, where XYZ123 is the ID of the default VPC--the only VPC, and I've verified that my security groups are indeed in that VPC.
I tried the code for my EC2 in another template and it worked, but only if I specifically assigned it to a public subnet.
This code is academic, not for production. Can't I just have my assets deploy to a default or random subnet? Aren't Security Groups at the instance level, so as long as it's the correct VPC it should be fine? What am I missing?
Resources:
04WebDMZ:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open to HTTP, HTTPS and SSH on all ports
GroupName: 04WebDMZ
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: 04WebDMZ
04DatabaseSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open to 04WebDMZ
GroupName: 04DatabaseSG
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupName:
Ref: 04WebDMZ
Tags:
- Key: Name
Value: 04DatabaseSG
04PublicEC2:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-047a51fa27710816e
InstanceType: t2.micro
KeyName: my_key_pair
NetworkInterfaces:
- AssociatePublicIpAddress: True
DeviceIndex: 0
DeleteOnTermination: True
Tags:
- Key: Name
Value: 04PublicEC2
UserData:
!Base64 |
#!/bin/bash
yum install httpd php php-mysql -y
cd /var/www/html
wget https://wordpress.org/wordpress-5.1.1.tar.gz
tar -xzf wordpress-5.1.1.tar.gz
cp -r wordpress/* /var/www/html/
rm -rf wordpress
rm -rf wordpress-5.1.1.tar.gz
chmod -R 755 wp-content
chown -R apache:apache wp-content
service httpd start
chkconfig httpd on
04RDS:
Type: AWS::RDS::DBInstance
Properties:
DBSecurityGroups:
- Ref: 04DatabaseSG
AllocatedStorage: '5'
DBInstanceClass: db.t2.small
Engine: MySQL
MasterUsername: admin
MasterUserPassword: admin
Tags:
- Key: Name
Value: 04RDS
DeletionPolicy: Snapshot
Screenshot of the error: https://imgur.com/a/WRw5BWi
Related
Hi I have tested my ec2 instance working or not from AWS console.
And it works fine.
I have added the sample script to show hello world text in user data section.
And then pasted the ip address without http 's'.
Of course, it shows the text.
And I am trying to show the same text, but this time by using cloudformation.
I have made it as followings. Everything looks the same as the one made through AWS console.
However, the cloudformation one does not allow me to assess on web and the request gets hanged.
I have no idea what I am missing,
Can Someone please point out?
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Type: AWS::EC2::KeyPair::KeyName
ConstraintDescription: must be the name of an existing EC2 KeyPair.
InstanceType:
Description: WebServer EC2 instance type
Type: String
Default: t2.micro
AllowedValues:
- t1.micro
- t2.nano
- t2.micro
SSHLocation:
Description: The IP address range that can be used to SSH to the EC2 instances
Type: String
MinLength: '9'
MaxLength: '18'
Default: 0.0.0.0/0
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
Mappings:
AWSInstanceType2Arch:
t1.micro:
Arch: PV64
t2.nano:
Arch: HVM64
t2.micro:
Arch: HVM64
AWSInstanceType2NATArch:
t1.micro:
Arch: NATPV64
t2.nano:
Arch: NATHVM64
t2.micro:
Arch: NATHVM64
AWSRegionArch2AMI:
ca-central-1:
PV64: NOT_SUPPORTED
HVM64: ami-730ebd17
HVMG2: NOT_SUPPORTED
Resources:
# ===== EC2 Instance =====
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType:
Ref: InstanceType
SecurityGroups:
- Ref: InstanceSecurityGroup
KeyName:
Ref: KeyName
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
sudo su
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello World from $(hostname -f)</h1>" > /var/www/html/index.html
ImageId:
Fn::FindInMap:
- AWSRegionArch2AMI
- Ref: AWS::Region
- Fn::FindInMap:
- AWSInstanceType2Arch
- Ref: InstanceType
- Arch
# ===== Security Group =====
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
# SSH
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp:
Ref: SSHLocation
# HTTP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp:
Ref: SSHLocation
# HTTPS
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp:
Ref: SSHLocation
There is nothing wrong with the template you showed and it works as expected (assuming that your AMI is for Amazon Linux 2). So probably your template in the question is not the one you are actually using, or perhaps you are using different operating system that you think you are. You have to double check your actual code.
Which parameter value did you use for SSHLocation?
If you want to have 80 and 443 publicly accessible and SSH only with your own IP, you will probably want to put instead the following SG.
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
# SSH
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp:
Ref: SSHLocation
# HTTP
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
# HTTPS
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Then SSH your machine and check the web server conf inside.
I am new to cloudformation and YAML and I am trying to create 2 ec2 instances in different regions and to attach them to a load balancer
These are the parameters
Parameters:
KeyName:
Description: Name of an existing EC2 Key Pair
Type: AWS::EC2::KeyPair::KeyName
VPC:
Type: AWS::EC2::VPC::Id
Description: Choose which VPC that the Application Load Balancer should be deployed to
Subnets:
Description: Choose minimum of 2 subnets (2 different availability zones) that Application Load Balancer should be deployed to
Type: List<AWS::EC2::Subnet::Id>
After that I added the ressources. The first one is the security group.
Resources:
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDEscription: Enable SSH access via port 22 and Enable Http via port 80
SecurityGroupEngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
The first ec2 instance with the location in Frankfurt
# Frankfurt
Ec2Instance1:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-043097594a7df80ec
KeyName: !Ref KeyName
SecurityGroups:
- !Ref SecurityGroup
UserData:
'Fn::Base64':
!Sub |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1> Hello World from $(hostname -f)</h1>" > /var/www/html/index.html
Second ec2 instance with the location in Virginia
# N. Virginia
Ec2Instance2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0d5eff06f840b45e9
KeyName: !Ref KeyName
SecurityGroups:
- !Ref SecurityGroup
UserData:
'Fn::Base64':
!Sub |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1> Hello World from $(hostname -f)</h1>" > /var/www/html/index.html
The code for load balancer. The ApplicationLoadBalancer:
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: 'MyLoadBalancer1'
Subnets: !Ref Subnets
SecurityGroups: [!GetAtt SecurityGroup.GroupId]
After that comes the ALBListener:
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroup
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
And the TargetGroup:
ALBTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Protocol: HTTP
Port: 80
HealthCheckIntervalSeconds: 30
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 10
HealthyThresholdCount: 3
Matcher:
HttpCode: '200'
Name: MyTargets
Targets:
- Id:
Ref: EC2Instance1
Port: 80
- Id:
Ref: EC2Instance2
Port: 80
VpcId: !Ref VPC
I am learning AWS and is trying to setup a web server on ec2, but I can't access the web server from outside even after I tried everything I can think of.
Here is the cloudformation template I am using:
AWSTemplateFormatVersion: "2010-09-09"
Resources:
## VPC
# Create a VPC
HelloVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: "true"
EnableDnsSupport: "true"
Tags:
- Key: Name
Value: HelloVpc
# Create internet gateway for public subnet
HelloInternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: HelloInternetGateway
HelloVPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: HelloVpc
InternetGatewayId:
Ref: HelloInternetGateway
# Create route table for public subnet
HelloPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: HelloPublicRouteTable
VpcId:
Ref: HelloVpc
HelloInternetGatewayRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId:
Ref: HelloPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId:
Ref: HelloInternetGateway
# create subnets
HelloVpcPrivateSubNet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: HelloVpc
AvailabilityZone: { "Fn::Select": [0, { "Fn::GetAZs": "" }] }
CidrBlock: 10.0.2.0/24
Tags:
- Key: Name
Value: HelloVpcPrivateSubNet
HelloVpcPublicSubNet:
Type: AWS::EC2::Subnet
Properties:
VpcId:
Ref: HelloVpc
AvailabilityZone: { "Fn::Select": [1, { "Fn::GetAZs": "" }] }
CidrBlock: 10.0.1.0/24
Tags:
- Key: Name
Value: HelloVpcPublicSubNet
HelloPublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
Ref: HelloPublicRouteTable
SubnetId:
Ref: HelloVpcPublicSubNet
## Security group
HelloSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow http and ssh
VpcId:
Ref: HelloVpc
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 5000
ToPort: 5000
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 5000
ToPort: 5000
CidrIp: 0.0.0.0/0
## EC2
HelloEc2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: ami-0c91eefc31e3b0867
InstanceType: t3.nano
KeyName: EC2-KP
NetworkInterfaces:
- AssociatePublicIpAddress: "true"
DeviceIndex: "0"
SubnetId:
Ref: HelloVpcPublicSubNet
GroupSet:
- Ref: HelloSecurityGroup
Then I SSH into the instance and started a web server with
mkdir app
cd app
dotnet new web
dotnet run
which starts a web server on port 5000 and curl http://localhost:5000 works fine.
Since I can ssh into the instance, the ACL and security group should be correct. I googled around and tried to disable the firewall with
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -F
but it still doesn't work.
At this point, I really have no idea what goes wrong. Can anyone please help?
The problem is that dotnet run causes your app to listen on localhost, so it's only reachable locally within the server itself.
You need it to bind to the public IP of the server, which you can do as follows:
dotnet run --urls http://0.0.0.0:5000
For additional options to set the URL, see here.
---
Parameters:
SSHKey:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-1a
ImageId: ami-00eb20669e0990cb4
InstanceType: t2.micro
SubnetId: subnet-082bbf8546527d556
KeyName: !Ref SSHKey
SecurityGroups:
- !Ref SSHSecurityGroup
# we install our web server with user data
UserData:
Fn::Base64: |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "Hello World from user data" > /var/www/html/index.html
# our EC2 security group
SSHSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SSH and HTTP
SecurityGroupIngress:
- CidrIp: 10.20.20.0/24
FromPort: 22
IpProtocol: tcp
ToPort: 22
- CidrIp: 10.20.20.0/24
FromPort: 80
IpProtocol: tcp
ToPort: 80
I am creating a basic security group using cloud formation on AWS but I am getting Property IpProtocol cannot be empty. error. Following is the yml code I am running:
Resources:
testsecuritygroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: test-group
GroupDescription: test security group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
- SourceSecurityGroupId: sg-xxxxxxxxxx
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0
Tags:
- Key: group
Value: test
VpcId: !ImportValue VPC
When I run create-stack command it is running successfully but the stack is rolled back with CREATE_FAILED status and Property IpProtocol cannot be empty error. What I am doing wrong here?
I resolved this issue. To add a security group we have to create an Ingress rule and attach it to the security group instead of defining it in the security group.
Resources:
test:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !ImportValue VPC
GroupName: test-group
GroupDescription: test security group
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Tags:
- Key: group
Value: test
TestInboundRule:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !GetAtt test.GroupId
IpProtocol: tcp
FromPort: 80
ToPort: 80
SourceSecurityGroupId: sg-xxxxxxxxx
Your cidr is not valid. It should be 0.0.0.0/0