Shashikant shah

Monday 27 February 2023

What is a jenkins Part-1

                                                                        Jenkins


1. What is a Jenkins ?

i) Jenkins is a tool that is used for automation, and it is an open-source tool.

ii) Jenkins  allows all the developers to build, test and deploy software.

iii) Jenkins tool written in Java programming language.

iv) Jenkins we can make a continuous integration and continuous delivery (CI/CD) of projects or end-to-endpoint automation.

2. How to install the Jenkins and which tools will be required for Jenkins install.

1. Java
2. Maven
3. Git
4. Sonarqube
5. Aritifcate.
6. Ansible 

Step 1: install java on linux.

1.We will be using open java for our demo, Get the latest version from http://openjdk.java.net/install/

2.yum install java-1.8 java-1.8.0-openjdk-devel

3.Confirm Java Version and set the java home

4.java -version

5.find /usr/lib/jvm/java-1.8* | head -n 3

6.JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-<Java version which seen in the above output>

7.export JAVA_HOME

8.PATH=$PATH:$JAVA_HOME

9.To set it permanently update your .bash_profile

# vi ~/.bash_profile

The output should be something like this,

[root@~]# java -version

openjdk version "1.8.0_151"

OpenJDK Runtime Environment (build 1.8.0_151-b12)

OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

Step 2: Jenkins Repository

# wget -O /etc/yum.repos.d/jenkins.repo   http://jenkins-ci.org/redhat/jenkins.repo

# rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

Step 3: Install Jenkins

# yum install Jenkins

Step 4: Start Jenkins

# /etc/init.d/jenkins start | stop | restart

# chkconfig jenkins on

Step 5: Verify Jenkins

# netstat -ntulp | grep 8080

# vim /etc/sysconfig/Jenkins

Default:

JENKINS_PORT="8080"

New:

JENKINS_PORT="8443"

Step 6: Access the Jenkins Web portal

Access the URL : http://<Ip-Address-of-your-Server>:8080


Admin password is created and stored in the log file  “/var/log/jenkins/jenkins.log“. Run the below command to get the password.

[root@jenkins ~]# grep -A 5 password /var/log/jenkins/jenkins.log

Copy the password and paste it in above windows and click on Continue..

In the next windows Select the option : Install suggested plugins



As we can see required plugin installation is in progress for Jenkins. Once it is done with plugin installation. It will ask to create Admin User


Click on Save and Finish


click on “Start using Jenkins

Jenkins user  login  :-

Go to :- Manage Jenkins à Configure Global Security


Uncheck “Allow users to sign up

User:-admin,  password:-admin

How to Create Jobs for Projects :-

Click “New Item”

Type :- Jobs Name à Freestyle Project à OK

Specify the Project Description

SVN Structure:- 

SVN Repo :- http://192.168.1.21:81/svn/repo_data

Three working  Directory in Repo :-

SVN  :- http://192.168.1.21:81/svn/repo_data/Project_name/{Trunk,Tag,Branch}

Code URL :- http://192.168.1.21:81/svn/repo_data/newsybytes/trunk/<code>newsybytes

# visudo

jenkins  ALL=NOPASSWD:/bin/chown , /bin/chmod , /usr/bin/rsync , /bin/cp

Global Variable Set :-

Manage Jenkins à configure system à Global properties 

Deployment Script :-

# vim /var/lib/Jenkins/test.sh

#!/bin/bash

date1=$(date +%d-%m-%Y-%T)

code_path="$WORKSPACE/$Deployment_name"

revision_no=$(svn info --username admin --password admin $SVN_URL --no-auth-cache | grep "Last Changed Rev:" | cut -d ":" -f2 | cut -d " " -f2)

last_commet=$(svn log -l 1 --username admin --password admin $SVN_URL --no-auth-cache)

echo "################# START BUILD ######################"

        mkfile=$(touch /tmp/revision_$Deployment_name)

        Rev_number=$(cat /tmp/revision_$Deployment_name)

        old_rev_no=$(echo "$Rev_number")

