This code provides a simplified look at configuring Intersight via Terraform. It works both as a set of coherent examples, and as a base for simple actives in a lab or learning environment.
In the work of the artist, a Study is an important step on the journey to create a new piece of art. It acts as a vehicle to help the artist understand the subject. The effort yields fresh insights that inform the ultimate creation.
While certain artists may work in clay or acrylics, others work in Ansible or Terraform. Or Python. Or Go.
This study should help you understand the subject and provide you with new insights.
The fundamental thing that always made Cisco UCS unique and interesting was the policy model. Instead of configuring one server, you built a stack of policy that could configure 100.
Although the policy model in Intersight is simplified compared to the UCS Manager policy model, the fundamental approach remains the same. And yet, all the details have changed.
One of the unique strengths of Intersight is the logical alignment with Terraform. The RESTful API using the Open API Spec lends itself to automatic conversion into a Terraform provider. And that’s what we have at our disposal.
Keep the Cisco Intersight Terraform Provider documentation close to hand.
The stacks of policy once held in UCS Manager, locked in each UCS Domain behind an XML API, are now exposed.
When approaching Intersight via Terraform, one is confronted with two simultaneously unfamiliar puzzles. The first puzzle is Terraform itself, and there are many resources available to help acquire the basics there. The second puzzle is Intersight. Here again, there are many great resources. If you have not yet been exposed to the Intersight Handbook, I have to recommend it immediately.
But there comes a point in the crawl, walk, run of learning when you want to see something that already works. It helps to see the Terraform concepts that may have been taught to you using the AWS provider implemented using the Intersight provider.
That is the goal of this effort.
These goals guided the development of this code.
- Simpler is better. Complexity will be here soon enough.
- No modules. Modules are great. But it’s easier to explain this code without them.
- Few variables. Variables are great. And this repository uses them in places, but they are used sparingly to improve the ease of understanding.
- One trick at a time. There are nice Terraform tricks that allow us to do more with less code. And this repository uses them in places, but in ways that are easier to understand because they are used in isolation instead of in a complex grouping.
This repo organizes code into many files. Although this may seem difficult at first, it makes it easier to use. There are a few files that are common to many TF projects.
This file is used to set some values that we use in a lot of places. They can be thought of as "static variables" in some ways. See the language docs for more details. This file has only a couple of values in it. Typically, you wouldn't need to change them if you're just getting started.
One value, which we use on all the resources, is to build a tag called "Automation" that we set to "Terraform". This tag is visible in Intersight to clearly mark the resources that we are creating with Terraform. Ideally, you would only change those resources via Terraform and not via the UI.
The other value in locals selects the organization where we want to deploy our resources. This isn't required by Intersight if your account only has the default organization. But if multiple organizations do exist, we must specify the target organization. Just to be safe, we're specifying the default organization. See also organization.tf
This file is used to tell Terraform which providers we intend to use and, in the case of Intersight, to configure them.
The required_providers
block tells Terraform the minimum version of each provider that our code requires. The random
provider doesn't have any configuration, but the intersight
provider does. In the intersight
block we retrieve the apikey
and secretkey
from variables. See the Required Variables section for more details.
In this file, we lookup the organization that already exists inside of your Intersight account. To do that, we use a Data Source. For simplicity, we use the default
organization.
The code that becomes a policy in Intersight is organized into a file for each policy type. They are named based on how the policy name is presented in the Intersight website. This doesn't always correspond perfectly to the resource names in the API, so sometimes our Terraform resources have different names. For example, in policy_boot_order.tf we use a resource type of intersight_boot_precision_policy
.
Some policies, such as policy_kvm.tf, only have one Terraform resource inside of them. Some policies, such as policy_imc_access.tf provide multiple examples of different policy options. All of those resources correspond one-to-one with the policy in Intersight.
Some policies, such as policy_local_user.tf or policy_port.tf, are actually constructed from multiple resources.
The code that becomes a pool in Intersight is likewise organized into a file for each pool type in a way that is like the policy files above. Most have multiple examples for different sized pools.
Profiles aggregate the policy and pool objects into something that can be applied to equipment. At least one example is provided for each type, and a server profile example is provided for FI Attached and Standalone targets in profile_ucs_server.tf.
There is also one example Server Profile Template. This template may be used from Intersight using the Derive Profiles action. While it is straightforward to create such templates from Terraform, it is not yet possible to use them from Terraform.
In addition to the basic server profile example, a more complex example that combines an intersight_search_search_item data source and an intersight_server_profile resource with a for_each to provision multiple profiles is provided in profile_ucs_server_by_tag.tf. Be aware that if you try to plan that terraform code and no servers are returned in the data source, it will cause the plan to (correctly) fail.
It is customary to define variables that are not "included" in the code using variables.tf. See the section below on Required Variable.
Although many of our Terraform files include variables that help us create better code (see pools_ip.tf for an example), this repo tries to keep the variables and the code that uses them together in the same file. The big exception is variables_network.tf which is used in policy_ethernet_network_group.tf and policy_vlan.tf among other places.
There are just three input variables that you need to specify to deploy this code to Intersight.
There are a couple of options for assigning input variables, but using a .tfvars is the preferred way.
That file might look something like this...
intersight-keyid = "ABCDEFGHIZJKMNOPQRSTUVWXYZ1234567890000"
intersight-secretkey = "insert your secret key here"
The most common way to specify these is by creating workspace specific variables.
You will need to have access to an Intersight account with at least one Essentials level license or higher. Alternatively, you may use an evaluation license. See the Intersight Documentation for instructions on creating the API key. Please select "API key for OpenAPI schema version 2".
If you are using the CLI, it's time to run ...
terraform init
terraform plan
terraform apply
Or, if you are using Terraform Cloud, just click the "Actions" dropdown in your workspace and click "Start New Plan".
The right place for this code is in the lab. It’s a solid choice to stand up an environment where further code will be developed. It could be useful for Proof-of-Concept type activities or demonstrations.
The next logical place to go from here is something much more modular. More complexity, more variables, more processed inputs, more reusable code. More ready for production.
I would have to recommend that you take a look at terraform-intersight-easy-imm for a more modular approach to the same tasks.
And the other repos available from this org on GitHub.
And other Terraform code from the Code Exchange at Cisco DEVNET.