<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Terraform Archives - VirtJunkie</title>
	<atom:link href="/category/automation/hashicorp/terraform/feed/" rel="self" type="application/rss+xml" />
	<link>/category/automation/hashicorp/terraform/</link>
	<description>Virtualization, Automation, and anything else that might be on my mind</description>
	<lastBuildDate>Mon, 05 Jul 2021 22:22:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.2</generator>

<image>
	<url>/wp-content/uploads/2020/04/cropped-vj4-150x150.png</url>
	<title>Terraform Archives - VirtJunkie</title>
	<link>/category/automation/hashicorp/terraform/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>VMware Provisioning using Hashicorp Terraform  &#8211; Part 2</title>
		<link>/2020/07/06/vmware-provisioning-using-hashicorp-terraform-part-2/</link>
					<comments>/2020/07/06/vmware-provisioning-using-hashicorp-terraform-part-2/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Mon, 06 Jul 2020 13:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Hashicorp]]></category>
		<category><![CDATA[InfrastructureAsCode]]></category>
		<category><![CDATA[Terraform]]></category>
		<category><![CDATA[VMware]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=1334</guid>

					<description><![CDATA[<p>In the first part of this series we went over Terraform at a very high level and discussed a basic example of using it to provision a single Windows VM or a single Linux VM. While this is a helpful baseline, it doesn&#8217;t realistically help us when defining our application structure in code. For example, [&#8230;]</p>
<p>The post <a href="/2020/07/06/vmware-provisioning-using-hashicorp-terraform-part-2/">VMware Provisioning using Hashicorp Terraform  &#8211; Part 2</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In the <a href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform/" target="_blank" rel="noreferrer noopener">first part of this series</a> we went over Terraform at a very high level and discussed a basic example of using it to provision a single Windows VM or a single Linux VM. While this is a helpful baseline, it doesn&#8217;t realistically help us when defining our application structure in code. For example, if you wanted to set up a <a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture" target="_blank">three tier application</a> you&#8217;ll need to have three separate instances of the project we used. At that point we&#8217;re not really gaining much efficiency over deploying a template in vCenter. In this post I&#8217;ll discuss Terraform Modules, give an example of how to store your Terraform Module in GitHub, and provide a real-life example of how to deploy a three tier application using multiple source images.</p>



<span id="more-1334"></span>



<h2 class="wp-block-heading">Introduction to Terraform Modules</h2>



<p>In Part 1 of this series I <a href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform/#main_tf" target="_blank" rel="noreferrer noopener">compared traditional programming languages to Terraform</a>. We can do the same thing with Modules. For example, with Powershell or Python, you can download a module that provides functionality and consume that functionality in your code without having to author it. The same thing happens in Terraform, and just like with other languages, you can create your own, or download one from a third party.</p>



<h3 class="wp-block-heading">Terraform Registry</h3>



<p>Thankfully, <a rel="noreferrer noopener" href="https://registry.terraform.io/" target="_blank">Hashicorp provides us with a registry</a> that we can use to find and consume Terraform Modules. At the time this post is published, the Terraform Registry contains support for <a rel="noreferrer noopener" href="https://registry.terraform.io/browse/providers" target="_blank">63 providers</a> and has <a rel="noreferrer noopener" href="https://registry.terraform.io/browse/modules" target="_blank">3454 Modules</a>. So if you are looking for specific functionality, check there first!</p>



<h2 class="wp-block-heading">Roll Your Own Module</h2>



<p>That said, you may have a need to create your own module, or if you&#8217;re like me, want to make sure you understand how modules work before you use one that someone else created.</p>



<h3 class="wp-block-heading">Best Practices</h3>



<p>First and foremost, you&#8217;ll want to take a look at the official documentation from Hashicorp on the standard module structure. It gets pretty in-depth, but I&#8217;ll hit on a few high level important items.</p>



<ul><li>Store your module in github</li><li>At the very least, make sure you split your variables and outputs into different TF files</li><li>Include an examples directory and show every variation of how to call your module. For example, if you can create a linux image or a windows image, but you need to call them differently, show an example for each.</li><li>Include a README.md file that has a description of the module, but also references your examples</li></ul>



<h3 class="wp-block-heading">Why store your module in GitHub?</h3>



<p>Aside from the wide ranging benefits of using version control, using GitHub will allow you to call a specific version of your module.</p>



<h3 class="wp-block-heading">File Structure</h3>



<p>The following files should be in your GitHub reposity. When you run <code>terraform init</code>, it will be downloaded to the .terraform directory on the machine running the project.</p>



<h4 class="wp-block-heading">main.tf</h4>



<script src="https://gist.github.com/jonhowe/7526c2316eda915116ae63248154b4cb.js"></script>



<h4 class="wp-block-heading">variables.tf</h4>



<script src="https://gist.github.com/jonhowe/5d44ecc0680f4c64447f9e7bab7b5150.js"></script>



<h4 class="wp-block-heading">output.tf</h4>



<script src="https://gist.github.com/jonhowe/81b6205c683c0a9273e29b9c62ee8a79.js"></script>



<h2 class="wp-block-heading">How to use this module?</h2>



<p>Now that we&#8217;ve created our module and have it in Github, all we need to do in order to complete our initial goal of having a three tier application is to create a single main.tf file, and call the module 3 times. Below is an example that allows us to set separate information for each of the new VMs.</p>



<script src="https://gist.github.com/jonhowe/f81432f089cb3bbc36113ce29e4f1db4.js"></script>



<h2 class="wp-block-heading">References and what&#8217;s next?</h2>



<h3 class="wp-block-heading">What&#8217;s Next?</h3>



<p>At this point we have shown how to create and <a href="https://www.virtjunkie.com/vmware-template-packer/" target="_blank" rel="noreferrer noopener">manage images using packer</a>, a <a href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform/" target="_blank" rel="noreferrer noopener">couple</a> of <a href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform-part-2/" target="_blank" rel="noreferrer noopener">parts</a> on how to use Terraform to deploy infrastructure, so all we have left is doing configuration of our newly created VMs.</p>



<ul><li>Use Ansible to configure our newly provisioned VMs</li><li>Wrap the Terraform VM Deployment process, as well as the Ansible VM configuration process together into a single process you execute once</li><li>Use Ansible to do a greenfield deployment of a vSphere environment</li></ul>



<h3 class="wp-block-heading">References</h3>



<ul><li><a rel="noreferrer noopener" href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform/" target="_blank">Part 1 &#8211; Provision VMware VMs using Terraform</a></li><li><a href="https://registry.terraform.io/">Terraform Registry</a></li><li><a rel="noreferrer noopener" href="https://www.terraform.io/docs/modules/index.html#standard-module-structure" target="_blank">Module Structure</a></li></ul>
<p>The post <a href="/2020/07/06/vmware-provisioning-using-hashicorp-terraform-part-2/">VMware Provisioning using Hashicorp Terraform  &#8211; Part 2</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2020/07/06/vmware-provisioning-using-hashicorp-terraform-part-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</title>
		<link>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/</link>
					<comments>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/#respond</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Mon, 04 May 2020 13:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[BASH]]></category>
		<category><![CDATA[Hashicorp]]></category>
		<category><![CDATA[InfrastructureAsCode]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[Terraform]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=1304</guid>

					<description><![CDATA[<p>With everything going on in the world with COVID-19 and the social distancing that is happening, people are looking to connect with friends, family and co-workers via Video conferencing more than ever. Recent vulnerabilities in Zoom have made people more cognizant than ever that security needs to be considered when using these platforms no matter [&#8230;]</p>
<p>The post <a href="/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/">Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>With everything going on in the world with COVID-19 and the social distancing that is happening, people are looking to connect with friends, family and co-workers via Video conferencing more than ever. Recent vulnerabilities in Zoom have made people more cognizant than ever that security needs to be considered when using these platforms no matter what you are using them for.</p>



<p><a href="https://jitsi.org/" target="_blank" rel="noreferrer noopener">Jitsi is an open source video conferencing platform</a> that I&#8217;ve been hearing about a lot lately, and finally had a chance to look into. In this post I&#8217;ll explain how to use Terraform to provision a Jitsi instance when you need a conference and tear it down when you are done. We&#8217;ll be using Vultr and their Jitsi &#8220;application&#8221; and AWS Route 53 for DNS.</p>



<span id="more-1304"></span>



<h2 class="wp-block-heading">Why Am I Writing This Article, and What Does It Accomplish?</h2>



<p>Why am I writing this article?</p>



<ol><li>We <strong>always</strong> want to have our apps and infrastructure defined in code</li><li>We pay for traditional web conferencing software 24 hours a day, 7 days a week, regardless of if we are are using running a conference or not. Why don&#8217;t we spin up conference infrastructure <strong>when we need it, and tear it down when we don&#8217;t</strong>?</li></ol>



<p>At a high level, this project will accomplish the following:</p>



<ol><li>Provision a Vultr VPS that is pre-configured with Jitsi</li><li>Take the IP Address that Vultr assigns the VPS and use it to create an A Record in Route 53</li><li>Copy a script to your VPS that will be used to finish the Jitsi configuration</li><li>Run the script that we copied and pass a few command line arguments that are specific to our environment</li></ol>



<h2 class="wp-block-heading">Prerequisites</h2>



<p>In addition to having Terraform downloaded and installed, we&#8217;ll need the following items:</p>



<h3 class="wp-block-heading">Vultr Account + API Access</h3>



<p>Vultr is definitely my go-to for VPS&#8217;s these days. Not only because of their price/performance/feature availability ratio, but because they provide a number of pre-configured applications that are ready, or near ready for use. <a rel="noreferrer noopener" href="https://www.vultr.com/docs/one-click-jitsi" target="_blank">Jitsi is one of these applications</a>. If you do use Vultr, please do me a favor and use&nbsp;<a rel="noreferrer noopener" href="https://www.vultr.com/?ref=8531966-6G" target="_blank">this link</a>&nbsp;to sign up. I’ll get a little kickback, but you’ll get $100 USD to use on the site in your first month.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile"><figure class="wp-block-media-text__media"><img fetchpriority="high" decoding="async" width="1024" height="450" src="https://www.virtjunkie.com/wp-content/uploads/2020/05/2020-05-02_19-45-1024x450.png" alt="" class="wp-image-1305" srcset="/wp-content/uploads/2020/05/2020-05-02_19-45-1024x450.png 1024w, /wp-content/uploads/2020/05/2020-05-02_19-45-300x132.png 300w, /wp-content/uploads/2020/05/2020-05-02_19-45-768x338.png 768w, /wp-content/uploads/2020/05/2020-05-02_19-45.png 1273w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure><div class="wp-block-media-text__content">
<p class="has-normal-font-size">Once you have a Vultr account, you&#8217;ll need to generate and record an API key to use with Terraform. Use the steps below to generate it.</p>



<ol><li>Log into Vultr</li><li>Navigate to Settings, and then API</li><li>Generate an API key, and copy it somewhere safe, we&#8217;ll be using it later</li></ol>
</div></div>



<h3 class="wp-block-heading">AWS Account + API Access</h3>



<p>We&#8217;ll be using <a rel="noreferrer noopener" href="https://aws.amazon.com/route53/" target="_blank">AWS&#8217;s Route 53 service</a>, which is really just a fancy DNS service that&#8217;s hooked into AWS.  In order to automate Route 53 with Terraform, we&#8217;ll need to enable API access.</p>



<div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile" style="grid-template-columns:auto 70%"><figure class="wp-block-media-text__media"><img decoding="async" width="1024" height="400" src="https://www.virtjunkie.com/wp-content/uploads/2020/05/2020-05-02_20-13-1024x400.png" alt="" class="wp-image-1307" srcset="/wp-content/uploads/2020/05/2020-05-02_20-13-1024x400.png 1024w, /wp-content/uploads/2020/05/2020-05-02_20-13-300x117.png 300w, /wp-content/uploads/2020/05/2020-05-02_20-13-768x300.png 768w, /wp-content/uploads/2020/05/2020-05-02_20-13-1536x599.png 1536w, /wp-content/uploads/2020/05/2020-05-02_20-13-1568x612.png 1568w, /wp-content/uploads/2020/05/2020-05-02_20-13.png 1607w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure><div class="wp-block-media-text__content">
<p><a rel="noreferrer noopener" href="https://console.aws.amazon.com/iam/home?#security_credential" target="_blank">Use this link to access the IAM Management page</a></p>



<ol><li>Expand the &#8220;Access Keys&#8221; blade</li><li>Select &#8220;Create New Access Key</li><li>Save the resulting file, as we&#8217;ll use the contents later</li></ol>
</div></div>



<h3 class="wp-block-heading">Domain Registrar Using Custom Nameservers</h3>



<p>In addition to the above, the domain you want to use will need to be configured to use the Route 53 Name Servers. Route 53 will provide you the nameservers when you create a zone, and you&#8217;ll simply plug those into your registrar DNS settings page. I&#8217;m not going to explain how to create a zone in Route 53, or how to configure your registrar, but if you have questions, throw them in the comments and I&#8217;ll do my best to help.</p>



<h2 class="wp-block-heading">Getting Started</h2>



<h3 class="wp-block-heading">Run This Project</h3>



<ol><li>Grab the files below, or copy them from my <a rel="noreferrer noopener" href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53" target="_blank">Github Repository</a></li><li>Enter the directory that contains the files</li><li>At a minimum, modify the fields in the auto.tfvars file<ol><li>vultr_api_key</li></ol><ol><li>aws_access_key</li><li>aws_secret_key</li><li>domain</li><li>email</li></ol></li><li>Initialize Terraform by running <strong><code>terraform init</code></strong></li><li>Create a terraform plan by running <strong><code>terraform plan</code></strong></li><li>Apply the configuration by running <strong><code>terraform apply</code></strong></li><li>Voila! In less than 5 minutes, you&#8217;ve got a functional, secure Jitsi instance, running on a server and domain you control. Upon successful creation, you&#8217;ll see text like what we see below giving you the URL and credentials. When you are done with your conference, just run <code><strong>terraform destroy</strong></code> to stop from receiving charges on a server/service you aren&#8217;t using.</li></ol>



<pre class="urvanov-syntax-highlighter-plain-tag">null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): |                            |
null_resource.jitsi_config (remote-exec): |   JITSI SETUP COMPLETED!   |
null_resource.jitsi_config (remote-exec): |                            |
null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): JITSI URL: https://conference.yourdomain.com/

null_resource.jitsi_config (remote-exec): USERNAME: admin
null_resource.jitsi_config (remote-exec): PASSWORD: @#$asdfahgsd34579--23%4asdf</pre>



<h2 class="wp-block-heading">Code</h2>



<h3 class="wp-block-heading">Main.tf</h3>



<p>This file does all of the work.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#main.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53

#Conifugre the Vultr provider
provider &quot;vultr&quot; {
  api_key = var.vultr_api_key
  rate_limit = 700
  retry_limit = 3
}

#Configure the AWS Provider
provider &quot;aws&quot; {
  #profile    = &quot;default&quot;
  #shared_credentials_file = &quot;/home/jhowe/storage/btsync/folders/Sync/awscredentials/credentials&quot;
  region     = var.aws_region
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
}

#https://www.terraform.io/docs/providers/aws/d/route53_zone.html
data &quot;aws_route53_zone&quot; &quot;selected&quot; {
  name         = &quot;${var.domain}.&quot;
  private_zone = false
}

#Provision Vultr Server
resource &quot;vultr_server&quot; &quot;my_server&quot; {
    plan_id = var.vultr_plan_id
    region_id = var.vultr_region
    app_id = var.vultr_app_id
    label = &quot;${var.hostname}.${var.domain}&quot;
    tag = var.vultr_tag
    hostname = &quot;${var.hostname}.${var.domain}&quot;
    enable_ipv6 = false
    auto_backup = false
    ddos_protection = false
    notify_activate = false

    connection {
        type     = &quot;ssh&quot;
        user     = &quot;root&quot;
        
        #https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
        password = self.default_password

        #https://www.terraform.io/docs/provisioners/connection.html#the-self-object
        host     = self.main_ip
    }

    provisioner &quot;local-exec&quot; {
      command = &quot;echo SSH to this server with the command: ssh root@${vultr_server.my_server.main_ip} with the password '${vultr_server.my_server.default_password}'&quot;
    }
}

#Create the Route 53 A Record
#https://www.terraform.io/docs/providers/aws/r/route53_record.html
resource &quot;aws_route53_record&quot; &quot;conference&quot; {
  zone_id = data.aws_route53_zone.selected.zone_id
  name    = &quot;${var.hostname}.${data.aws_route53_zone.selected.name}&quot;
  type    = &quot;A&quot;
  ttl     = &quot;300&quot;
  records = &amp;#91;&quot;${vultr_server.my_server.main_ip}&quot;]
}

#This null resource exists to handle configuration of the Vultr VPS after Route 53
resource &quot;null_resource&quot; &quot;jitsi_config&quot; {
    
    connection {
        type     = &quot;ssh&quot;
        user     = &quot;root&quot;
        
        #https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
        password = vultr_server.my_server.default_password

        #https://www.terraform.io/docs/provisioners/connection.html#the-self-object
        host     = vultr_server.my_server.main_ip
    }

    provisioner &quot;file&quot; {
        source      = &quot;./configure_jitsi_param.sh&quot;
        destination = &quot;/root/configure_jitsi_param.sh&quot;
    }

    provisioner &quot;remote-exec&quot; {
        inline = &amp;#91;
            &quot;chmod +x /root/configure_jitsi_param.sh&quot;,
            &quot;/root/configure_jitsi_param.sh ${var.hostname}.${var.domain} ${var.email} y&quot;
        ]
    }
}</pre>



<h3 class="wp-block-heading">Variables.tf</h3>



<p>This file defines the variables that we will use in main.tf</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#variables.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53

variable &quot;vultr_api_key&quot; {
    description = &quot;API Key Used by Vultr (https://my.vultr.com/settings/#settingsapi)&quot;
}

variable &quot;vultr_region&quot; {
    description = &quot;Vultr Region Selection (curl https://api.vultr.com/v1/regions/availability?DCID=1)&quot;
    default = 1
}

variable &quot;vultr_plan_id&quot; {
    description = &quot;Vultr Plan for the VPS to use (curl https://api.vultr.com/v1/plans/list)&quot;
    default = 202
}

variable &quot;vultr_tag&quot; {
    description = &quot;Vultr Tag to apply to the new VPS&quot;
    default = &quot;jitsi-conference&quot;
}

variable &quot;vultr_app_id&quot; {
    description = &quot;Vultr App to pre-install. This should always be '47', if jitsi is being provisioned (curl https://api.vultr.com/v1/app/list)&quot;
    default = 47
}

variable &quot;hostname&quot; {
    description = &quot;Hostname to be used&quot;
    default = &quot;conferences&quot;
}

variable &quot;email&quot; {
    description = &quot;email to be used for let's encrypt acme config&quot;
    default = &quot;john.doe@email.com&quot;
}

variable &quot;domain&quot; {
    description = &quot;domain to be used&quot;
    default = &quot;aremyj.am&quot;
}

variable &quot;aws_access_key&quot; {
    description = &quot;AWS Access Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)&quot;
}

variable &quot;aws_secret_key&quot; {
    description = &quot;AWS Secret Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)&quot;
}

variable &quot;aws_region&quot; {
    description = &quot;AWS Region&quot;
    default = &quot;us-east-1&quot;
}</pre>



<h3 class="wp-block-heading">[yourdomain].auto.tfvars</h3>



<p>The auto.tfvars file provides values to the variables defined in the variables.tf file. You&#8217;ll have to create this file from scratch, and terraform best practices dictate that you exclude this file from source control. Here&#8217;s an example you can use. Modify this for your environment. The name doesn&#8217;t matter, as long as it ends with auto.tfvars.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">vultr_api_key = &quot;&amp;#91;fill this in]&quot;
vultr_region = 1
vultr_plan_id = 202
vultr_app_id = 47
vultr_tag = &quot;jitsi-conference&quot;
hostname = &quot;conference&quot;
email = &quot;your.email@address.org&quot;
domain = &quot;your-domain.com&quot;
aws_region = &quot;us-east-1&quot;
aws_access_key = &quot;&amp;#91;fill this in]&quot;
aws_secret_key = &quot;&amp;#91;fill this in]&quot;</pre>



<h3 class="wp-block-heading">configure_jitsi_param.sh</h3>



<p>Full disclosure, I did not create this script. Vultr created it, and provides it on your Jitsi VPS when you request it. Unfortunately, the version they provide is intended to be executed interactively, so I made a few very minor modifications to allow for us to run it with parameters.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
#This script was copied from /opt/vultr/configure_jitsi.sh on a Vultr VPS that has the one-click Jitsi App
#I added lines 7-9 to allow for adding parameters on the CLI and commented lines 11-13 to force the variables to be provided on the CLI
#https://www.vultr.com/docs/one-click-jitsi
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
HOSTNAME=$1
EMAIL=$2
response=$3
# User choices
#read -ep &quot;Please specify which domain you would like to use: &quot; HOSTNAME
#read -ep &quot;Please enter your email address for Let's Encrypt Registration: &quot; EMAIL
#read -r -p &quot;Would you like to enable password authorization? &amp;#91;y/N] &quot; response
case &quot;$response&quot; in
    &amp;#91;yY]&amp;#91;eE]&amp;#91;sS]|&amp;#91;yY])
        AUTH=1
        ;;
    *)
        AUTH=0
        ;;
esac


PROSODYPATH=/etc/prosody/conf.avail/${HOSTNAME}.cfg.lua
JITSIPATH=/etc/jitsi/meet/${HOSTNAME}-config.js
JICOFOPATH=/etc/jitsi/jicofo/sip-communicator.properties

# Remove and purge (Stop first and wait to avoid race condition)
purgeold() {        
        /opt/vultr/stopjitsi.sh
        sleep 5
        apt -y purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge2 jitsi*
}

# Reinstall
reinstalljitsi() {
        echo &quot;jitsi-videobridge2 jitsi-videobridge/jvb-hostname string ${HOSTNAME}&quot; | debconf-set-selections
        echo &quot;jitsi-meet-web-config jitsi-meet/cert-choice string Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate)&quot; | debconf-set-selections
        apt-get -y install jitsi-meet
}

# Remove nginx defaults
wipenginx() {
        rm -f /etc/nginx/sites-enabled/default
}

# Configure Lets Encrypt
configssl(){
    systemctl restart nginx
    sed -i -e 's/echo.*Enter your email and press.*/EMAIL=$1/' /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
    sed -i -e 's/read EMAIL//'  /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
    /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh ${EMAIL}
}

configprosody() {
  AUHTLINE='authentication = &quot;internal_plain&quot;'
  sed -i &quot;s/authentication\ \=\ \&quot;anonymous\&quot;/${AUTHLINE}/g&quot; ${PROSODYPATH}
  cat &amp;lt;&amp;lt; EOT &gt;&gt; ${PROSODYPATH}

VirtualHost &quot;guest.${HOSTNAME}&quot;
    authentication = &quot;anonymous&quot;
    c2s_require_encryption = false

EOT
}

configjitsi() {
        sed -i &quot;s/\/\/\ anonymousdomain\:\ 'guest.example.com',/anonymousdomain\:\ 'guest.${HOSTNAME}',/g&quot; ${JITSIPATH}
}

configjicofo() {
        echo &quot;org.jitsi.jicofo.auth.URL=XMPP:${HOSTNAME}&quot; &gt;&gt; ${JICOFOPATH}
}

registeruser(){
        PASSWORD=$(&amp;lt; /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16};echo;)
        prosodyctl register admin ${HOSTNAME} ${PASSWORD}
}

restartjitsi() {
        /opt/vultr/stopjitsi.sh
        /opt/vultr/startjitsi.sh
}

completedsetup(){
    echo &quot;&quot;
    echo &quot;------------------------------&quot;
    echo &quot;|                            |&quot;
    echo &quot;|   JITSI SETUP COMPLETED!   |&quot;
    echo &quot;|                            |&quot;
    echo &quot;------------------------------&quot;
    echo &quot;JITSI URL: https://${HOSTNAME}&quot;/
    echo &quot;&quot;
}

outputUser(){
    echo &quot;USERNAME: admin&quot;
    echo &quot;PASSWORD: ${PASSWORD}&quot;
    echo &quot;&quot;
}

# Script start

purgeold
reinstalljitsi
wipenginx
configssl
if &amp;#91; &quot;$AUTH&quot; == &quot;1&quot; ]; then
    configprosody
    configjitsi
    configjicofo
    registeruser
    restartjitsi    
fi
completedsetup
if &amp;#91; &quot;$AUTH&quot; == &quot;1&quot; ]; then
    outputUser
fi</pre>



<h2 class="wp-block-heading">Summary + More Reading</h2>



<p>There you have it! With this project you can have a fully functional Jitsi instance on your own domain with end to end encryption in less than 5 minutes. When you are done, there&#8217;s no harm in deleting it so you aren&#8217;t charged.</p>



<p>Here are some references I used while creating this:</p>



<ul><li><a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53">https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53</a></li><li><a href="https://www.vultr.com/docs/one-click-jitsi">https://www.vultr.com/docs/one-click-jitsi</a></li><li><a href="https://www.terraform.io/docs/providers/aws/d/route53_zone.html">https://www.terraform.io/docs/providers/aws/d/route53_zone.html</a></li><li><a href="https://www.terraform.io/docs/providers/aws/r/route53_record.html">https://www.terraform.io/docs/providers/aws/r/route53_record.html</a></li><li><a href="https://www.terraform.io/docs/providers/vultr/r/server.html#default_password">https://www.terraform.io/docs/providers/vultr/r/server.html#default_password</a></li><li><a href="https://www.terraform.io/docs/provisioners/connection.html#the-self-object">https://www.terraform.io/docs/provisioners/connection.html#the-self-object</a></li><li>Create Vultr API Key: <a href="https://my.vultr.com/settings/#settingsapi">https://my.vultr.com/settings/#settingsapi</a></li><li>Create AWS Access/Secret Key: <a href="https://console.aws.amazon.com/iam/home?#security_credential">https://console.aws.amazon.com/iam/home?#security_credential</a></li><li>Vultr API Reference &#8211; has examples that will get you plan, region, and app IDs. <a href="https://www.vultr.com/api/">https://www.vultr.com/api/</a></li></ul>
<p>The post <a href="/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/">Jitsi for Just in Time Conferencing using Terraform on Vultr with Route 53</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2020/05/04/jitsi-jit-conferencing-tf-vultr-route53/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>VMware Provisioning using Hashicorp Terraform</title>
		<link>/2020/04/22/vmware-provisioning-using-hashicorp-terraform/</link>
					<comments>/2020/04/22/vmware-provisioning-using-hashicorp-terraform/#comments</comments>
		
		<dc:creator><![CDATA[Jon]]></dc:creator>
		<pubDate>Wed, 22 Apr 2020 13:00:00 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Hashicorp]]></category>
		<category><![CDATA[Terraform]]></category>
		<category><![CDATA[VMware]]></category>
		<guid isPermaLink="false">http://www.virtjunkie.com/?p=1181</guid>

					<description><![CDATA[<p>As a part of my effort to use Infrastructure as Code to define and automate VMware environments, I'm taking a look at Terraform for VMware provisioning. In this article, I will give a brief intro to Terraform, talk about how it can help in managing your enterprise environments, as well as how it's different than Ansible. I'll also provide example code and description for how to provision Windows and Linux VMs. </p>
<p>The post <a href="/2020/04/22/vmware-provisioning-using-hashicorp-terraform/">VMware Provisioning using Hashicorp Terraform</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>As a part of my effort to use Infrastructure as Code to define and automate VMware environments, I&#8217;m taking a look at Terraform for VMware provisioning. In this article, I will give a brief intro to Terraform, talk about how it can help in managing your enterprise environments, as well as how it&#8217;s different than Ansible. I&#8217;ll also provide example code and description for how to provision Windows and Linux VMs. </p>



<span id="more-1181"></span>



<h2 class="wp-block-heading">Source Code</h2>



<p>As always, you can find all of the source code for this project on my <a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Terraform" target="_blank" rel="noreferrer noopener">Github account</a>.</p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h2 class="wp-block-heading">Terraform Intro</h2>



<p>According to Hashicorp, <em>&#8220;Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions&#8221;</em>. </p>
</div></div>



<p>Like in <a rel="noreferrer noopener" href="https://www.virtjunkie.com/vmware-template-packer/" target="_blank">my packer article</a>, I want to be clear that this isn&#8217;t a Terraform 101 article. Hashicorp provides some fairly good documentation, and the internet is full of articles explaining how to get going with Terraform.  That said, I will provide a short references for some of the building blocks of Terraform.</p>
</div></div>
</div></div>
</div></div>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<h2 class="wp-block-heading">Terraform VS. Deploying VMware Templates in vCenter VS. Ansible</h2>



<p>Should you use Terraform to provision VMs instead of deploying a VM from vCenter? Should you use Ansible instead of either of them? As with everything in technology these days, it depends. The skill we should all work towards is developing the ability to determine what tool we should use for the task at hand.</p>
</div></div>



<h3 class="wp-block-heading">Deploying VMware Templates in vCenter</h3>



<p>Nothing new here.. log into vCenter, deploy a VM from a template, use a guest customization specification. The pro&#8217;s are obvious, so I&#8217;ll skip over them and focus on the cons.</p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<p><strong>Cons:</strong></p>



<ul><li>Multi-step manual process for each VM</li><li>Guest Customization Specification is tied to a single vCenter Server which reduces scalability</li><li>Multiple VMs require multiple iterations of the same manual process</li></ul>
</div></div>



<h3 class="wp-block-heading">Deploy VMs via Ansible</h3>



<p>Ansible communicates with an OS via SSH on Linux, and via WinRM on Windows. It has different modules that can be used to communicate with different providers, such as AWS, GCP, and yes, VMware.</p>



<p><strong>Pros:</strong></p>



<ul><li>Infrastructure is defined in code</li><li>Excellent at ensuring desired state configuration of </li><li>Multi-os, and multi-cloud support</li></ul>



<p><strong>Cons:</strong></p>



<ul><li>This could end up being a bit of a holy war, but I consider it a con that Ansible requires different modules to connect to different cloud providers. They are maintained by different teams and individuals, and end up working differently than each other.</li></ul>



<h3 class="wp-block-heading">Deploy VMs using Terraform</h3>



<p>Terraform, similarly to Ansible, is able to communicate with Linux via SSH and Windows via WinRM. Where it differs, is it&#8217;s ability to communicate with cloud providers such as AWS, GCP, Azure, and VMware. Terraform uses the concept of &#8220;Providers&#8221;, with a number of them being maintained by Hashicorp, and a number of them being maintained by the community. In addition to cloud providers, they also have providers that allow for configuration of networking hardware, storage, databases, monitoring, DNS systems, and many more, all using the same structure in your code.</p>



<h2 class="wp-block-heading">Terraform Component Overview</h2>



<p>Few points to get us started here:</p>



<ul><li>Terraform will look in a directory for all files that have the extension of .tf, and .auto.tfvars</li><li>Terraform configuration files are written in <a rel="noreferrer noopener" href="https://www.terraform.io/docs/configuration/syntax.html" target="_blank">a language called HCL</a>, but can also be written in JSON.</li><li>Terraform uses the concept of blocks, I&#8217;ll go through them below</li></ul>



<h3 class="wp-block-heading">Resource Block</h3>



<p><a rel="noreferrer noopener" href="https://www.terraform.io/docs/configuration/resources.html" target="_blank">Hashicorp defines resources</a> as <em>the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.</em> </p>



<p>In our example, we will be working with the resource type &#8220;vsphere_virtual_machine&#8221; that is defined by the vSphere provider. This resource block contains all information needed to provision and customize a new VM.</p>



<h3 class="wp-block-heading">Provider Block</h3>



<p>We&#8217;ll be working with the vSphere provider in this project. Providers have two main functions we should keep in mind when using Terraform with VMware.</p>



<ul><li>They define parameters used to connect to vCenter</li><li>They expose additional resources we can use. Most notably, the vsphere_virtual_machine resource.</li></ul>



<p><a href="https://www.terraform.io/docs/configuration/providers.html" target="_blank" rel="noreferrer noopener">Hashicorp Provider Documentation</a></p>



<h3 class="wp-block-heading">Data Source Blocks</h3>



<p>Hashicorp tells us that &#8220;<em><em>Data sources</em>&nbsp;allow data to be fetched or computed for use elsewhere in Terraform configuration. Use of data sources allows a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration</em>&#8221; and that <em>&#8220;Each&nbsp;provider&nbsp;may offer data sources alongside its set of&nbsp;resource types&#8221;</em>. </p>



<p>To say this &#8220;cloud agnostically&#8221;, data sources allow us to fetch information from a provider (whether it be something like AWS, GCP, Azure, or vSphere), and use that information in a resource.</p>



<p>To say this in &#8220;VMware Speak&#8221;, we use data sources to pull information like a datacenter, cluster, datastore, or port group from a vCenter, and use it to build a VM.</p>



<h3 class="wp-block-heading">Input Variable Block</h3>



<p>Hashicorp&#8217;s documentation says that Input Variables <em>&#8220;serve as parameters for a Terraform module, allowing aspects of the module to be customized without altering the module&#8217;s own source code, and allowing modules to be shared between different configurations</em>&#8220;. To say this another way, input variables end up working like parameters added on the command line on a script.</p>



<h2 class="wp-block-heading">Examples</h2>



<p>Let&#8217;s put all of this together. I&#8217;ll give you two examples here, one for setting up a Linux VM and one for a Windows VM.</p>



<h3 class="wp-block-heading">Provision Linux VM with Terraform</h3>



<p>The three files below are required for this project, and can be found in the <a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Terraform" target="_blank" rel="noreferrer noopener">github repository</a>.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">├── main.tf
├── variables.tf
└── homelab.auto.tfvars</pre>



<h4 class="wp-block-heading">Quick Start</h4>



<p>Run the following commands to get started!</p>



<pre class="urvanov-syntax-highlighter-plain-tag">git clone https://github.com/jonhowe/Virtjunkie.com.git
cd Virtjunkie.com/Terraform/SingleLinuxVM
terraform init
terraform plan
terraform apply</pre>



<p>Running <strong><code>terraform init</code> </strong>will set up the Terraform project. It will download any required modules and plugins for the project to be created. It will store all of it&#8217;s files in a hidden directory called &#8220;.terraform&#8221;.</p>



<p>The command <code><strong>terraform plan</strong></code> looks at the destination and determines what needs to change. Optionally, you can have Terraform store this &#8220;plan&#8221; in a file to be used at a later time. To do this, you&#8217;ll run this command: <code><strong>terraform plan -out myplan.tfplan</strong></code>. The extension and file name are not important.</p>



<p>Finally, the command <code><strong>terraform apply</strong></code> is used to make changes to the environment that were determined in the &#8220;plan&#8221; step. Optionally, you can tell terraform to &#8220;apply&#8221; based on the output. To do this, you&#8217;ll run the following command: <code><strong>terraform apply myplan.tfplan</strong></code>. This isn&#8217;t necessary for a single VM deployment, but if you are using automation, or deploying multiple VMs, it is more important.</p>



<h4 class="wp-block-heading">main.tf</h4>



<p>As the name states, this is the main file in the project. It contains the provider, data source, and resource blocks.</p>



<p>The provider block simply is pretty self explanatory. If this is your first time looking at a Terraform file, you&#8217;ll probably be interested in the var.&#8221;whatever&#8221; lines. In the provider block, there&#8217;s a variable in the variables.tf file called vsphere_user (and the others as well). The &#8220;var.&#8221; prefix tells us that we should look for this variable definition in an input variables block.</p>



<p>The data blocks take raw data from the vSphere environment (datacenter, datastore, cluster, and port group) and store them in variables used for building a VM. </p>



<p>To understand this a bit more, please take a look at the picture below. We are creating a variable called <strong><code>datacenter_id</code></strong> on line 19 and assigning it the value <strong><code>data.vsphere_datacenter.dc.id</code></strong>. Understanding this concept is key to understanding how Terraform creates and consumes variables. The below image will elaborate a bit. The value of <strong><code>data.vsphere_datacenter.dc.id</code></strong> is returned from the datacenter object in the vCenter Server.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="775" height="368" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/terraform-config.png" alt="" class="wp-image-1228" srcset="/wp-content/uploads/2020/04/terraform-config.png 775w, /wp-content/uploads/2020/04/terraform-config-300x142.png 300w, /wp-content/uploads/2020/04/terraform-config-768x365.png 768w" sizes="(max-width: 775px) 100vw, 775px" /></figure>



<p>I&#8217;ll be comparing the way that Terraform blocks work together to the way that a programming function works. I&#8217;ll be using the following pseudocode to show similarities. The main.tf file, alongside with the blocks it contains would correspond with the area below:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="797" height="276" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/terraform-main.png" alt="" class="wp-image-1236" srcset="/wp-content/uploads/2020/04/terraform-main.png 797w, /wp-content/uploads/2020/04/terraform-main-300x104.png 300w, /wp-content/uploads/2020/04/terraform-main-768x266.png 768w" sizes="(max-width: 797px) 100vw, 797px" /></figure>



<p><strong>Line 40 &#8211; Resource block begins</strong><br>Now that we understand how to reference values from input and data variables, most of this should be pretty clear. The one area I want to spend a little bit of time on is the customize block, starting on line 67. In this example, we are simply setting the host name and the domain inside of the provisioned VM. However, there you could set static networking, dns and the time zone as well, if you like.</p>



<p>Here&#8217;s the code for the main.tf file. It&#8217;s also <a href="https://github.com/jonhowe/Virtjunkie.com/blob/master/Terraform/SingleLinuxVM/main.tf" target="_blank" rel="noreferrer noopener">available on github</a>.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">#The variables are all defined in the variables.tf file. The values assigned to the variables are set in the auto.tfvars file

provider &quot;vsphere&quot; {
  #https://www.terraform.io/docs/providers/vsphere/index.html
  user                 = var.vsphere_user
  password             = var.vsphere_password
  vsphere_server       = var.vsphere_server
  allow_unverified_ssl = true
}

data &quot;vsphere_datacenter&quot; &quot;dc&quot; {
  #https://www.terraform.io/docs/providers/vsphere/d/datacenter.html
  name = var.datacenter
}

data &quot;vsphere_datastore&quot; &quot;datastore&quot; {
  #https://www.terraform.io/docs/providers/vsphere/d/datastore.html
  name          = var.datastore
  datacenter_id = data.vsphere_datacenter.dc.id
}

data &quot;vsphere_compute_cluster&quot; &quot;cluster&quot; {
  #https://www.terraform.io/docs/providers/vsphere/d/compute_cluster.html
  var.cluster
  datacenter_id = data.vsphere_datacenter.dc.id
}

data &quot;vsphere_network&quot; &quot;network&quot; {
  #https://www.terraform.io/docs/providers/vsphere/d/network.html
  name          = var.portgroup
  datacenter_id = data.vsphere_datacenter.dc.id
}

data &quot;vsphere_virtual_machine&quot; &quot;template&quot; {
  #https://www.terraform.io/docs/providers/vsphere/d/virtual_machine.html
  name          = var.template_name
  datacenter_id = data.vsphere_datacenter.dc.id
}

resource &quot;vsphere_virtual_machine&quot; &quot;vm&quot; {
  #https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html
  name             = var.vm_name
  resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.datastore.id

  num_cpus = var.vcpu_count
  memory   = var.memory
  guest_id = data.vsphere_virtual_machine.template.guest_id

  scsi_type = data.vsphere_virtual_machine.template.scsi_type

  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.template.network_interface_types&amp;#91;0]
  }

  disk {
    label            = &quot;disk0&quot;
    size             = data.vsphere_virtual_machine.template.disks.0.size
    eagerly_scrub    = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.template.id

    customize {
      #https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html#linux-customization-options
      linux_options {
        host_name = var.vm_name
        domain    = var.domain_name
      }

      #This example uses DHCP. To switch to static IP addresses, comment the line below...
      network_interface {}

      #... and uncomment this bloc
      /*
      network_interface {
        ipv4_address = var.vm_ip
        ipv4_netmask = var.vm_cidr
    }
      ipv4_gateway = var.default_gw
      dns_server_list = &amp;#91;&quot;1.2.3.4&quot;]
    */

    }

  }
}</pre>



<h4 class="wp-block-heading">variables.tf</h4>



<p>Terraform can be most easily understood by comparing the structure of a project to a programming function. The main file is the body of the function, and it consumes values of variables to &#8220;do stuff&#8221;. Most programming languages require us to declare a variable before we can assign a value to it or use it. That&#8217;s really all the input variables block is for. In the example below, we are defining the variable name, providing a description for it, and assigning a default value.</p>



<p>If you want to use a pseudocode example, the variable definition below is the function of the input variable block, and the function of the entire variables.tf file</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="795" height="294" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/terraform-variables-1.png" alt="" class="wp-image-1232" srcset="/wp-content/uploads/2020/04/terraform-variables-1.png 795w, /wp-content/uploads/2020/04/terraform-variables-1-300x111.png 300w, /wp-content/uploads/2020/04/terraform-variables-1-768x284.png 768w" sizes="(max-width: 795px) 100vw, 795px" /></figure>



<p>Here&#8217;s the code for the variables.tf file, which is also <a href="https://github.com/jonhowe/Virtjunkie.com/blob/master/Terraform/SingleLinuxVM/variables.tf" target="_blank" rel="noreferrer noopener">available on github</a>.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">variable &quot;vsphere_server&quot; {
  description = &quot;vsphere server for the environment - EXAMPLE: vcenter01.hosted.local&quot;
  default     = &quot;vcenter.corp.lab&quot;
}

variable &quot;vsphere_user&quot; {
  description = &quot;vsphere server for the environment - EXAMPLE: vsphereuser&quot;
  default     = &quot;administrator@vsphere.local&quot;
}

variable &quot;vsphere_password&quot; {
  description = &quot;vsphere server password for the environment&quot;
  default     = &quot;VMware1!&quot;
}

variable &quot;adminpassword&quot; { 
    default = &quot;terraform&quot; 
    description = &quot;Administrator password for windows builds&quot;
}

variable &quot;datacenter&quot; { 
    default = &quot;Datacenter&quot;
    description = &quot;Datacenter name in vCenter&quot;
}

variable &quot;datastore&quot; { 
    default = &quot;vsanDatastore&quot; 
    description = &quot;datastore name in vCenter&quot;
}

variable &quot;cluster&quot; { 
    default = &quot;Cluster&quot; 
    description = &quot;Cluster name in vCenter&quot;
}

variable &quot;portgroup&quot; { 
    default = &quot;VM Network&quot; 
    description = &quot;Port Group new VM(s) will use&quot;
}

variable &quot;domain_name&quot; { 
    default = &quot;contoso.lan&quot;
    description = &quot;Domain Search name&quot;
}
variable &quot;default_gw&quot; { 
    default = &quot;172.16.1.1&quot; 
    description = &quot;Default Gateway&quot;
}

variable &quot;template_name&quot; { 
    default = &quot;Windows2019&quot; 
    description = &quot;VMware Template Name&quot;
}

variable &quot;vm_name&quot; { 
    default = &quot;WS19-1&quot; 
    description = &quot;New VM Name&quot;

}

variable &quot;vm_ip&quot; { 
    default = &quot;172.16.1.150&quot; 
    description = &quot;IP Address to assign to VM&quot;
}

variable &quot;vm_cidr&quot; { 
    default = 24 
    description = &quot;CIDR Block for VM&quot;
}

variable &quot;vcpu_count&quot; { 
    default = 1 
    description = &quot;How many vCPUs do you want?&quot;
}

variable &quot;memory&quot; { 
    default = 1024 
    description = &quot;RAM in MB&quot;
}</pre>



<h4 class="wp-block-heading">homelab.auto.tfvars</h4>



<p>If you&#8217;ve been reading in order up to this point, you understand the programming function analogy. Ansible will look in it&#8217;s directory for a file with the extension of .auto.tfvars. It will use it to assign values to input variables that are defined in the variables.tf file.</p>



<p>Below is a pseudo code example that shows how we&#8217;d compare terraform to a function in a conventional programming language.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="787" height="303" src="https://www.virtjunkie.com/wp-content/uploads/2020/04/terraform-tfvars.png" alt="" class="wp-image-1234" srcset="/wp-content/uploads/2020/04/terraform-tfvars.png 787w, /wp-content/uploads/2020/04/terraform-tfvars-300x116.png 300w, /wp-content/uploads/2020/04/terraform-tfvars-768x296.png 768w" sizes="(max-width: 787px) 100vw, 787px" /></figure>



<p>Below is the tfvars file I use in my home lab, and for your reference, it&#8217;s also <a href="https://github.com/jonhowe/Virtjunkie.com/blob/master/Terraform/SingleLinuxVM/homelab.auto.tfvars" target="_blank" rel="noreferrer noopener">available on github</a>.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">vsphere_server = &quot;vcenter.home.lab&quot;

vsphere_user = &quot;administrator@vsphere.local&quot;

vsphere_password = &quot;VMware1!&quot;

adminpassword = &quot;terraform&quot; 

datacenter = &quot;Datacenter&quot;

datastore = &quot;vsanDatastore&quot; 

cluster = &quot;Cluster&quot;

portgroup = &quot;100-LabNetwork&quot; 

domain_name = &quot;home.lab&quot;

default_gw = &quot;172.16.1.1&quot; 

template_name = &quot;Ubuntu18&quot; 

vm_name = &quot;Ubuntu18-1&quot; 

vm_ip = &quot;172.16.1.150&quot;

vm_cidr = 24

vcpu_count = 1

memory = 1024</pre>



<h3 class="wp-block-heading">Provision Windows VM with Terraform</h3>



<p>Since provisioning a Windows and Linux VM share literally everything in a virtual environment with exception of the OS itself, there&#8217;s not a whole lot that&#8217;s different in provisioning Windows VMs. The one are that is different is the Customize block inside of the Resource block.</p>



<p>We are handling this the exact same as the Linux VM, however, we have a handful of options we can add, such as</p>



<ul><li>Join a domain</li><li>Execute a list of commands</li><li>Add a product key</li><li>Enable auto login for a specified amount of logins</li><li>Supply your own SysPrep file</li></ul>



<p>Here&#8217;s the code, but all files are <a href="https://github.com/jonhowe/Virtjunkie.com/tree/master/Terraform/SingleWindowsVM" target="_blank" rel="noreferrer noopener">stored on Github</a>.</p>



<pre class="urvanov-syntax-highlighter-plain-tag">resource &quot;vsphere_virtual_machine&quot; &quot;vm&quot; {
  name             = var.vm_name
  resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
  datastore_id     = data.vsphere_datastore.datastore.id

  num_cpus = var.vcpu_count
  memory   = var.memory
  guest_id = data.vsphere_virtual_machine.template.guest_id

  scsi_type = data.vsphere_virtual_machine.template.scsi_type

  network_interface {
    network_id   = data.vsphere_network.network.id
    adapter_type = data.vsphere_virtual_machine.template.network_interface_types&amp;#91;0]
  }

  disk {
    label            = &quot;disk0&quot;
    size             = data.vsphere_virtual_machine.template.disks.0.size
    eagerly_scrub    = data.vsphere_virtual_machine.template.disks.0.eagerly_scrub
    thin_provisioned = data.vsphere_virtual_machine.template.disks.0.thin_provisioned
  }

  clone {
    template_uuid = data.vsphere_virtual_machine.template.id

    customize {
      #https://www.terraform.io/docs/providers/vsphere/r/virtual_machine.html#windows-customization-options
      windows_options {
        computer_name  = var.vm_name
        admin_password = var.adminpassword
        /*
        join_domain = &quot;cloud.local&quot;
	      domain_admin_user = &quot;administrator@cloud.local&quot;
	      domain_admin_password = &quot;password&quot;
        run_once_command_list = &amp;#91;

        ]
        */
      }
      network_interface {}

      /*
      network_interface {
        ipv4_address = var.vm_ip
        ipv4_netmask = var.vm_cidr
      }
      ipv4_gateway = var.default_gw
      dns_server_list = &amp;#91;&quot;1.2.3.4&quot;]
      */
    }
  }
}</pre>



<h2 class="wp-block-heading">References</h2>



<p>The following resources were helpful for me getting started, and I suggest you take a look at them as well.</p>



<p>The Terraform documentation is the best place to start (<a rel="noreferrer noopener" href="https://www.terraform.io/docs/cli-index.html" target="_blank">link</a>)<br>Dmitry Teslya has a great article that got me started here, but like the packer article he created, wasn&#8217;t working for me. Highly recommend this one (<a rel="noreferrer noopener" href="https://dteslya.engineer/automation/2019-01-21-creating_vms_with_terraform/" target="_blank">link</a>)<br></p>



<h2 class="wp-block-heading">What&#8217;s next?</h2>



<p>Good Question! At this point, I&#8217;ve written <a href="https://www.virtjunkie.com/vmware-template-packer/" target="_blank" rel="noreferrer noopener">about how to manage images (read: vmware templates) using Packer</a>. I&#8217;ve written this article, which speaks to how to deploy the VMs. The next things I&#8217;ll speak about are:</p>



<ul><li><a href="https://www.virtjunkie.com/vmware-provisioning-using-hashicorp-terraform-part-2/" target="_blank" rel="noreferrer noopener">Write our own Terraform Module, store it in Github, and use that, instead of a full Terraform project, so we can deploy multiple VMs, from different templates, all at once.</a></li><li>Use Ansible to configure our newly provisioned VMs</li><li>Wrap the Terraform VM Deployment process, as well as the Ansible VM configuration process together into a single process you execute once</li><li>Use Ansible to do a greenfield deployment of a vSphere environment</li></ul>



<p></p>
<p>The post <a href="/2020/04/22/vmware-provisioning-using-hashicorp-terraform/">VMware Provisioning using Hashicorp Terraform</a> appeared first on <a href="/">VirtJunkie</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>/2020/04/22/vmware-provisioning-using-hashicorp-terraform/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
