Terraform How to create an EC2 instance on AWS

I have done practical tutorial in Create infrastructure | Terraform | HashiCorp Developer

Like to share the commands and usages with terraform to spin up an EC2 instance.

terraform {

required_providers {

aws = {

source = "hashicorp/aws"

version = "~> 5.92"

}

}

required_version = ">= 1.2"

}

provider "aws" {

region = "us-west-2"

access_key = "anaccesskey"

secret_key = "asecretkey"

s3_use_path_style = true

skip_credentials_validation = true

skip_metadata_api_check = true

skip_requesting_account_id = true

endpoints {

ec2 = "http://localhost:4566"

}

}

data "aws_ami" "linux" {

most_recent = true

filter {

name = "name"

values = ["amzn2-ami-hvm-2.0.*-x86_64-ebs"]

}

owners = ["137112412989"] # Amazon

}

resource "aws_instance" "app_server" {

ami = data.aws_ami.linux.id

instance_type = "t2.micro"

tags = {

Name = "hashicorp-learn"

}

}

Create infrastructure

*********************

To create your infrastructure, you must first use terraform init to install your configuration's required components

terraform cli

*************

# terraform fmt

terraform.tf

# terraform init

Initializing the backend...

Initializing provider plugins...

- Finding hashicorp/aws versions matching "~> 5.92"...

- Installing hashicorp/aws v5.100.0...

- Installed hashicorp/aws v5.100.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider

selections it made above. Include this file in your version control repository

so that Terraform can guarantee to make the same selections by default when

you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see

any changes that are required for your infrastructure. All Terraform commands

should now work.

If you ever set or change modules or backend configuration for Terraform,

rerun this command to reinitialize your working directory. If you forget, other

commands will detect it and remind you to do so if necessary.

#

Apply configuration

Terraform needs to authenticate with your cloud provider before it can make any changes. For this lab environment, the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are already set. Terraform's AWS provider will automatically use these variables to authenticate with the AWS API when you use it to manage your infrastructure.

# aws configure list

Name Value Type Location

---- ----- ---- --------

profile <not set> None None

access_key ****************skey shared-credentials-file

secret_key ****************skey shared-credentials-file

region <not set> None None

#

Apply your configuration to create your EC2 instance. Terraform will print out a plan to make this change, and wait for you to confirm it. Respond to the confirmation prompt with a yes to confirm the plan.

********************************************************************************************************************************************************************************************************

# terraform apply

data.aws_ami.linux: Reading...

data.aws_ami.linux: Read complete after 4s [id=ami-022552c8354f3cb14]

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.app_server will be created

+ resource "aws_instance" "app_server" {

+ ami = "ami-022552c8354f3cb14"

+ arn = (known after apply)

+ associate_public_ip_address = (known after apply)

+ availability_zone = (known after apply)

+ cpu_core_count = (known after apply)

+ cpu_threads_per_core = (known after apply)

+ disable_api_stop = (known after apply)

+ disable_api_termination = (known after apply)

+ ebs_optimized = (known after apply)

+ enable_primary_ipv6 = (known after apply)

+ get_password_data = false

+ host_id = (known after apply)

+ host_resource_group_arn = (known after apply)

+ iam_instance_profile = (known after apply)

+ id = (known after apply)

+ instance_initiated_shutdown_behavior = (known after apply)

+ instance_lifecycle = (known after apply)

+ instance_state = (known after apply)

+ instance_type = "t2.micro"

+ ipv6_address_count = (known after apply)

+ ipv6_addresses = (known after apply)

+ key_name = (known after apply)

+ monitoring = (known after apply)

+ outpost_arn = (known after apply)

+ password_data = (known after apply)

+ placement_group = (known after apply)

+ placement_partition_number = (known after apply)

+ primary_network_interface_id = (known after apply)

+ private_dns = (known after apply)

+ private_ip = (known after apply)

+ public_dns = (known after apply)

+ public_ip = (known after apply)

+ secondary_private_ips = (known after apply)

+ security_groups = (known after apply)

+ source_dest_check = true

+ spot_instance_request_id = (known after apply)

+ subnet_id = (known after apply)

+ tags = {

+ "Name" = "hashicorp-learn"

}

+ tags_all = {

+ "Name" = "hashicorp-learn"

}

+ tenancy = (known after apply)

+ user_data = (known after apply)

+ user_data_base64 = (known after apply)

+ user_data_replace_on_change = false

+ vpc_security_group_ids = (known after apply)

+ capacity_reservation_specification (known after apply)

+ cpu_options (known after apply)

+ ebs_block_device (known after apply)

+ enclave_options (known after apply)

+ ephemeral_block_device (known after apply)

+ instance_market_options (known after apply)

+ maintenance_options (known after apply)

+ metadata_options (known after apply)

+ network_interface (known after apply)

+ private_dns_name_options (known after apply)

+ root_block_device (known after apply)

}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?

Terraform will perform the actions described above.

Only 'yes' will be accepted to approve.

Enter a value: yes

aws_instance.app_server: Creating...

aws_instance.app_server: Still creating... [00m10s elapsed]

aws_instance.app_server: Creation complete after 10s [id=i-bfef111a643702f45]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

#

Inspect state

Terraform stores your workspace's state in a file named terraform.tfstate.

