
In this blog we are gonna see about terraform provisoners .So basically there total 3 provisioners in terraform 1. file , 2. Local-exec , 3. Remote-exec but in this blog we are gonna see the file provisoners in detail . So without wasting any time lets see first what is terraform provisoners
Terraform Provisioners
Terraform provisoners are used to performe certain task0s s or action on local or remote machine which can not be handle declaratively by terraform. For example installing some software or provide some configuration.
How to use Provisoners
You can define those provisoners in your resource block, and those provioners can execute only once during resource creation. Also you can provide triggers for your provisoners.
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
}
}
Here i am giving and example of local-exec provisioner but it same declartion for all provisioner, it is just give you an idea that how to use provisoner. The same we can use multiple provisioner within single resource block . as shown below . The order of execution is in the same way we declare them.
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo first"
}
provisioner "local-exec" {
command = "echo second"
}
}
File Provisoner
As the name given file provisoners is used to transfer file/directory fro,m one machine where terraform is working to the newly created machone/resource
So when we talk about copying files or directories from one machine to another machine then it has to be secured and file provisioner supports for ssh
and winrm
type of connections which can help you to achieve secure file transfer between the source machine and destination machine.
Example
Let us take an example to understand how to implement terraform file provisioner. The following code snippet shows –
- How to write your file provisioner
- How to specify
source and
destination` for copying/transferring the file.
provisioner "file" {
source = "/home/knoldus/devops/techhub/keys/aws/test-file.txt"
destination = "/home/ubuntu/test-file.txt"
}
In the above code snippet, we are trying to copy file test-file.txt
from its source =/home/knoldus/devops/techhub/keys/aws/test-file.txt
to its destination =/home/ubuntu/test-file.txt
Here is the complete terraform script which demonstrates on how to use terraform file provisioner
provider "aws" {
region = "eu-central-1"
#version = "~> 3.0"
profile = "sakshi-aws"
}
resource "aws_instance" "ec2_example" {
ami = "ami-0767046d1677be5a0"
instance_type = "t2.micro"
key_name= "aws_key"
vpc_security_group_ids = [aws_security_group.main.id]
provisioner "file" {
source = "/home/knoldus/devops/techhub/keys/aws/test-file.txt"
destination = "/home/ubuntu/test-file.txt"
}
connection {
type = "ssh"
host = self.public_ip
user = "ubuntu"
private_key = file("/home/knoldus/devops/techhub/keys/aws/test-file.txt")
timeout = "4m"
}
}
resource "aws_security_group" "main" {
egress = [
{
cidr_blocks = [ "0.0.0.0/0", ]
description = ""
from_port = 0
ipv6_cidr_blocks = []
prefix_list_ids = []
protocol = "-1"
security_groups = []
self = false
to_port = 0
}
]
ingress = [
{
cidr_blocks = [ "0.0.0.0/0", ]
description = ""
from_port = 22
ipv6_cidr_blocks = []
prefix_list_ids = []
protocol = "tcp"
security_groups = []
self = false
to_port = 22
}
]
}
resource "aws_key_pair" "deployer" {
key_name = "aws_key"
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDbvRN/gvQBhFe+dE8p3Q865T/xTKgjqTjj56p1IIKbq8SDyOybE8ia0rMPcBLAKds+wjePIYpTtRxT9UsUbZJTgF+SGSG2dC6+ohCQpi6F3xM7ryL9fy3BNCT5aPrwbR862jcOIfv7R1xVfH8OS0WZa8DpVy5kTeutsuH5FMAmEgba4KhYLTzIdhM7UKJvNoUMRBaxAqIAThqH9Vt/iR1WpXgazoPw6dyPssa7ye6tUPRipmPTZukfpxcPlsqytXWlXm7R89xAY9OXkdPPVsrQA0XFQnY8aFb9XaZP8cm7EOVRdxMsA1DyWMVZOTjhBwCHfEIGoePAS3jFMqQjGWQd rahul@rahul-HP-ZBook-15-G2"
}
Here is one thing to note – You need to generate the ssh keys to connect to your EC2 instance running in the AWS cloud. You can use the command ssh-keygen -t aws_key
to generate the key-pair. You can read this blog post on Terraform how to do SSH in AWS EC2 instance?
Connection Block
You can create one or more connection block that describe how to access the remote resource. One use case for providing multiple connections is to have an initial provisioner connect as the root
user to set up user accounts and then have subsequent provisioners connect as a user with more limited permissions.
connection {
type = "ssh"
host = self.public_ip
user = "ubuntu"
private_key = file("/home/knoldus/devops/techhub/keys/aws/test-file.txt")
timeout = "4m"
}
Arguments
source
– The source file or directory. Specify it either relative to the current working directory or as an absolute path. This argument cannot be combined withcontent
.content
– The direct content to copy on the destination. If destination is a file, the content will be written on that file. In case of a directory, a file namedtf-file-content
is created inside that directory. We recommend using a file as the destination when usingcontent
. This argument cannot be combined withsource
.destination
– (Required) The destination path to write to on the remote system. See Destination Paths below for more information.
Directory Uploads
Note : When you are uploading directory directly rather than file using ssh connection type, then destinationion dir must be prestnt already . If destinatination directory is not present there then you must use remote-exec provisoner to create destination dir prior to file provisoner.
If you are are using winrm then there is no need to create destination dir, as winrm connection type will create it for you.
Proudly powered by WordPress