if [[ "$old_rev_no" == "$revision_no" ]];then

        echo -e "LAST SVN REVISION NO:- $revision_no\n"

        echo "LAST COMMIT :-"

        echo -e "$last_commet\n"

        echo -e "NO ANY UPDATE....!\n"

else

  delete_svn=$(find $code_path -name ".svn" -type d -exec rm -rf "{}" \; 2> /dev/null)

rc=$(sudo rsync -a --delete $code_path/$Deployment_name/ /var/www/html/$Deployment_name/)

        per=$(sudo chmod -R 777 /var/www/html/$Deployment_name)

        own=$(sudo chown -R root:root /var/www/html/$Deployment_name)

        echo "LAST COMMIT :-"

        echo -e "$last_commet\n"

        echo -e "PERVIOUS SVN REVISION NO:- $old_rev_no\n"

        echo -e "CURRENT SVN REVISION NO:- $revision_no\n"

        echo -e "DEPLOYMENT IS COMPLETED..\n"

        svn_no=$(echo "$revision_no" > /tmp/revision_$Deployment_name)

fi

echo "################# COMPLETED BUILD #####################"

#chmod  -R 777 /var/lib/Jenkins/test.sh

Mailing  Configuration:-

Manage Jenkins à configure System à Extended E-mail Notification


Manage Jenkins à configure System à E-mail Notification

Post-build Actions

Triggers à add Trigger à Always

Add à  Recipient List,    Developers


Apply à Save

Need to multiple parameter

plugin name :- active choices


1.General à select This project is parameterized àActive Choices Parameter

Name:- Env

Select :- Groovy script

return[

'',

'Production',

'Development',

'Test',

'Stage'

]

Fallback Script

Groovy Script ->

return['error']

Description->

Please select an Environment

Choice Type -> Single Select

Filter starts at -> 1

Add à Active Choices Reactive Parameter

Name -> Servers

Select Groovy Script à

if (Env.equals("Production")) {

return ["Prod01", "Prod02", "Prod03", "Prod04"]

} else if (Env.equals("Development")) {

return ["Dev01", "Dev02", "Dev03"]

} else if (Env.equals("Test")) {

return ["test01", "test02"]

} else {

return ["Unknown state"]

}

Fallback Script

Groovy Script ->

return ['script Error']

Choice Type -> Single Select

Referenced parameters -> Env

Filter starts at -> 1

Build :-

echo "$Env"

echo "$Servers"




Saturday 25 February 2023

What is a terraform .

 What is a terraform ?



1.terraform is an open-source software tools created by HashiCorp in 2014.

2.Tool used to build, manage and version infrastructure as code.

2.uses HCL to declare desired state.

2.It is developed by Mitchell Hashimoto developer.

3.Terraform is written in GO language.

4.It supports declarative configuration language know as HashiCorp configuration language (HCL).

With the help of terraform we can codify our infrastructure

Infrastructure means our component like EC2, RT, IGW, LB, Autoscaling etc.



Install terraform.

# mkdir /opt/terraform

# yum install wget zip

# wget https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_linux_amd64.zip

# unzip terraform_0.14.5_linux_amd64.zip

# mv terraform /usr/bin

# terraform -v

Terraform v0.14.5


Create user in IAM AWS.

1.User name :- terraform à select programmatic access

2.select à attach existing policies directly à AdministratorAccess.



Next à create user.


Download key.

# aws configure

# AWS Access Key ID [None]: AKIAWOZL57VN52ILHW22

# AWS Secret Access Key [None]: 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

# Default region name [None]: ap-south-1

# Default output format [None]:


# terraform help

Usage: terraform [global options] <subcommand> [args]

Main commands:

  init               Prepare your working directory for other commands.

  validate      Check whether the configuration is valid.

  plan             Show changes required by the current configuration.

  apply           Create or update infrastructure.

  destroy       Destroy previously-created infrastructure.

 

