{"id":11114,"date":"2023-09-18T08:05:25","date_gmt":"2023-09-18T08:05:25","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=11114"},"modified":"2023-09-20T02:51:28","modified_gmt":"2023-09-20T02:51:28","slug":"terraform-provisioners-tutorials-and-complete-guide","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/terraform-provisioners-tutorials-and-complete-guide\/","title":{"rendered":"Terraform provisioners Tutorials and Complete Guide"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"515\" src=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2023\/09\/image-454-1024x515.png\" alt=\"\" class=\"wp-image-39909\" srcset=\"https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2023\/09\/image-454-1024x515.png 1024w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2023\/09\/image-454-300x151.png 300w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2023\/09\/image-454-768x386.png 768w, https:\/\/www.devopsschool.com\/blog\/wp-content\/uploads\/2023\/09\/image-454.png 1093w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Terraform provisioners are used to execute scripts or shell commands on a local or remote machine as part of resource creation\/deletion. They are similar to \u201cEC2 instance user data\u201d scripts that only run once on the creation and if it fails terraform marks it tainted.<\/p>\n\n\n\n<p>Terraform includes a number of built-in provisioners, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>file:<\/strong>&nbsp;Copies files or directories from the machine running Terraform to the newly created resource.<\/li>\n\n\n\n<li><strong>remote-exec:<\/strong>&nbsp;Executes a command on the newly created resource.<\/li>\n\n\n\n<li><strong>local-exec:<\/strong>&nbsp;Executes a command on the machine running Terraform.<\/li>\n<\/ul>\n\n\n\n<p>Provisioners can also be used to implement custom logic, such as:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Installing and configuring software<\/li>\n\n\n\n<li>Creating and configuring user accounts<\/li>\n\n\n\n<li>Starting and stopping services<\/li>\n\n\n\n<li>Performing health checks<\/li>\n<\/ul>\n\n\n\n<p>Provisioners should be used as a last resort. There are better alternatives for most situations, such as using Terraform modules or a configuration management tool like Ansible or Chef. However, provisioners can be useful for certain tasks, such as configuring resources that are not supported by Terraform modules or for integrating Terraform with other tools.\\<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">resource <span class=\"hljs-string\">\"aws_instance\"<\/span> <span class=\"hljs-string\">\"web\"<\/span> {\n  ami           = <span class=\"hljs-string\">\"ami-053b0d53c279acc90\"<\/span>\n  instance_type = <span class=\"hljs-string\">\"t3.micro\"<\/span>\n  key_name \t\t= <span class=\"hljs-string\">\"aws-hl-training\"<\/span>\n\n  tags = {\n    Name = <span class=\"hljs-string\">\"HelloWorld-rajesh\"<\/span>\n  }\n  \n  connection {\n      type     = <span class=\"hljs-string\">\"ssh\"<\/span>\n      user     = <span class=\"hljs-string\">\"ubuntu\"<\/span>\n      private_key = file(<span class=\"hljs-string\">\"aws-hl-training.pem\"<\/span>)\n      <span class=\"hljs-comment\">#host = aws_instance.web.public_ip<\/span>\n      host = <span class=\"hljs-keyword\">self<\/span>.public_ip\n  } \n  \n  provisioner <span class=\"hljs-string\">\"local-exec\"<\/span> {\n    command = <span class=\"hljs-string\">\"mkdir devopsschool-local\"<\/span>\n  }\n  \n provisioner <span class=\"hljs-string\">\"remote-exec\"<\/span> {\n    inline = &#91;\n\t  <span class=\"hljs-string\">\"sudo apt-get update\"<\/span>,\n      <span class=\"hljs-string\">\"sudo apt-get install apache2 -y\"<\/span>,\n\t  <span class=\"hljs-string\">\"sudo systemctl start apache2\"<\/span>,\n    ]\n  }\n  \n  provisioner <span class=\"hljs-string\">\"file\"<\/span> {\n    source      = <span class=\"hljs-string\">\"terraform.tfstate.backup\"<\/span>\n    destination = <span class=\"hljs-string\">\"\/tmp\/\"<\/span>\n  } \n  \n  \n}\n\noutput <span class=\"hljs-string\">\"instance_public_ip\"<\/span> {\n  value = aws_instance.web.public_ip\n}\n\noutput <span class=\"hljs-string\">\"instance_public_sg\"<\/span> {\n  value = aws_instance.web.security_groups\n}\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">List of connection types in Terraform remote-exec provisioner?<\/h2>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>SSH (Secure Shell)<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Type<\/strong>: <code>\"ssh\"<\/code><\/li>\n\n\n\n<li><strong>Description<\/strong>: Used for connecting to Unix-based operating systems, including Linux and macOS.<\/li>\n\n\n\n<li><strong>Commonly Used With<\/strong>: Linux and Unix-based cloud instances.<\/li>\n\n\n\n<li><strong>Example<\/strong>:<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">connection {\r\n  type        = <span class=\"hljs-string\">\"ssh\"<\/span>\r\n  user        = <span class=\"hljs-string\">\"your_username\"<\/span>\r\n  private_key = file(<span class=\"hljs-string\">\"~\/.ssh\/your_private_key.pem\"<\/span>)\r\n  host        = aws_instance.example.public_ip\r\n}\r\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>WinRM (Windows Remote Management)<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Type<\/strong>: <code>\"winrm\"<\/code><\/li>\n\n\n\n<li><strong>Description<\/strong>: Used for connecting to Windows-based operating systems.<\/li>\n\n\n\n<li><strong>Commonly Used With<\/strong>: Windows cloud instances.<\/li>\n\n\n\n<li><strong>Example<\/strong>:<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">connection {\r\n  type     = <span class=\"hljs-string\">\"winrm\"<\/span>\r\n  host     = aws_instance.example.private_ip\r\n  user     = <span class=\"hljs-string\">\"Administrator\"<\/span>\r\n  password = <span class=\"hljs-string\">\"your_password\"<\/span>\r\n}\r\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>To establish a WinRM connection over HTTPS with SSL and ignore certificate validation, you can modify the connection block as follows:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">connection {\r\n  type        = <span class=\"hljs-string\">\"winrm\"<\/span>\r\n  host        = aws_instance.example.private_ip\r\n  user        = <span class=\"hljs-string\">\"Administrator\"<\/span>\r\n  password    = <span class=\"hljs-string\">\"your_password\"<\/span>\r\n  https       = <span class=\"hljs-keyword\">true<\/span>  <span class=\"hljs-comment\"># Enable HTTPS<\/span>\r\n  insecure    = <span class=\"hljs-keyword\">true<\/span>  <span class=\"hljs-comment\"># Ignore SSL certificate validation (for testing purposes, not recommended in production)<\/span>\r\n  port        = <span class=\"hljs-number\">5986<\/span>  <span class=\"hljs-comment\"># Use the default HTTPS port for WinRM<\/span>\r\n  cacert      = <span class=\"hljs-string\">\"\/path\/to\/ca.crt\"<\/span>  <span class=\"hljs-comment\"># Optional path to a CA certificate file (if required)<\/span>\r\n  cert        = <span class=\"hljs-string\">\"\/path\/to\/client.crt\"<\/span>  <span class=\"hljs-comment\"># Optional path to a client certificate file (if required)<\/span>\r\n  key         = <span class=\"hljs-string\">\"\/path\/to\/client.key\"<\/span>  <span class=\"hljs-comment\"># Optional path to the client certificate's private key file (if required)<\/span>\r\n  timeout     = <span class=\"hljs-string\">\"5m\"<\/span>  <span class=\"hljs-comment\"># Set a timeout for the WinRM connection<\/span>\r\n  max_retries = <span class=\"hljs-number\">3<\/span>     <span class=\"hljs-comment\"># Maximum number of connection retries<\/span>\r\n}\r\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>Explanation of the options:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>https<\/code>: Set to <code>true<\/code> to enable HTTPS for the WinRM connection.<\/li>\n\n\n\n<li><code>insecure<\/code>: Set to <code>true<\/code> to ignore SSL certificate validation. This option is typically used for testing and debugging but is not recommended for production due to security concerns.<\/li>\n\n\n\n<li><code>port<\/code>: Use <code>5986<\/code> as the default port for HTTPS WinRM connections.<\/li>\n\n\n\n<li><code>cacert<\/code>: Optional path to a CA certificate file. Use this if your WinRM server&#8217;s certificate is signed by a custom CA.<\/li>\n\n\n\n<li><code>cert<\/code>: Optional path to a client certificate file. Use this if client certificate authentication is required.<\/li>\n\n\n\n<li><code>key<\/code>: Optional path to the private key file corresponding to the client certificate.<\/li>\n\n\n\n<li><code>timeout<\/code>: Set a timeout for the WinRM connection (e.g., <code>\"5m\"<\/code> for 5 minutes).<\/li>\n\n\n\n<li><code>max_retries<\/code>: Maximum number of connection retries in case of failures.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-devopsschool-com wp-block-embed-devopsschool-com\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"xa8euDvcgZ\"><a href=\"https:\/\/www.devopsschool.com\/blog\/how-to-run-provisioners-code-after-resources-is-created-in-terraform\/\">Terraform: run code after resources is created using using remote-exec provisioners<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Terraform: run code after resources is created using using remote-exec provisioners&#8221; &#8212; \" src=\"https:\/\/www.devopsschool.com\/blog\/how-to-run-provisioners-code-after-resources-is-created-in-terraform\/embed\/#?secret=7fbKIH7eT2#?secret=xa8euDvcgZ\" data-secret=\"xa8euDvcgZ\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-devopsschool-com wp-block-embed-devopsschool-com\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"61G0BD1uJ0\"><a href=\"https:\/\/www.devopsschool.com\/blog\/understanding-local-exec-provisioner-in-terraform\/\">Understanding local-exec provisioner in terraform<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Understanding local-exec provisioner in terraform&#8221; &#8212; \" src=\"https:\/\/www.devopsschool.com\/blog\/understanding-local-exec-provisioner-in-terraform\/embed\/#?secret=nIIWBdWSz9#?secret=61G0BD1uJ0\" data-secret=\"61G0BD1uJ0\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-devopsschool-com wp-block-embed-devopsschool-com\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"3dtOfVDzm5\"><a href=\"https:\/\/www.devopsschool.com\/blog\/terrafrom-example-code-for-aws-ec2-instance-and-remote-exec-provisioner\/\">Terrafrom Tutorials &#8211; remote-exec provisioner using AWS &#038; Azure providers<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Terrafrom Tutorials &#8211; remote-exec provisioner using AWS &#038; Azure providers&#8221; &#8212; \" src=\"https:\/\/www.devopsschool.com\/blog\/terrafrom-example-code-for-aws-ec2-instance-and-remote-exec-provisioner\/embed\/#?secret=7QD0JkA0pf#?secret=3dtOfVDzm5\" data-secret=\"3dtOfVDzm5\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-devopsschool-com wp-block-embed-devopsschool-com\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"EtQHf0ThFW\"><a href=\"https:\/\/www.devopsschool.com\/blog\/terrafrom-example-code-for-remote-exec-provisioner\/\">Terrafrom &#8211; Example Code for remote-exec, local-exec &#038; file provisioner<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Terrafrom &#8211; Example Code for remote-exec, local-exec &#038; file provisioner&#8221; &#8212; \" src=\"https:\/\/www.devopsschool.com\/blog\/terrafrom-example-code-for-remote-exec-provisioner\/embed\/#?secret=4ebnyAXhwl#?secret=EtQHf0ThFW\" data-secret=\"EtQHf0ThFW\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-devopsschool-com wp-block-embed-devopsschool-com\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"uKGBbbYFnc\"><a href=\"https:\/\/www.devopsschool.com\/blog\/terraform-example-program-for-aws_security_group-aws_instance-and-provisioner\/\">Terraform example program for aws_security_group, aws_instance and provisioner<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;Terraform example program for aws_security_group, aws_instance and provisioner&#8221; &#8212; \" src=\"https:\/\/www.devopsschool.com\/blog\/terraform-example-program-for-aws_security_group-aws_instance-and-provisioner\/embed\/#?secret=x7tIhQJG9C#?secret=uKGBbbYFnc\" data-secret=\"uKGBbbYFnc\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n<div class=\"epyt-gallery\" data-currpage=\"1\" id=\"epyt_gallery_35128\"><figure class=\"wp-block-embed wp-block-embed-youtube is-type-video is-provider-youtube epyt-figure\"><div class=\"wp-block-embed__wrapper\"><iframe loading=\"lazy\"  id=\"_ytid_75308\"  width=\"760\" height=\"427\"  data-origwidth=\"760\" data-origheight=\"427\" src=\"https:\/\/www.youtube.com\/embed\/?enablejsapi=1&#038;autoplay=0&#038;cc_load_policy=0&#038;cc_lang_pref=&#038;iv_load_policy=1&#038;loop=0&#038;rel=1&#038;fs=1&#038;playsinline=0&#038;autohide=2&#038;theme=dark&#038;color=red&#038;controls=1&#038;disablekb=0&#038;\" class=\"__youtube_prefs__  no-lazyload\" title=\"YouTube player\"  data-epytgalleryid=\"epyt_gallery_35128\"  allow=\"fullscreen; accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen data-no-lazy=\"1\" data-skipgform_ajax_framebjll=\"\"><\/iframe><\/div><\/figure><div class=\"epyt-gallery-list\"><div>Sorry, there was a YouTube error.<\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Terraform provisioners are used to execute scripts or shell commands on a local or remote machine as part of resource creation\/deletion. They are similar to \u201cEC2 instance user data\u201d scripts that only run once on the creation and if it fails terraform marks it tainted. Terraform includes a number of built-in provisioners, such as: Provisioners&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","_joinchat":[],"footnotes":""},"categories":[5129],"tags":[],"class_list":["post-11114","post","type-post","status-publish","format-standard","hentry","category-terraform"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/11114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=11114"}],"version-history":[{"count":9,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/11114\/revisions"}],"predecessor-version":[{"id":39979,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/11114\/revisions\/39979"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=11114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=11114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=11114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}