top of page
  • Writer's pictureTaylor Etheredge

Implementation of a set of EC2 instances using Terraform and AWS Systems Manager

Updated: Nov 10, 2023


In this project based on a real-world scenario, I acted as DevSecOps Engineer, and I deployed a set of EC2 instances and infrastructure in an automated way using Terraform (infrastructure as code - IaC). Also, it was necessary to install a specific security agent on all these instances in an automated way.

Once I provisioned the infrastructure, AWS System Manager and its component Command Run were used to install the security agents in an automated way. I used the Amazon Simple Notification Service – SNS to send an email informing the whole process status.


First thing to get started is to install Terraform inside the AWS Cloud Shell so that the infrastructure can be deployed. Run the following commands:

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
sudo yum -y install terraform

Now that Terraforrm is installed we need to run the following command to initialize the environment.

terraform init

Here are the Terraform files that were used to deploy the infrastructure on AWS:


main.tf

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

variable "vpc_id" {
    default = "default-vpc"
}

variable "subnet_id" {
    default = "default-subnet"
}

variable "key_name" {
    default = "ssh-key"
}


resource "aws_security_group" "allow_ssh" {
  name        = "allow_ssh"
  description = "Allow external SSH connectivity to EC2 instances"
  vpc_id      = var.vpc_id

  ingress {
    description = "SSH to EC2"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "allow_ssh"
  }
}

resource "aws_instance" "webserver1" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  key_name = var.key_name
  subnet_id = var.subnet_id
  vpc_security_group_ids = [aws_security_group.allow_ssh.id]
  associate_public_ip_address = true

  tags = {
    Name = "webserver1"
  }
}


resource "aws_instance" "webserver2" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"
  key_name = var.key_name
  subnet_id = var.subnet_id
  vpc_security_group_ids = [aws_security_group.allow_ssh.id]
  associate_public_ip_address = true

  tags = {
    Name = "webserver2"
  }
}

You will need to replace the variables that are defined, such as vpc_id, subnet_id, and key_name, with your correct values in order for the plan to run.


provider "aws" {
    region = "us-east-1"
}

Replace the region with the correct AWS region you want to deploy to.


Now run the following command to apply the infrastructure in AWS.

terraform apply

This command will build out the EC2 instances as well as the security group to allow SSH access into the instances and allow all traffic out of the instances.


The next thing we need to do is create an new role in IAM called SystemsManagerToSNS and assign it a policy of AmazonSNSFullAccess. Then create a notification topic called DevOpsNotification and copy the ARN associated with the topic. Create a subscription and set it to use a the email option.


Now with the subscription setup, the Systems Manager needs to be setup to automatically run the command on the EC2 instances. Go to the Systems Manager service and run the quick setup from the left hand pane. The configuration type should be host management and the set it to choose the instances manually. Then select the EC2 instances created using Terraform. Next to deploy the security agent, select the "Run Command" button and put for the command document, AWS-RunShellScript. For the command parameters put in:

sudo wget -q https://tcb-bootcamps.s3.amazonaws.com/bootcamp-aws/en/install_security_agent.sh -P /tmp
sudo chmod +x /tmp/install_security_agent.sh
sudo /tmp/install_security_agent.sh
ls -ltr /usr/bin/security_agent

For the targets choose instances manually, uncheck enable S3 bucket. Enable the SNS notification and put in the IAM role of SystemsManagerToSNS. Then put in the SNS topic that we copied from the previous step. For the event notifications, select all events. For the change notifications, put notifications per instance.


Now you should be able to see the result of the command run and email confirmations that it was successful or not. Here is a snippet of the command that was run on the EC2 instances:



Here is the architecture setup for this project.



Hopefully you learned how to use Terraform to provision EC2 instances and use the AWS Systems Manager to run automated tasks on the instances that were provisioned.



19 views0 comments
bottom of page