All other commands:

  console       Try Terraform expressions at an interactive command prompt.

  fmt           Reformat your configuration in the standard style.

  force-unlock  Release a stuck lock on the current workspace.

  get           Install or upgrade remote Terraform modules.

  graph         Generate a Graphviz graph of the steps in an operation.

  import        Associate existing infrastructure with a Terraform resource.

  login         Obtain and save credentials for a remote host.

  logout        Remove locally-stored credentials for a remote host.

  output        Show output values from your root module.

  providers     Show the providers required for this configuration.

  refresh       Update the state to match remote systems.

  show          Show the current state or a saved plan.

  state         Advanced state management.

  taint         Mark a resource instance as not fully functional.

  untaint       Remove the 'tainted' state from a resource instance.

  version       Show the current Terraform version.

  workspace     Workspace management.

 

Global options (use these before the subcommand, if any):

  -chdir=DIR    Switch to a different working directory before executing the

                given subcommand.

  -help         Show this help output, or the help for a specified subcommand.

  -version      An alias for the "version" subcommand.

 

terraform apply   

applies state

terraform destroy

destroys all terraform managed state (use with caution)

terraform fmt

Rewrite terraform configuration files to a canonical format and style

terraform get

Download and update modules

terraform graph

Create a visual representation of a configuration or execution plan

terraform [options] ADDRESS ID

Import will try and find the infrastructure resource identified with ID and import the state into terraform.tfstate with resource id ADDRESS

terraform output [options] [NAME]

Output any of your resources. Using NAME will output a specific resource

terraform plan

terraform plan, show the changes to be made to the infrastructure

terraform push

Push changes to Atlas, enterprise tool that can automatically run terraform from a centralized server

terraform refresh

Refresh the remote state. Can identify differences between state file and remote state

terraform remote

Configure remote state storage

terraform show

Show human readable output from a state or a plan

terraform state

Use this command for advanced state management e.g. Rename a resource with terraform state mv aws_instance.example aws_instance.production

terraform taint

Manually mark a resource as tainted, meaning it will be destructed and recreated

at the next apply.

terraform validate

validate your terraform syntax

terraform untaint

Undo a taint


Comments  line in terraform :-

/*

Line1

Line2

*/

#mkdir terraform

# cat main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region = "ap-south-1"

}

resource "aws_instance" "base" {

 ami = "ami-04b1ddd35fd71475a"

 instance_type = "t2.micro"

}


1.Install plugin like aws.

# terraform init


# ls -la


2.Dry mode command use for check changes and which resources will creating.

# terraform plan

# terraform plan -help

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












3. apply command use for create resources then automatic create one more terraform.tfstate.

# terraform apply

# terraform apply -help

# terraform apply -target=aws_instance.base (single resource target) 

All instance details save in terraform.tfstate file.

# cat terraform.tfstate

"monitoring": false,

            "network_interface": [],

            "outpost_arn": "",

            "password_data": "",

            "placement_group": "",

            "primary_network_interface_id": "eni-0472b8f7436e30719",

            "private_dns": "ip-172-31-39-218.ap-south-1.compute.internal",

            "private_ip": "172.31.39.218",

            "public_dns": "ec2-15-206-172-204.ap-south-1.compute.amazonaws.com",

            "public_ip": "15.206.172.204",


4. destroy command for delete resources and read state file like terraform.tfstate.

# terraform destroy

# terraform destroy -help

# terraform destroy -target=aws_instance.base  (Destroying Specific Resource)

OR

/*

s3 resource name

*/

# terraform destroy (s3 bucket delete)

i)terraform.tfstate

ii) terraform.tfstate.backup

5.validate command for check syntax in template.

# terraform  validate

6.fmt command use for arrange format.

# terraform  fmt main.tf

# terraform fmt -help


# terraform  fmt main.tf


7.providers command use for show providers plugin used.

# terraform providers

Providers required by configuration:

.

└── provider[registry.terraform.io/hashicorp/aws]

8.show command use for essay to read files.

# terraform show

# terraform show terraform.tfstate.backup


Set the environment

All template create in Defaut

Create a terraform.tfstate.d

1.list command.

# terraform  workspace list

* default

2.create a env.

How to create environments DEV, UAT, PROD.

# terraform   workspace  new  dev

# terraform   workspace  new  uat

# terraform   workspace  new  prod

# terraform workspace list


3.show command for currently which workspace are work.

# terraform workspace show


4.select command for change workspace.

# terraform workspace select dev


