Launching EC2 using Terraform | Installing Grafana and promotues using Terraform.

 

Launching EC2 instance using Terraform:

The set of files used to describe infrastructure in Terraform is known as a Terraform configuration. You will write your first configuration to define a single AWS EC2 instance.

Each Terraform configuration must be in its own working directory. Create a directory for your configuration.

$ mkdir learn-terraform-aws-instance

Change into the directory.

$ cd learn-terraform-aws-instance

Create a file to define your infrastructure.

$ touch main.tf

Open main.tf in your text editor, paste in the configuration below, and save the file.

Tip: The AMI ID used in this configuration is specific to the us-west-2 region. If you would like to use a different region, see the Troubleshooting section for guidance.

terraform {  required_providers {    aws = {      source  = "hashicorp/aws"      version = "~> 3.27"    }  }
  required_version = ">= 0.14.9"}
provider "aws" {  profile = "default"  region  = "us-west-2"}
resource "aws_instance" "app_server" {  ami           = "ami-830c94e3"  instance_type = "t2.micro"
  tags = {    Name = "ExampleAppServerInstance"  }}

This is a complete configuration that you can deploy with Terraform. The following sections review each block of this configuration in more detail.

»Terraform Block

The terraform {} block contains Terraform settings, including the required providers Terraform will use to provision your infrastructure. For each provider, the source attribute defines an optional hostname, a namespace, and the provider type. Terraform installs providers from the Terraform Registry by default. In this example configuration, the aws provider's source is defined as hashicorp/aws, which is shorthand for registry.terraform.io/hashicorp/aws.

You can also set a version constraint for each provider defined in the required_providers block. The version attribute is optional, but we recommend using it to constrain the provider version so that Terraform does not install a version of the provider that does not work with your configuration. If you do not specify a provider version, Terraform will automatically download the most recent version during initialization.

To learn more, reference the provider source documentation.

»Providers

The provider block configures the specified provider, in this case aws. A provider is a plugin that Terraform uses to create and manage your resources.

The profile attribute in the aws provider block refers Terraform to the AWS credentials stored in your AWS configuration file, which you created when you configured the AWS CLI. Never hard-code credentials or other secrets in your Terraform configuration files. Like other types of code, you may share and manage your Terraform configuration files using source control, so hard-coding secret values can expose them to attackers.

You can use multiple provider blocks in your Terraform configuration to manage resources from different providers. You can even use different providers together. For example, you could pass the IP address of your AWS EC2 instance to a monitoring resource from DataDog.

»Resources

Use resource blocks to define components of your infrastructure. A resource might be a physical or virtual component such as an EC2 instance, or it can be a logical resource such as a Heroku application.

Resource blocks have two strings before the block: the resource type and the resource name. In this example, the resource type is aws_instance and the name is app_server. The prefix of the type maps to the name of the provider. In the example configuration, Terraform manages the aws_instance resource with the aws provider. Together, the resource type and resource name form a unique ID for the resource. For example, the ID for your EC2 instance is aws_instance.app_server.

Resource blocks contain arguments which you use to configure the resource. Arguments can include things like machine sizes, disk image names, or VPC IDs. Our providers reference documents the required and optional arguments for each resource. For your EC2 instance, the example configuration sets the AMI ID to an Ubuntu image, and the instance type to t2.micro, which qualifies for AWS' free tier. It also sets a tag to give the instance a name.

»Initialize the directory

When you create a new configuration — or check out an existing configuration from version control — you need to initialize the directory with terraform init.

Initializing a configuration directory downloads and installs the providers defined in the configuration, which in this case is the aws provider.

Initialize the directory.

$ terraform init
Initializing the backend...
Initializing provider plugins...- Finding hashicorp/aws versions matching "~> 3.27"...- Installing hashicorp/aws v3.27.0...- Installed hashicorp/aws v3.27.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the providerselections it made above. Include this file in your version control repositoryso that Terraform can guarantee to make the same selections by default whenyou run "terraform init" in the future.
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to seeany changes that are required for your infrastructure. All Terraform commandsshould 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, othercommands will detect it and remind you to do so if necessary.

Terraform downloads the aws provider and installs it in a hidden subdirectory of your current working directory, named .terraform. The terraform init command prints out which version of the provider was installed. Terraform also creates a lock file named .terraform.lock.hcl which specifies the exact provider versions used, so that you can control when you want to update the providers used for your project.

»Format and validate the configuration

We recommend using consistent formatting in all of your configuration files. The terraform fmt command automatically updates configurations in the current directory for readability and consistency.

Format your configuration. Terraform will print out the names of the files it modified, if any. In this case, your configuration file was already formatted correctly, so Terraform won't return any file names.

$ terraform fmt

You can also make sure your configuration is syntactically valid and internally consistent by using the terraform validate command.

