Creating EC2 Instances with CloudFormation
So in this post we’re going to take a look at how you can create an AWS EC2 Instance using a CloudFormation template. We’re going to create a few different resources in our template and then talk briefly about how to use the template to create a stack in the AWS portal.
So first up we need to create a new YAML file for our template. I use VSCode for this but you can use any text editor you like.
Your basic template should look like this:
AWSTemplateFormatVersion: 2010-09-09 Description: >- Creating an EC2 Instance Resources:
Now we can create our resources in any order we like so lets start by adding a SecurityGroup. we can use this to allow traffic to our instance on port 80 and port 22. We need access to port 22 for SSH access. That way we can connect remotely to our instance.
The definition of our security group resources looks like this and you can see it defines two ingress rules, one for port 80 and one for port 22.
WebServerSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: >- Enable HTTP access via port 80 + SSH access 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
Next up we need to define our EC2 resource. Now in this example, I’m setting the ImageId, InstanceType and KeyName properties directly here, in a future post we will look at how we can bind these values to input parameters.
WebServer: Type: 'AWS::EC2::Instance' Properties: ImageId: 'ami-01419b804382064e4' InstanceType: 't2.small' SecurityGroups: - !Ref WebServerSecurityGroup KeyName: 'myEC2KeyPair'
Now there are a couple of things to point out here. Firstly notice how we reference our security group using the inbuilt Ref function.
Secondly for the keyname property I’m supplying the name of an existing EC2 KeyPair. If this KeyPair doesnt already exist then template creation will fail.
Finally let’s add an ElasticIP address and associate it with our EC2 instance. To do this we’re going to create two resources. The ElasticIP address itself and an IPAssociation resource to tie the IP address to the instance.
IPAddress: Type: 'AWS::EC2::EIP' IPAssoc: Type: 'AWS::EC2::EIPAssociation' Properties: InstanceId: !Ref WebServer EIP: !Ref IPAddress
Again, notice how we can reference other resources within our template using the Ref function.
So our finished template now looks like this:
AWSTemplateFormatVersion: 2010-09-09 Description: >- Creating an EC2 Instance Resources: WebServerSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: >- Enable HTTP access via port 80 + SSH access 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 WebServer: Type: 'AWS::EC2::Instance' Properties: ImageId: 'ami-01419b804382064e4' InstanceType: 't2.small' SecurityGroups: - !Ref WebServerSecurityGroup KeyName: 'myEC2KeyPair' IPAddress: Type: 'AWS::EC2::EIP' IPAssoc: Type: 'AWS::EC2::EIPAssociation' Properties: InstanceId: !Ref WebServer EIP: !Ref IPAddress
Creating a Stack
Now you have your template you probably want to use it to create some resources.
There are several ways you can do this but the easiest, especially when starting out is to use the AWS Portal.
Simply log into AWS, select CloudFormation from the Services menu (under Management & Governance) and click “Create a Stack”
Simply upload your template and follow the prompts and after a few minutes your resources will be created.