5.created one directory terraform.tfstate.d and three directory dev,prod,uat in  terraform.tfstate.d.

# tree terraform.tfstate.d

6. running main.tf and all state file save in dev directory.

# terraform apply

Do you want to perform these actions in workspace "dev"?

# ls -l terraform.tfstate.d/dev/


7.taint, untaint command use for particular resource recreate/changes/any correction. 


# terraform taint aws_instance.base

# terraform untaint aws_instance.base

Show to taint status

# terraform show


# terraform plan


Note :- instance rename then apply command.

apply ke badh taint remove ho jata hai.

Delete hoga fir se create karega.

# terraform apply

1.Terraform State File

1.terraform stores the state of the infrastructure that is being created from the TF files.

2.This state allow terraform to map real world resource to your existing configuration.

if manual change a ec2 instance through aws portal.

# terraform plan (one change show hoga.)

# terraform apply  {fir se t2.micro set kar dega.}


2.What is Desired state and Current state.

i)desired state à Main.tf   (what resource are launch)

ii)current state à terraform.tfstate (what resource are running in aws )

Plan command matching files

desired state == current state

refresh command use for fetch current status from aws portal and update in terraform.tfstate file.

Note :- ec2-instance stop manual and how to terraform fetch status from aws. 

To refresh the current state

# terraform refresh

# vim /terraform.tfstate.d/dev/terraform.tfstate

# terraform show


3.terrafrom provider versioning.



#example :-



4.Types of terraform providers.

i) hashiCorp Distributed :- init command use install plugin automatic.

ii) 3rd Party :- manual download plugin and install.



5.Attributes and Output Values:-

i)Many attributes for ec2-instance and other resources.

# terraform apply 


ii) aws_instance.my_machine (show all attributes) 

# terraform apply


6.Referening Cross-account resource attributes.

Example 1:-  EIP and EC2 instance.


2.Example :-

Create a security group and add Elastic IP(other security group)


7.Terraform Variables :-

Repeated static value can create more work in the future.

Create one vpc and security group and set IP variables in security group.

1.create variable file.

# vim variables.tf


2.create main.tf file


Approaches to variable Assignment.


1.Defaults variable.

# cat variables.tf

variable " instancetype" {

  default = "t2.micro"

}

# terraform plan

2.command line Flags.

# terraform plan -var="instancetype=t2.small"

# terraform plan

Note :-  Not define default variable then ask to variable name.

# cat variables.tf

variable "instancetype" {}

# terraform plan


3.From a File (first variable read to terraform.tfvars file after that default variable read).

Example - 01

# cat variables.tf

variable " instancetype" {

  default = "t2.micro"

}

# vim terraform.tfvars

instancetype="t2.large"

# terraform plan


Example – 02

# vim  custom.tfvars

instancetype="t2.large"

# terraform plan -var-file=custom.tfvars


4. Environment variable.

# export TF_VAR_instancetype="t2.nano"

 

Data type of variables :-



# cat main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

resource "aws_elb" "test_lb" {

  name              = var.elb_name

  availability_zones = var.az

  listener {

    instance_port     = 8000

    instance_protocol = "http"

    lb_port           = 80

    lb_protocol       = "http"

  }

  health_check {

    healthy_threshold   = 2

    unhealthy_threshold = 2

    timeout             = 3

    target              = "HTTP:8000/"

    interval            = 30

  }

  cross_zone_load_balancing   = true

  idle_timeout                = 400

  connection_draining         = true

  connection_draining_timeout = 400

  tags = {

    Name = "test_terraform_elb"

  }

}

#cat vaiables.tf

variable "elb_name" {

  type = string

}

variable "az" {

  type = list

}

variable "timeout" {

  type = number

}

# cat terraform.tfvars

elb_name = "myelb"

timeout  = "400"

az       = ["us-west-1a", "us-west-1b"]

# terraform  plan


Fetching data from Maps and List in Variable.

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

resource "aws_instance" "myec2" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = var.types["ap-south-1"]

 

  tags = {

    Name = "dev server1"

  }

}

variable "types" {

  type = map

  default = {

    us-east-1  = "t2.micro"

    us-west-2  = "t2.nano"

    ap-south-1 = "t2.small"

  }

}