Validate your configuration. The example configuration provided above is valid, so Terraform will return a success message.

$ terraform validateSuccess! The configuration is valid.

»Create infrastructure

Apply the configuration now with the terraform apply command. Terraform will print output similar to what is shown below. We have truncated some of the output to save space.

$ terraform apply
An execution plan has been generated and is shown below.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-830c94e3"      + arn                          = (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:

Tip: If your configuration fails to apply, you may have customized your region or removed your default VPC. Refer to the troubleshooting section at the bottom of this tutorial for help.

Before it applies any changes, Terraform prints out the execution plan which describes the actions Terraform will take in order to change your infrastructure to match the configuration.

The output format is similar to the diff format generated by tools such as Git. The output has a + next to aws_instance.app_server, meaning that Terraform will create this resource. Beneath that, it shows the attributes that will be set. When the value displayed is (known after apply), it means that the value will not be known until the resource is created. For example, AWS assigns Amazon Resource Names (ARNs) to instances upon creation, so Terraform cannot know the value of the arn attribute until you apply the change and the AWS provider returns that value from the AWS API.

Terraform will now pause and wait for your approval before proceeding. If anything in the plan seems incorrect or dangerous, it is safe to abort here with no changes made to your infrastructure.

In this case the plan is acceptable, so type yes at the confirmation prompt to proceed. Executing the plan will take a few minutes since Terraform waits for the EC2 instance to become available.

  Enter a value: yes
aws_instance.app_server: Creating...aws_instance.app_server: Still creating... [10s elapsed]aws_instance.app_server: Still creating... [20s elapsed]aws_instance.app_server: Still creating... [30s elapsed]aws_instance.app_server: Creation complete after 36s [id=i-01e03375ba238b384]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

You have now created infrastructure using Terraform! Visit the EC2 console and find your new EC2 instance.

Note: Per the aws provider block, your instance was created in the us-west-2 region. Ensure that your AWS Console is set to this region.

»Inspect state

When you applied your configuration, Terraform wrote data into a file called terraform.tfstate. Terraform stores the IDs and properties of the resources it manages in this file, so that it can update or destroy those resources going forward.

The Terraform state file is the only way Terraform can track which resources it manages, and often contains sensitive information, so you must store your state file securely and restrict access to only trusted team members who need to manage your infrastructure. In production, we recommend storing your state remotely with Terraform Cloud or Terraform Enterprise. Terraform also supports several other remote backends you can use to store and manage your state.

Inspect the current state using terraform show.

$ terraform show# aws_instance.app_server:resource "aws_instance" "app_server" {    ami                          = "ami-830c94e3"    arn                          = "arn:aws:ec2:us-west-2:561656980159:instance/i-01e03375ba238b384"    associate_public_ip_address  = true    availability_zone            = "us-west-2c"    cpu_core_count               = 1    cpu_threads_per_core         = 1    disable_api_termination      = false    ebs_optimized                = false    get_password_data            = false    hibernation                  = false    id                           = "i-01e03375ba238b384"    instance_state               = "running"    instance_type                = "t2.micro"    ipv6_address_count           = 0    ipv6_addresses               = []    monitoring                   = false    primary_network_interface_id = "eni-068d850de6a4321b7"    private_dns                  = "ip-172-31-0-139.us-west-2.compute.internal"    private_ip                   = "172.31.0.139"    public_dns                   = "ec2-18-237-201-188.us-west-2.compute.amazonaws.com"    public_ip                    = "18.237.201.188"    secondary_private_ips        = []    security_groups              = [        "default",    ]    source_dest_check            = true    subnet_id                    = "subnet-31855d6c"    tags                         = {        "Name" = "ExampleAppServerInstance"    }    tenancy                      = "default"    vpc_security_group_ids       = [        "sg-0edc8a5a",    ]
    credit_specification {        cpu_credits = "standard"    }
    enclave_options {        enabled = false    }
    metadata_options {        http_endpoint               = "enabled"        http_put_response_hop_limit = 1        http_tokens                 = "optional"    }
    root_block_device {        delete_on_termination = true        device_name           = "/dev/sda1"        encrypted             = false        iops                  = 0        tags                  = {}        throughput            = 0        volume_id             = "vol-031d56cc45ea4a245"        volume_size           = 8        volume_type           = "standard"    }}

When Terraform created this EC2 instance, it also gathered the resource's metadata from the from the AWS provider and wrote the metadata to the state file. Later in this collection, you will modify your configuration to reference these values to configure other resources and output values.

»Manually Managing State

Terraform has a built-in command called terraform state for advanced state management. Use the list subcommand to list of the resources in your project's state.

$ terraform state listaws_instance.app_server

»Troubleshooting

