Creating EC2 Instance with Cloud Formation
Tags: aws, cloudformation
Published: 2021-01-28 17:18:27

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 let's 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 key name property, I’m supplying the name of an existing EC2 KeyPair.  If this KeyPair doesn't 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.