Skip to main content

Terraform basics using aws provider

Updated 5 min readMarkdown
Terraform basics using aws provider

Terraform basics

Terraform installation

  • Terraform installation page

  • Linux installation:

    wget -O - https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
    sudo apt update && sudo apt install terraform
    
  • Installation check

    > $ terraform --version
    
    Terraform v1.10.5
    on linux_amd64
    

AWS CLI installation

  • AWS CLI usage

  • AWS CLI installation doc

    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    unzip awscliv2.zip
    sudo ./aws/install
    
  • AWS CLI configuration

    • AWS CLI configuration doc

    • create an admin user through the console: IAM section

    • Connect using the admin user credentials:

      $ aws configure
      
      AWS Access Key ID [None]: accesskey
      AWS Secret Access Key [None]: secretkey
      Default region name [None]: us-west-2
      Default output format [None]:
      

Terraform user

We can create a terraform through:

  • AWS console, in the IAM section

  • AWS CLI:

    # Create user
    aws iam create-user --user-name terraform-user
    
    # Create an access key, Terraform will use it to make API call to manage AWS resources(save the output securely as it shows only once)
    aws iam create-access-key --user-name terraform-user
    
    # Attach the AmazonEC2FullAccess policy
    aws iam attach-user-policy \
      --user-name terraform-user \
      --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
    

By now we only use EC2 management, but policies will be updated as our needs will.

Terraform configuration

If you using Visual studio code you may use the terraform extension

Terraform provider

Terraform is designed to use providers depending on resource you want to manage like public cloud, containers orchestrator and others... All providers are available here

In our use case the provider is AWS

Let's configure it. Create and edit a main.tf file with the following code:

provider "aws" {
    region = "eu-west-3"
    access_key = var.AWS_ACCESS_KEY
    secret_key = var.AWS_SECRET_KEY
}

Declare credentials directly in the tf file is obviously a lack of security. Let's create a variable file vars.tf to solve this:

variable "AWS_ACCESS_KEY" {}
variable "AWS_SECRET_KEY" {}

And a specific file terraform.tfvars for the credential, this will be declared in the .gitignore

AWS_ACCESS_KEY="your_access_key"
AWS_SECRET_KEY="your_secret_key"

AWS Resource creation

Let's create our first resource:

When using terraform the general syntax is "

resource "<PROVIDER>_<TYPE>" "NAME" {
 CONFIG_BLOC
}

Let's create a very basic EC2 instance, based on the Terraform aws_instance documentation

  • PROVIDER: aws
  • TYPE: instance
  • NAME: a id to use our resource within Terraform: my_ec2_instance
  • CONFIG:
    • ami: stands for Amazon Machine Image, a unique ID refering to an OS on a specific region You can retrieve this id here: https://cloud-images.ubuntu.com/locator/ec2/, or in the AWS console
    • instance_type: an instance corresponds to a server with specific CPU, Memory and network capacity, here we chose t3.micro (instance type doc)
resource "aws_instance" "my_ec2_instance" {
    ami = "ami-06e02ae7bdac6b938"
    instance_type = "t3.micro"
    tags = {
        Name = "my_ec2_instance"
    }
}

Run terraform commad to create the resource:

> $ terraform init # Initate terraform based on provider

Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/aws v5.84.0

Terraform has been successfully initialized!

> $ terraform plan # Describe desired state and actions

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.my_ec2_instance will be created
  + resource "aws_instance" "my_ec2_instance" {
      + ami                                  = "ami-06e02ae7bdac6b938"
      + ...

> $ terraform apply # Create resources

...

aws_instance.my_ec2_instance: Creating...
aws_instance.my_ec2_instance: Still creating... [10s elapsed]
aws_instance.my_ec2_instance: Creation complete after 13s [id=i-0f3835eca43c80125]

Add web server

Let's install apache a quick configure it using terraform, below basic commands to set up a web server:

#!/bin/bash
sudo apt-get update
sudo apt-get install -y apache2
sudo systemctl start apache2
sudo systemctl enable apache2
sudo echo "<h1>Hello devopssec</h1>" > /var/www/html/index.html

Let's add them into our main.tf file:

resource "aws_instance" "my_ec2_instance" {
    ami = "ami-06e02ae7bdac6b938"
    instance_type = "t3.micro"
    user_data = <<-EOF
        #!/bin/bash
        sudo apt-get update
        sudo apt-get install -y apache2
        sudo systemctl start apache2
        sudo systemctl enable apache2
        sudo echo "<h1>Hello devopssec</h1>" > /var/www/html/index.html
    EOF
    tags = {
        Name = "my_ec2_instance"
    }
}

To have access to our web site we need to configure security groups to allow connection from anywhere on port 80

resource "aws_security_group" "instance_sg" {
    name = "terraform-test-sg"

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

    ingress {
        from_port   = 80
        to_port     = 80
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

The EC2 also need to be bind to this security group. Once the security group is created, variables from the terraform output are available, we can configure our EC2 to use the vpc ID from the security group creation by adding: vpc_security_group_ids = [aws_security_group.instance_sg.id]

resource "aws_instance" "my_ec2_instance" {
    ami = "ami-06e02ae7bdac6b938"
    instance_type = "t3.micro"
    vpc_security_group_ids = [aws_security_group.instance_sg.id]
    user_data = <<-EOF
        #!/bin/bash
        sudo apt-get update
        sudo apt-get install -y apache2
        sudo systemctl start apache2
        sudo systemctl enable apache2
        sudo echo "<h1>Hello devopssec</h1>" > /var/www/html/index.html
    EOF
    tags = {
        Name = "my_ec2_instance"
    }
}

Cleaning the infra

To clean infrastructure based on main.tf, run the following command: terraform destroy

No comments yet. Be the first to comment.