# terraform validate

# terraform plan

List use

# cat main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

resource "aws_instance" "myec2" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = var.list["0"]

 

  tags = {

    Name = "dev server1"

  }

}

variable "list" {

  type    = list

  default = ["m5.large", "m5.xlarge", "t2.medium"]

}

}



Count Parameter.

With count parameter, we can simply specify the count value and the resource can be scaled accordingly.

Example 01 :-

3 instance is create .

Count Index

In resource blocks where count is set, an additional count object is available in expression, so you can modify the configuration of each instance.

This object has one attribute:

count.index – The distinct index number (starting with 0) corresponding to this instance.

Understanding Challenge with Count.

With the below code, terraform will create 3 instances. But the problem is that all will have the same name.

count.index allows us to fetch the index of each iteration in the loop.

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  count         = 3

  tags = {

    Name = "dev server_${count.index}"

  }

}

Output Instance name numbering like :-

dev server_0

dev server_1

dev server_2

multiple name add in instances.

Output like :-

          + "Name" = "dev-server"

          + "Name" = "stage-server"   

          + "Name" = "prod-server"


Conditional Expression.

1.Value is true then 3 dev instance is create.

2.value is false then 1 prod instance is create.  

count = var.istest == true ? 3 : 0

##################

# vim main.tf


# vim terraform.tfvars

istest = false


3.value is true then 3 instance create if not true then 1 instance create.

count = var.istest == true ? 3 : 1


Local Values :-



# vim main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

 

 

locals {

  common_tags = {

    Name    = "server1"

    Owner   = "DevOps team"

    service = "backend"

  }

}

resource "aws_instance" "db-dev" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  tags          = local.common_tags

}

resource "aws_ebs_volume" "db-ebs" {

  availability_zone = "ap-south-1a"

  size              = 8

  tags              = local.common_tags

}

# terraform apply 





Terraform Functions :-

1.The terraform language include a number of built-in functions that you can use to transform and combine values.

2.The general syntax for function calls is a function  name followed by comma-separated arguments in parentheses.

# function (argument1, argument2)

Example:

max (5, 12, 9) 

12



# ssh-keygen -t rsa

]# cat main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = var.region

}

locals {

  time = formatdate("DD MMM YYYY hh:mm ZZZ", timestamp())

}

variable "region" {

  default = "ap-south-1"

}

variable "tags" {

  type    = list

  default = ["firstec2", "secondec2"]

}

variable "ami" {

  type = map

  default = {

    "ap-south-1" = "ami-04b1ddd35fd71475a"

    "us-east-1"  = "ami-01b3d4d785f71475n"

  }

}

resource "aws_key_pair" "loginkey" {

  key_name   = "login-key"

  public_key = file("${path.module}/id_rsa.pub")

}

 

resource "aws_instance" "app-dev" {

  ami           = lookup(var.ami, var.region)

  instance_type = "t2.micro"

  key_name      = aws_key_pair.loginkey.key_name

  count         = 2

  tags = {

    Name = element(var.tags, count.index)

  }

}

Data Sources: -





Region according fetch image.

Amazon image:-

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

data "aws_ami" "app_ami" {

  most_recent = true

  owners      = ["amazon"]

  filter {

    name   = "name"

    values = ["amzn2-ami-hvm*"]

  }

  filter {

    name   = "virtualization-type"

    values = ["hvm"]

  }

}

resource "aws_instance" "instance-1" {

  ami           = data.aws_ami.app_ami.id

  instance_type = "t2.micro"

  key_name = "new-keypair-aws"

 

  tags = {

    Name = "dev server1"

  }

}


Ubuntu image:-

data "aws_ami" "app_ami" {

  most_recent = true

  owners      = ["099720109477"]

 

  filter {

    name   = "name"

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

  }

  filter {

    name   = "virtualization-type"

    values = ["hvm"]

  }

}

# image details

# aws ec2 describe-images --region ap-south-1 --image-ids ami-042b34111b1289ccd

Debugging in Terraform :-




# export TF_LOG=TRACE

# export TF_LOG_PATH=/tmp/terraform-crash.log