If terraform validate was successful and your apply still failed, you may be encountering one of these common errors.

  • If you use a region other than us-west-2, you will also need to change your ami, since AMI IDs are region-specific. Choose an AMI ID specific to your region by following these instructions, and modify main.tf with this ID. Then re-run terraform apply.

  • If you do not have a default VPC in your AWS account in the correct region, navigate to the AWS VPC Dashboard in the web UI, create a new VPC in your region, and associate a subnet and security group to that VPC. Then add the security group ID (vpc_security_group_ids) and subnet ID (subnet_id) arguments to your aws_instance resource, and replace the values with the ones from your new security group and subnet.

     resource "aws_instance" "app_server" {   ami                    = "ami-830c94e3"   instance_type          = "t2.micro"+  vpc_security_group_ids = ["sg-0077..."]+  subnet_id              = "subnet-923a..." }

    Save the changes to main.tf, and re-run terraform apply.

    Remember to add these lines to your configuration for the rest of the tutorials in this collection. For more information, review this document from AWS on working with VPCs.


Launching the Grafana and Prometheus

Create a terraform file on the name of installation.sh and past.

#!/bin/bash
###################### Installing java #################################
sudo apt install software-properties-common apt-transport-https -y
sudo apt install openjdk-8-jdk
sudo export RELEASE="2.2.1"
sudo useradd --no-create-home --shell /bin/false prometheus
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo mkdir /etc/prometheus
sudo mkdir /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus
 cd /opt/
wget https://github.com/prometheus/prometheus/releases/download/v2.26.0/prometheus-2.26.0.linux-amd64.tar.gz
tar -xvf prometheus-2.26.0.linux-amd64.tar.gz
cd prometheus-2.26.0.linux-amd64
sudo cp /opt/prometheus-2.26.0.linux-amd64/prometheus /usr/local/bin/
sudo cp /opt/prometheus-2.26.0.linux-amd64/promtool /usr/local/bin/
sudo chown prometheus:prometheus /usr/local/bin/prometheus
sudo chown prometheus:prometheus /usr/local/bin/promtool
sudo cp -r /opt/prometheus-2.26.0.linux-amd64/consoles /etc/prometheus
sudo cp -r /opt/prometheus-2.26.0.linux-amd64/console_libraries /etc/prometheus
sudo cp -r /opt/prometheus-2.26.0.linux-amd64/prometheus.yml /etc/prometheus
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
sudo chown -R prometheus:prometheus /etc/prometheus/prometheus.yml
prometheus --version
promtool --version
sudo touch /etc/systemd/system/prometheus.service
sudo tee -a /etc/systemd/system/prometheus.service << END
[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file /etc/prometheus/prometheus.yml \
    --storage.tsdb.path /var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries

[Install]
WantedBy=multi-user.target
END
sudo systemctl start prometheus
sudo systemctl enable prometheus
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install grafana -y
sudo systemctl start grafana-server

Create a terraform file on the name of resources.tf  and past.

provider "aws" {
  region     = "${var.region}"
  access_key = "${var.access_key_id}"
  secret_key = "${var.secret_key_id}"
}

data "template_file" "init" {
  template = "${file("installation.sh")}"
}

resource "aws_instance" "test" {
  ami                    = "${var.ami_id}"
  instance_type          = "${var.instance_type}"
  key_name               = "${var.key_name}"
  subnet_id              = "${var.subnet}" 
  user_data              = "${data.template_file.init.rendered}"
  vpc_security_group_ids = ["${var.security_group_id}"]


  tags = {
    Name = "${var.instance_name}"
  }
}

Create a terraform file on the name of var.tfvars  and past.


region              = "ap-south-1"
access_key_id       = "xxxxxxxxxxxxxxxxxxx"
secret_key_id       = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ami_id              = "ami-04a0d9**********"
instance_type       = "t3.small"
subnet              = "subnet-b4*****"
security_group_id   = "sg-041d19xxxxxxx"
instance_name       = "grafana-test"
key_name            = "give the key_pair"

Note: Give the acces id, secret key and instance id on which instance, sub net and give the name for the instance and name of key pair mention for the instance.

Create a terraform file on the name of variables.tf  and past.
variable "region"{}
variable "ami_id"{}
variable "key_name"{}
variable "access_key_id"{}
variable "secret_key_id"{}
variable "instance_type"{}
variable "subnet"{}
variable "security_group_id"{}
variable "instance_name"{}

  • initialize the directory with terraform init.
  • To check the configuration is correct or not useterraform plan command.
  • Apply the configuration now with the terraform apply command. 
  • In this case the plan is acceptable, so type yes at the confirmation prompt to proceed. 
  • Inspect the current state using terraform show.






Comments

Popular posts from this blog

Installing metabase on ec2 linux server as a service file.

Elastic search Kibana