-
Notifications
You must be signed in to change notification settings - Fork 3
Lesson 1: Security Group, Instance and Role
- Security groups are the main line of IT security defenses within AWS. An instance is placed within a security group and inherits a firewall from the rules of the group.
- Instances are the building blocks of an AWS infrastructure, they are virtual machines running in the aws cloud.
- Roles allow a machine by itself to obtain certain permissions, such as getting data from a specific S3 bucket. It's a great way to give tasks to machines in the absence of users, or to distribute processing nicely.
- To teach the complexities and intricacies of Terraform, now we move to a much more real-world example and demonstrate how much Terraform can contain and streamline our infrastructure allocation.
- You are already a Terraform expert or this is not a relevent part of Terraform for you.
We can create security groups, roles and instances with the aws console. It's pretty easy to do that.
And then we can add an instance to that security group:
And we won't stop there, now we can add a role to the instance so that people or applications on that instance have access to S3. Amazon describes this themselves using their own tutorial videos:
Now, you could repeat this process for each new machine, and juggle around the configuration of security groups in your head, on pieces of paper, on diagrams, and in internal communications. However this just isn't scalable to large infrastructures and does not permit roll-backs in case of mistakes. It commits you to certain static infrastructure. To escape this, we need IaC.
In Terraform, creating a security group, a Role, and an instance, for an existing VPC would be done with a file like this:
#provider
provider "aws" {
region = "eu-west-1"
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
}
# variables
variable "myamiid" {
type = "string"
default = "ami-332422"
}
variable "myvpcid" {
type = "string"
default = "vpc-1701"
}
#find info, I want to place into the first and only default subnet
data "aws_subnet_ids" "mysubnetid" {
vpc_id = "${var.myvpcid}"
}
# make security group
resource "aws_security_group" "allow_all" {
name = "allow_all"
description = "Allow all traffic"
vpc_id = "${var.myvpcid}"
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# make policy inside a role directly
resource "aws_iam_role" "test_role" {
name = "test_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
},
{
"Action": "s3:*",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_instance_profile" "s3_profile" {
name = "${aws_iam_role.test_role.name}"
role = "${aws_iam_role.test_role.name}"
}
# make instance attached to this policy, in this group
resource "aws_instance" "talktos3" {
ami = "${var.myamiid}"
instance_type = "t2.micro"
subnet_id = "${element(data.aws_subnet_ids.mysubnetid.ids, 0)}"
vpc_security_group_ids = ["${aws_security_group.allow_all.id}"]
iam_instance_profile = "${aws_iam_instance_profile.s3_profile.name}"
associate_public_ip_address = true
}
# outputs
output "ip" {
value = "${aws_instance.talktos3.public_ip}"
}
To summarize: We started by creating a security group with a ingress and egress rules that are open to the world, in production, you should refrain from doing that for security reason. In production only allow ingress and egress to and from places you trust.
We later created a role with an inline policy and an instance profile. The instance profile allows aws ec2 service to find that role and we made sure the role can be assumed by an ec2 instance with the inline policy.
Once we had the IAM resources we need we used the subnet data
resource in order to get a list of available subnets.
Since this tutorial assumes we are using the default subnet with the default vpc we can told Terraform to use the first (and only) subnet in the resulting list.
We also used the data
resource for finding the latest Ubuntu AMI and finally we used all of the resources we created to define our ec2 instance.
Create a .tf file based upon the code above, validate it and 'plan' it if possible with Terraform. If you are on a sandbox environment, try applying/destroying this infrastructure with Terraform. Note that you will have to find your VPC-id.
We use an inline policy above, which helps us directly create a role and a dedicated policy together. There are several other ways to construct this such as:
- reading the policy from a separate json file
- creating the policy in the console and referencing it here
- creating the policy as a separate resource declaration
Choose one of these three options to implement yourself, and get through to the 'validate' stage.
The nature of a security group, instance and role, within aws. How to create and destroy these with Terraform.