# terraform plan

Terraform Format  check:-


Validating Terraform configuration files.


Load Order & Semantics:

# ec2.tf,  iam_user.tf,  provider.tf,  variable.tf

 

# cat provider.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

 

# cat variable.tf

variable "iam_user" {

  default = "demouser"

}

 

# cat ec2.tf

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  tags = {

    Name = "dev server1"

  }

}

 

# cat iam_user.tf

resource "aws_iam_user" "userdemo" {

  name = var.iam_user

  path = "/system/"

}

# terraform fmt

# terraform validate

# terraform plan

# terraform apply


Dynamic Block



# file dynamic-block.tf    , provider.tf

# cat dynamic-block.tf

variable "sg_ports" {

  type        = list(number)

  description = "list of ingress ports"

  default     = [8200, 8201, 8300, 9200, 9500]

}

resource "aws_security_group" "dynamicsg" {

  name        = "dynamic-sg"

  description = "Ingress for vault"

  dynamic "ingress" {

    for_each = var.sg_ports

    content {

      from_port   = ingress.value

      to_port     = ingress.value

      protocol    = "tcp"

      cidr_blocks = ["0.0.0.0/0"]

    }

  }

ingress {

  from_port   = 9090

  to_port     = 9090

  protocol    = "tcp"

  cidr_blocks = ["192.168.1.0/0"]

}

}

# terraform plan

 


Terraform taint



Eg :- terraform taint <resource>.<name>

# terraform taint aws_instance.myec2


Splat expression

Example01

Output showing all user.


Example02:-

Showing one user.

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

Outputs:

arns = "arn:aws:iam::444084387163:user/system/iam_user.0"

Terraform Graph :-


# terraform graph > graph.dot

# cat graph.dot | dot -Tsvg > graph.svg

# yum install nginx

# service nginx start

# cp -rvf graph.svg  /usr/share/nginx/

Saving terraform plan to file.



Change in terraform file

# terraform  plan  -out=demopath

# terraform apply demopath

#

resource "aws_iam_user" "userdemo" {

  name  = "iam_user.${count.index}"

  count = 3

  path  = "/system/"

}

output "arns" {

  value = aws_iam_user.userdemo[*].arn

 

# terraform apply

 

How to fetch data.

# terraform output arns

[

  "arn:aws:iam::444084387163:user/system/iam_user.0",

  "arn:aws:iam::444084387163:user/system/iam_user.1",

  "arn:aws:iam::444084387163:user/system/iam_user.2",

]

 

Terraform setting.

The special terraform configuration block type is used to configure some behaviors of terraform itself, such as requiring a minimum terraform version to apply your configuration.

# terraform -v

Terraform v0.14.5

+ provider registry.terraform.io/hashicorp/aws v3.26.0

# require for terraform version and aws version then run int command.

terraform {

 required_version = "0.14.5"

 required_providers {

      aws = "3.26"

}

}

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

# terraform init

Dealing with larger Infrastructure:




Slow Down:

We can prevent terraform from querying the current state during operations like terraform plan.

This can be achieved with the -refresh=false  flag

# terraform  apply -auto-approve 

Refresh to all resource like ec2, iam , vpc. 

# terraform plan

aws_iam_user.userdemo[1]: Refreshing state... [id=iam_user.1]

aws_iam_user.userdemo[2]: Refreshing state... [id=iam_user.2]

aws_iam_user.userdemo[0]: Refreshing state... [id=iam_user.0]

How to disable refresh option :-

# terraform plan  -refresh=false     

 

Specify the Target:

If any specific resource changes in terraform file.

Like :- port change , Ips , instance name

The -target=resource flag can be used to target a specific resource.

Generally used as a means to operate on isolated portions of very large configurations.

# terraform plan -target=<resource>.<name> 

# terraform plan -refresh=false   -target=aws_security_group.allow_ssh_conn

Provisioners :


Create ec2 instance and install nginx service.

 

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  key_name      = "new-keypair-aws"

 

  tags = {

    Name = "dev server1"

  }

provisioner "remote-exec" {

inline = [

 "sudo amazon-linux-extras install -y nginx1.12",

 "sudo systemctl start nginx"

]

connection {

type = "ssh"

host = self.public_ip

user = "ec2-user"

private_key = "${file("./terraform.pem")}"

}

}

}