# pwd

/root/learn-terraform-aws-get-started

#

# pwd

/root/learn-terraform-aws-get-started

# ls -al

total 28

drwxr-xr-x 3 root root 4096 Sep 18 20:24 .

drwx------ 7 root root 4096 Sep 18 20:18 ..

drwxr-xr-x 3 root root 4096 Sep 18 20:18 .terraform

-rw-r--r-- 1 root root 1408 Sep 18 20:18 .terraform.lock.hcl

-rw-r--r-- 1 root root 0 Sep 18 20:07 main.tf

-rw-r--r-- 1 root root 809 Sep 18 20:17 terraform.tf

-rw-r--r-- 1 root root 6978 Sep 18 20:24 terraform.tfstate -----> this file contains workspace state in this file

List state

List the resources and data sources in your state with the terrafrom state list command.

# pwd

/root/learn-terraform-aws-get-started

# terraform state list

data.aws_ami.linux

aws_instance.app_server

#

#

Show state

Print out your workspace's entire state with terraform show.

# terraform show

# data.aws_ami.linux:

data "aws_ami" "linux" {

architecture = "x86_64"

arn = "arn:aws:ec2:us-west-2::image/ami-022552c8354f3cb14"

block_device_mappings = [

{

device_name = "/dev/xvda"

ebs = {

"delete_on_termination" = "false"

"encrypted" = "false"

"iops" = "0"

"snapshot_id" = "snap-a5672f21f82b1bcaf"

"throughput" = "0"

"volume_initialization_rate" = "0"

"volume_size" = "15"

"volume_type" = "standard"

}

no_device = null

virtual_name = null

},

]

boot_mode = "uefi"

creation_date = "2025-09-18T20:22:39.000Z"

deprecation_time = null

description = "Amazon Linux 2 AMI 2.0.20250818.2 x86_64 HVM ebs"

ena_support = false

hypervisor = "xen"

id = "ami-022552c8354f3cb14"

image_id = "ami-022552c8354f3cb14"

image_location = null

image_owner_alias = "amazon"

image_type = "machine"

imds_support = null

include_deprecated = false

kernel_id = null

last_launched_time = null

most_recent = true

name = "amzn2-ami-hvm-2.0.20250818.2-x86_64-ebs"

owner_id = "137112412989"

owners = [

"137112412989",

]

platform = null

platform_details = null

product_codes = []

public = true

ramdisk_id = null

root_device_name = "/dev/xvda"

root_device_type = "ebs"

root_snapshot_id = "snap-a5672f21f82b1bcaf"

sriov_net_support = null

state = "available"

state_reason = {

"code" = "UNSET"

"message" = "UNSET"

}

tags = {}

tpm_support = null

usage_operation = null

virtualization_type = "hvm"

filter {

name = "name"

values = [

"amzn2-ami-hvm-2.0.*-x86_64-ebs",

]

}

}

# aws_instance.app_server:

resource "aws_instance" "app_server" {

ami = "ami-022552c8354f3cb14"

arn = "arn:aws:ec2:us-west-2::instance/i-bfef111a643702f45"

associate_public_ip_address = true

availability_zone = "us-west-2a"

disable_api_stop = false

disable_api_termination = false

ebs_optimized = false

get_password_data = false

hibernation = false

host_id = null

iam_instance_profile = null

id = "i-bfef111a643702f45"

instance_initiated_shutdown_behavior = "stop"

instance_lifecycle = null

instance_state = "running"

instance_type = "t2.micro"

ipv6_address_count = 0

ipv6_addresses = []

key_name = null

monitoring = false

outpost_arn = null

password_data = null

placement_group = null

placement_partition_number = 0

primary_network_interface_id = "eni-b812cec48db0f7729"

private_dns = "ip-10-162-31-21.us-west-2.compute.internal"

private_ip = "10.162.31.21"

public_dns = "ec2-54-214-32-100.us-west-2.compute.amazonaws.com"

public_ip = "54.214.32.100"

secondary_private_ips = []

security_groups = []

source_dest_check = true

spot_instance_request_id = null

subnet_id = "subnet-f30ffd304d583bac5"

tags = {

"Name" = "hashicorp-learn"

}

tags_all = {

"Name" = "hashicorp-learn"

}

tenancy = "default"

user_data_replace_on_change = false

vpc_security_group_ids = []

metadata_options {

http_endpoint = "enabled"

http_protocol_ipv6 = "disabled"

http_put_response_hop_limit = 1

http_tokens = "optional"

instance_metadata_tags = "disabled"

}

root_block_device {

delete_on_termination = true

device_name = "/dev/sda1"

encrypted = false

iops = 0

kms_key_id = null

tags = {}

tags_all = {}

throughput = 0

volume_id = "vol-37651716444707f69"

volume_size = 8

volume_type = "gp2"

}

}

# terraform fmt

main.tf

#


To view or add a comment, sign in

More articles by Nandhakumar T.A

  • Terraform Install on Windows 64bit Machine

    Go to ---> google.com---> search terraform click the Hyper link - Terraform | HashiCorp Developer click on Install --->…

    2 Comments
  • Git merge functionality

    In real life scenarios, Developers will clone the content from main branch, In this example as developer I have created…

    1 Comment

Explore content categories