Failure Behavior for Provisioners.

 

Dry Principle :-

Create directory  like ec2, elb , ebs , cdn and put resource and pick resource from directory.

# mkdir -p   modules/ec2

# mkdir -p   project

 

# vim modules/ec2/main.tf

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  security_groups = ["default"]

  key_name = "new-keypair-aws"

 

  tags = {

    Name = "dev server1"

  }

}

 

# vim project/provider.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

 

 

# cat project/ec2_web_dry.tf

module "myec2" {

  source = "../modules/ec2"

}

# cd project

# terraform init

# terraform plan


Variable and terraform Modules 

# mkdir -p   modules/ec2

# mkdir -p   project

 

# vim modules/ec2/main.tf

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = var.instance_type

  security_groups = ["default"]

  key_name = "new-keypair-aws"

  tags = {

    Name = "dev server1"

  }

}

# vim modules/ec2/variables.tf

variable  “instance_type”  {

default = “t2.micro”  (second variable)

}

# vim project/provider.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

# cat project/ec2_web_dry.tf

module "myec2" {

  source = "../modules/ec2"

  instance_type = “t2.large”   (first variable)

}

# cd project

# terraform init

# terraform plan

Output showing :-

instance_type =  t2.large

Terraform Registry

The Terraform Registry is a repository of modules written by the Terraform community.

The registry can help you get started with Terraform more quickly


3.1 Module Location

If we intend to use a module, we need to define the path where the module files are present.

The module files can be stored in multiple locations, some of these include:

        Local Path

        GitHub

        Terraform Registry

        S3 Bucket

        HTTP URLs

 

3.2 Verified Modules in Terraform Registry

Within Terraform Registry, you can find verified modules that are maintained by various third-party vendors.

These modules are available for various resources like AWS VPC, RDS, ELB, and others

Using Registry Modules in Terraform

To use Terraform Registry module within the code, we can make use of the source argument that contains the module path.

Below code references to the EC2 Instance module within terraform registry.

module "ec2-instance" {

  source  = "terraform-aws-modules/ec2-instance/aws"

  version = "2.13.0" (code comment version)

  # insert the 10 required variables here

}

# ls main.tf  provider.tf

# cat main.tf 

module "ec2_cluster" {

  source  = "terraform-aws-modules/ec2-instance/aws"

  version = "~>2.0"

  name           = "my-ec2"

  instance_count = 1

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = "t2.micro"

  subnet_id     = "subnet-69d49425"

  tags = {

    Terraform   = "true"

    Environment = "dev"

  }

}

# ls .terraform/modules/ec2_cluster/

CHANGELOG.md  examples  LICENSE  main.tf  Makefile  outputs.tf  README.md  variables.tf  versions.tf

# terraform plan

# terraform apply


Terraform Workspace

Terraform allows us to have multiple workspaces, with each of the workspaces we can have a different set of environment variables associated.

1.Terraform starts with a single workspace named "default".

 

2.Workspaces are managed with the terraform workspace set of commands.

 

3.To create a new workspace and switch to it, you can use terraform workspace new; to switch workspaces you can use terraform workspace select; etc.

 

Environment according variable set.

 

# terraform workspace -h

 

# terraform workspace list

* default

 

# terraform workspace new prd

# terraform workspace new dev

# terraform workspace list

  default

  dev

* prd

 

# terraform workspace select default

# terraform plan

 

# cat main.tf

provider "aws" {

  access_key = "AKIAWOZL57VN52ILHW22"

  secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  region     = "ap-south-1"

}

 

resource "aws_instance" "base" {

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = lookup(var.instance_type,terraform.workspace)

 

}

variable "instance_type" {

  type = map(string)

 

  default = {

    default = "t2.nano"

    dev     = "t2.micro"

    prd     = "t2.large"

  }

 

}

Default workspace showing :-

+ instance_type                = "t2.nano"

# ls terraform.tfstate

Dev workspace showing :-

# terraform workspace select dev

+ instance_type                = "t2.micro"

# ls terraform.tfstate.d/dev/terraform.tfstate

Prd workspace showing :-

# terraform workspace select prd

+ instance_type                = "t2.large"

# ls terraform.tfstate.d/prd/terraform.tfstate

Integrating with GIT for team management.

Module Source in terraform

1.Local path :-

 

module “local_dir” {

source = “../local_dir”

} 

2.Git module source:-

 module “vpc” {

source = “git::https://example.com/vpc.git”

}

module “storage” {

source = “git::ssh://username@example.com/storage.git”

}

module “branch_git” {

source = “git::ssh://username@example.com/storage.git?ref=<branch-name/revesion no>”

}

3.Terraform Registry.

module "consul" {

  source = "hashicorp/consul/aws"

  version = "0.1.0"

} 

4.Bitbucket.

module "consul" {

  source = "bitbucket.org/hashicorp/terraform-consul-aws"

}

5.Fetching archives over HTTP.

module "vpc" {

  source = "https://example.com/vpc-module.zip"

} 

6.S3 Bucket.

module "consul" {

  source = "s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/vpc.zip"

}

7.GCS Bucket

module "consul" {

  source = "gcs::https://www.googleapis.com/storage/v1/modules/foomodule.zip"

}

# terraform init

# ls .terraform/modules/consul

Terraform and .gitignore

# vim  .gitignore

.terraform

*.tfvars

Terraform.tfstate

# git status

# git add .gitignore

# git commit -a “add gitignore file”

# git push origin master

 

Remote State management with Terraform.






# ls

backend.tf  main.tf

# cat backend.tf

terraform {

  backend "s3" {

    bucket = "terraform-backend-s3-testing"

    key    = "remotedemo.tfstate"

    region = "ap-south-1"

    access_key = "AKIAWOZL57VN52ILHW22"

    secret_key = "oUlIWDNuFhZ5DD/LdHf/q3dggPCVK9cjy2w7NX4U"

  }

}

# terraform init

# terraform plan

# terraform apply

 


State file locking




Create DynamoDB for terraform lock file save. 



# terraform init

# terraform plan

terraform.lock.hcl save in dynamodb


Terraform state Management

 

1.How many resources are running.

# terraform state list

2. This command is used in many case in which you want to rename an existing resource without destroying and recreating it.

Old resource name :- base

Rename resource name :- base01

# terraform state mv [option]  SORUCE  DESTINATION

resource "aws_instance" "base01"ß change resource name

  ami           = "ami-04b1ddd35fd71475a"

  instance_type = lookup(var.instance_type, terraform.workspace)

  tags = {

    Name = "dev-test02"

  }

# terraform plan

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

# terraform state list

aws_instance.base

# terraform state mv aws_instance.base  aws_instance.base01

Move "aws_instance.base" to "aws_instance.base01"

Successfully moved 1 object(s).

# terraform plan

No changes. Infrastructure is up-to-date.

3.pull command use download terraform state “remotedemo.tfstate” from s3 bucket and show output.

# terraform state pull

4.The terraform state push command is used to manually upload a local state file to remote state.

5.rm command is used to remove items from the terraform state “remotedemo.tfstate”  file but resource running in aws.

# terraform state list

aws_instance.base

# terraform state rm  aws_instance.base

# terraform state pull

6.show command use for show the attributes of a single resource  in the Terraform state.

# terraform state show aws_instance.base


Importing Existing resources with terraform Import.

# vim ec2.tf

# terraform import  aws_instance.myec2  i-041732765374fbd98

# check terraform state file.

Terraform provider use case Resources in multiple Regions 




By default, resources use a default provider configuration inferred from the first word of the resource type name.

For example, a resource of type aws_instance uses the default (un-aliased) aws provider configuration unless otherwise stated.

To select an aliased provider for a resource or data source, set its provider meta-argument to a <PROVIDER NAME>.<ALIAS> reference:

# vim providers.tf

# vim main.tf


Handling  multiple aws account

 

# aws   s3   ls    --profile   account02

# cat provider.tf

# cat eip.tf

Terraform & Assume role with AWS STS

Sensitive parameter