Showing posts with label terraform. Show all posts
Showing posts with label terraform. Show all posts

Tuesday, 23 February 2021

Introduction to Terraform and ACI – Part 5

If you haven’t already seen the Introduction to Terraform posts, please have a read through. Here are links to the first four posts:

1. Introduction to Terraform

2. Terraform and ACI​​​​​​​

3. Explanation of the Terraform configuration files

4. Terraform Remote State and Team Collaboration

So far we’ve seen how Terraform works, ACI integration, and remote state. Although not absolutely necessary, sometimes it’s useful to understand how the providers work in case you need to troubleshoot an issue.​​​​​​​ This section will cover at a high level how Terraform Providers are built, using the ACI provider as an example. 

Code Example

https://github.com/conmurphy/intro-to-terraform-and-aci-remote-backend.git

For explanation of the Terraform files see Part 3 of the series. The backend.tf file will be added in the current post.

Lab Infrastructure

You may already have your own ACI lab to follow along with however if you don’t you might want to use the ACI Simulator in the Devnet Sandbox.

ACI Simulator AlwaysOn – V4

Terraform File Structure

As we previously saw, Terraform is split into two main components, Core and Plugins. All Providers and Provisioners used in Terraform configurations are plugins.  ​​​​

Data sources and resources exist within a provider and are responsible for the lifecycle management of the specific endpoint. For example we will have a look at the resource, “aci_bridge_domain“, which is responsible for creating and managing our bridge domains.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

The code for the Terraform ACI Provider can be found on Github


Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

There are a number of files in the root directory of this repo how the ones we are concerned with are “main.go“, the “vendor” folder, and the “aci” folder. 


◉ vendor: This folder contains all of the Go modules which will be imported and used by the provider plugin. The key module for this provider is the ACI Go SDK which is responsible for making the HTTP requests to APIC and returning the response.

◉ aci: This is the important directory where all the resources for the provider exist.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

Within the ACI  folder you’ll find a file called “provider.go“. This is a standard file in the Terraform providers and is responsible for setting the properties such as username, password, and URL of the APIC in this case.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

It’s also responsible for defining which resources are available to configure in the Terraform files, and linking them with the function which implements the Create, Read, Update, and Delete (CRUD) capability.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

In the aci folder you’ll also find all the data sources and resources available for this provider. Terraform has a specific structure for the filename and should start with data_source_ or resource_

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

Let’s look at the resource, “resource_aci_fvbd“, used to create bridge domains.

◉ On lines 10 and 11 the ACI Go SDK is imported. 
◉ The main function starts on line 16 and is followed by a standard Terraform configuration
    ◉ Lines 18 – 21 define which operations are available for this resource and which function should be called. We will see these four further down the page.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

◉ Lines 29 – 59 in the screenshot are setting the properties which will be available for the resource in the Terraform configuration files.

TROUBLESHOOTING TIP: This is an easy way to check exactly what is supported/configurable if you think the documentation for a provider is incorrect or incomplete. 

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

We’ve now reached the key functions in the file and these are responsible for implementing the changes. In our case creating, reading, updating, and destroying a bridge domain.

If you scroll up you can confirm that the function names match those configured on lines 18-21 

Whenever you run a command, e.g. “terraform destroy“, Terraform will call one of these functions. 

Let’s have a look at what it’s creating.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

First the ACI Go SDK has to be setup on line 419

Following on from that the values from your configuration files are retrieved so Terraform can take the appropriate action. For example in this screenshot the name we’ve configured, “bd_for_subnet“, will be stored in the variable, “name“. 

Likewise for the description, TenantDn, and all other bridge domain properties we’ve configured.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

Further down in the file you’ll see the ACI Go SDK is called to create a NewBridgeDomain. This object is then passed to a Save function in the SDK which makes a call to the APIC to create the bridge domain

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

Continuing down towards the end of the create function you’ll see the ID being set on line 726. Remember when Terraform manages a resource it keeps the state within the terraform.tfstate file. Terraform tracks this resource using the id, and in the case of ACI the id is the DistinguishedName.

Cisco Prep, Cisco Preparation, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Guide, Cisco Career

It’s not only the id that Terraform tracks though, all the other properties for the resource should also be available in the state file. To save this data there is another function, setBridgeDomainAttributes, which sets the properties in the state file with the values that were returned after creating/updating the resource. 

So when Terraform creates our bridge domain, it saves the response properties into the state file using this function.

TROUBLESHOOTING TIP: If resources are always created/updated when you run a terraform apply even though  you haven’t changed any configuration, you might want to check the state file to ensure that all the properties are being set correctly.

Source: cisco.com

Saturday, 20 February 2021

Introduction to Terraform with ACI – Part 4

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

If you haven’t already seen the Introduction to Terraform post, please have a read through. This section will cover the Terraform Remote Backend using Terraform Cloud.​​​​​​​

1. Introduction to Terraform

2. Terraform and ACI​​​​​​​

3. Explanation of the Terraform configuration files

Code Example

https://github.com/conmurphy/intro-to-terraform-and-aci-remote-backend.git

For explanation of the Terraform files see the following post. The backend.tf file will be added in the current post.

Lab Infrastructure

You may already have your own ACI lab to follow along with however if you don’t you might want to use the ACI Simulator in the Devnet Sandbox.

ACI Simulator AlwaysOn – V4

Terraform Backends

An important part of using Terraform is understanding where and how state is managed. In the first section Terraform was installed on my laptop when running the init, plan, and apply commands. A state file (terraform.tfstate) was also created in the folder in which I ran the commands. ​​​​​​​

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

It’s fine when learning and testing concepts however does not typically work well in shared/production environment. What happens if my colleagues also want to run these commands? Do they have their own separate state file?​​​​​​​

These questions can be answered with the concept of the Terraform Backend.

“A backend in Terraform determines how state is loaded and how an operation such as apply is executed. This abstraction enables non-local file state storage, remote execution, etc.


Here are some of the benefits of backends:

◉ Working in a team: Backends can store their state remotely and protect that state with locks to prevent corruption. Some backends such as Terraform Cloud even automatically store a history of all state revisions.

◉ Keeping sensitive information off disk: State is retrieved from backends on demand and only stored in memory. If you’re using a backend such as Amazon S3, the only location the state ever is persisted is in S3.

◉ Remote operations: For larger infrastructures or certain changes, terraform apply can take a long, long time. Some backends support remote operations which enable the operation to execute remotely. You can then turn off your computer and your operation will still complete. Paired with remote state storage and locking above, this also helps in team environments.”


Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

As you can see from the Terraform documentation, there are many backend options to choose from.

In this post we’ll setup the Terraform Cloud Remote backend.


Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

We will use the same Terraform configuration files as we saw in the previous posts, with the addition of the “backend.tf “ file. See the code examples above for a post explaining the various files.

For this example you will need to create a free account on the Terraform Cloud platform

◉ Create a new organization and provide it a name

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Create a new CLI Driven workspace

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Once created, navigate to the “General” page under “Settings”

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Change the “Execution Mode” to “Local”

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

You have two options with Terraform Cloud

◉ Remote Execution – Let Terraform Cloud maintain the state and run the plan and apply commands

◉ Local Execution – Let Terraform Cloud main the state but you run the plan and apply  commands on your local machine

In order to have Terraform Cloud run the commands you will either need public access to the endpoints or run an agent in your environment (similar to Intersight Assist configuring on premises devices)

Agents are available as part of the Terraform Cloud business plan. For the purposes of this post Terraform Cloud will manage the state while we will run the commands locally.

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Navigate back to the production workspace and you should see that the queue and variables tabs have been removed.

◉ Copy the example Terraform code and update the backend.tf file (the Terraform files can be found in the Github repo above)

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Navigate to the Settings link at the top of the page and then API Tokens

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Create an authentication token
◉ Copy the token
◉ On your local machine create a file (if it doesn’t already exist) in the home directory with the name .terraformrc
◉ Add the credentials/token information that was just create for your organization. Here is an example

CONMURPH:~$ cat ~/.terraformrc
credentials "app.terraform.io" {
  token="<ENTER THE TOKEN HERE> "
}

◉ You should now have the example Terraform files from the Github repo above, an updated backend.tf file with your organization/workspace, and a .terraformrc file with the token to access this organization
◉ Navigate to the folder containing the example Terraform files and your backend.tf file
◉ Run the terraform init command. If everything is correct you should see the remote backend initialised and the ACI plugin installed

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

◉ Run the terraform plan and terraform apply commands to apply to configuration changes.
◉ Once complete, if the apply is successful have a look at your Terraform Cloud organization.
◉ In the States tab you should now see the first version of your state file. When you look through this file you’ll see it’s exactly the same as the one you previously had on your local machine, however now it’s under the control of Terraform Cloud​​​​​​​
◉ Finally, if you want to collaborate with your colleagues, you can all run the commands locally and have Terraform Cloud manage a single state file. (May need to investigate locking depending on how you are managing the environment)

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Terraform, Cisco Preparation, Cisco Exam Prep, Cisco Learning, Cisco Guides

Source: cisco.com

Friday, 19 February 2021

Introduction to Terraform with ACI – Part 3

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

If you haven’t already seen the previous Introduction to Terraform posts, please have a read through. This “Part 3” will provide an explanation of the various configuration files you’ll see in the Terraform demo.

Introduction to Terraform

Terraform and ACI

Code Example

https://github.com/conmurphy/terraform-aci-testing/tree/master/terraform

Configuration Files

You could split out the Terraform backend config from the ACI config however in this demo it has been consolidated. 

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

config-app.tf

The name “myWebsite” in this example refers to the Terraform instance name of the “aci_application_profile” resource. 

The Application Profile name that will be configured in ACI is “my_website“. 

When referencing one Terraform resource from another, use the Terraform instance name (i.e. “myWebsite“).

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

config.tf

Only the key (name of the Terraform state file) has been statically configured in the S3 backend configuration. The bucket, region, access key, and secret key would be passed through the command line arguments when running the “terraform init” command. See the following for more detail on the various options to set these arguments.


Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

terraform.tfvars

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

variables.tf

We need to define the variables that Terraform will use in the configuration. Here are the options to provide values for these variables:

◉ Provide a default value in the variable definition below
◉ Configure the “terraform.tfvars” file with default values as previously shown
◉ Provide the variable values as part of the command line input

$terraform apply –var ’tenant_name=tenant-01’

◉ Use environmental variables starting with “TF_VAR“

$export TF_VAR_tenant_name=tenant-01

◉ Provide no default value in which case Terraform will prompt for an input when a plan or apply command runs

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

versions.tf

Cisco Developer, Cisco ACI, Cisco DevNet, Cisco Network Automation, Cisco Terraform, Cisco Preparation, Cisco Exam Prep

Source: cisco.com

Tuesday, 2 February 2021

Introduction to Terraform with ACI – Part 2

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

If you haven’t already seen Part 1 of this blog series, please have a read through. This section will cover ACI + Terraform, and we’ll include a couple of new topics – Terraform importing and data resources.

Read More: 200-901: Developing Applications and Automating Workflows using Cisco Core Platforms (DEVASC)  ​​​​​​​

1. Introduction to Terraform

2. Terraform and ACI​​​​​​​

3. Explanation of the Terraform configuration files

4. Terraform Remote State and Team Collaboration

5. Terraform Providers – How are they built?

Code Example

https://github.com/conmurphy/intro-to-terraform-and-aci

Lab Infrastructure

You may already have your own ACI lab to follow along with however if you don’t you might want to use the ACI Simulator in the DevNet Sandbox.

ACI Simulator AlwaysOn – V4

Terraform ACI Provider and Resources

As explained in the previous post, a Terraform provider is responsible for understanding API interactions and exposing resources.

A Terraform resource describes one or more infrastructure objects, for example in an ACI Tenant, EPG, Contract, BD.

This post will cover the ACI Terraform Provider which includes a large number of resources.

The full list of available resources can be found from the following link.

https://www.terraform.io/docs/providers/aci/index.html

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation
800

Terraform Resource vs Data Sources


Until now we’ve only looked at the provider resource, for example “aci_tenant”.

resource "aci_tenant" "my_terraform_tenant" {

  name        = "tenant_for_terraform"   
  description = "This tenant is created by the Terraform ACI provider"

}

Terraform also includes a concept known as data sources.

Data sources allow a Terraform configuration to make use of information defined outside of Terraform, or defined by another separate Terraform configuration.


It’s important to note that while resources are read/write, data sources are read only. This means we can include information in our configuration file for objects that we may not manage.

For example in the case of ACI, perhaps we want to manage our own app profiles and EPGs in a shared tenant however don’t want Terraform to have any control of the tenant itself.

We can define the shared elements (tenant, BD, VRF, contracts etc) as data sources (read only), and the ANP/EPGs as resources which will be created and deleted by Terraform.

provider "aci" {
  # cisco-aci user name
  username = "${var.username}"
  # cisco-aci password
  password = "${var.password}"
  # cisco-aci url
  url      =  "${var.apic_url}"
  insecure = true
}

data "aci_tenant" "my_shared_tenant" {
  name = "my_shared_tenant"
}

data "aci_bridge_domain" "my_shared_bd" {
  tenant_dn   = "${data.aci_tenant. my_shared_tenant.id}"
  name        = "my_shared_bd"
}

resource "aci_application_profile" "terraform_app" {
  tenant_dn = "${data.aci_tenant. my_shared_tenant.id}"
  name       = "demo_app_profile"
}

resource "aci_application_epg" "my_web_epg" {
    application_profile_dn  = "${aci_application_profile.terraform_app.id}"
    name                            = "db_epg"
    description                   = "%s"
    annotation                    = "tag_epg"
    exception_tag               = "0"
    flood_on_encap            = "disabled"
    fwd_ctrl                    = "none"
    has_mcast_source            = "no"
    is_attr_based_e_pg      = "no"
    match_t                         = "AtleastOne"
    name_alias                  = "alias_epg"
    pc_enf_pref                 = "unenforced"
    pref_gr_memb                = "exclude"
    prio                            = "unspecified"
    shutdown                    = "no"
  }

As you can see above we have defined two data sources (my_shared_tenant and my_shared_bd). These are then referenced in the aci_application_profile resource using the format, “${data.aci_tenant. my_shared_tenant.id}“.

Remember from the previous post that some properties such as IDs are computed behind the scenes without the need to hard code values.

NOTE: You’ll need to ensure that any data sources you’re referencing already exist in the ACI fabric. For example the bridge domain, “my_shared_bd”, already exists in the tenant, “my_shared_tenant” in our lab. If these data sources don’t already exists you will receive an error.

So using these two concepts we can build the desired configuration for our ACI fabric. Some Terraform ACI configuration has already been provided above and in the previous post. To help you get started the ACI Business Unit have created a large number of example configuration files which you can find from the following link.


Additionally, for any customer configuration you may want to create, the following document includes the entire list of available resources for the ACI provider.


These resources should give you a good start on your journey to managing ACI with Terraform.

But wait, there’s more! There are a couple of questions that are often asked in relation to the ACI provider.

◉ Is this only for greenfield deployments?
◉ Can I configure everything through Terraform?
◉ What happens if I manually configure ACI?

Importing With Terraform


ACI may already exist in many customer environments when they start to use Terraform. Alternatively, a customer new to ACI and Terraform may not want to learn both at the same time, choosing to first learn ACI and then migrate configuration to Terraform.

Luckily Terraform supports (for some providers) the importing of existing configuration to address these common scenarios.

terraform import


Remember there are two main files we’re working with, the configuration (.tf) and the state (terraform.tfstate) files.

Currently the “Terraform Import” command will only import what it learns about the existing infrastructure into the state (terraform.tfstate) file. It will not automatically append this into the configuration file.

This is a manual process you must complete.


Step 1 – Add the new resources to the configuration (.tf) file.

resource "aci_tenant" "myTenant" {
}

You only need to define the resource.

If you configure a property such as a name and then import from an existing resource, the values will be overwritten.

resource "aci_tenant" "myTenant" {
  name = “myTenant1”
}

In this example if the ACI tenant is named “myTenant”, when first importing Terraform will use “myTenant” in the state file. The configuration file is not updated on an import and therefore “myTenant1” will not be changed. Later when you run the apply command, Terraform will update the ACI fabric with the new name, “myTenant1”

Step 2 – Run the import command

Terraform identifies ACI objects with their Distinguished Name (Dn) and the Terraform resource ID is the absolute path of ACI object in the DMIT.

For example, the ID of an ACI tenant, myTenant, is uni/tn-myTenant. The ID of an ACI VRF, vrf1, in myTenant is uni/tn-myTenant/ctx-vrf1

The import command is used as follows:

terraform import <resource name> <resource id>

e.g terraform import aci_tenant.myTenant uni/tn-myTenant

We added the aci_tenant.myTenant resource to the configuration file in Step 1. This command is now assigning an ID, the ACI Tenant Dn (uni/tn-myTenant), to the resource and will also import existing configuration.

Step 3 – Repeat for all required resources

This used the ACI tenant as an example however you may also need to import other resources such as bridge domains, VRFs, EPGs, contract. You would repeat the steps above for each of these resources. First add them all as resources and then run the import command referencing the name of the resource and the ACI Dn as ID.

ACI REST Resource


There are many properties of ACI that can be configured, however not all exist as Terraform resources in the ACI provider. For this reason the aci_rest resource was created and allows you to configure ACI Objects through the REST API. Any Model Object that is not supported by the provider can be created/managed using this resource.

As a result, anything that can be configured through the ACI REST API can be configured and managed by Terraform. Either through a native resource (e.g. aci_tenant), or using the API (aci_rest resource).

Here’s an example of creating an L3Out.

resource "aci_rest" "rest_l3_ext_out" {
  path       = "/api/node/mo/${aci_tenant.tenant_for_rest_example.id}/out-test_ext.json"
  class_name = "l3extOut"​​​​​​​
  content = {
    "name" = "test_ext"
  }
}

These is the same configuration you would find in a Python script making raw calls to the ACI API, only this is wrapped in a Terraform resource.

Note as well that you can still reference existing variables or properties such as the aci_tenant id.


Config Drift


“What happens if someone manually configures a resource Terraform is managing?”

This is a common question not only for Terraform but anytime we are using external tools to manage infrastructure.

In the case of ACI we can test it out and see what happens.

Step 1 – First create a tenant, my_terraform_tenant, with the following description.

resource "aci_tenant" "my_terraform_tenant" {
  name        = "tenant_for_terraform"   
  description = "This tenant is created by the Terraform ACI provider"
}

Step 2 –  Login to the GUI and under the Tenant -> Policy, update the description.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Step 3 – Run the terraform plan command and see what will happen

You should see that one change will be made to reconfigure the tenant description.

This validates what we have previously learnt. Terraform will attempt to maintain consistency between the desired configuration (.tf files) and the current state (terraform.tfstate file) of the infrastructure. If it notices that the state has been changed (manually in our case), it will reconfigure the infrastructure.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation
800800

Modifying Attributes vs Resources


Be aware that the outcome above may not always be the same when working with Terraform and ACI. Let’s run another test and see what happens.

Step 1 – Create a tenant, BD, and subnet with the following configuration.​​​​​​​

resource "aci_tenant" "myTenant" {
  name        = "myTenant"   
}

resource "aci_bridge_domain" "bd_for_subnet" {
  tenant_dn   = "${aci_tenant.myTenant.id}"
  name        = "bd_for_subnet"
  description = "This bridge domain is created by the Terraform ACI provider"
}

resource "aci_subnet" "demosubnet" {
  bridge_domain_dn                    = "${aci_bridge_domain.bd_for_subnet.id}"
  ip                                  = "10.1.1.1/24"
  scope                               = "private"
  description                         = "This subject is created by Terraform"
}

Step 2 – Through the ACI GUI, create a new subnet in the same bridge domain. I’ve used 172.16.1.1/24 as an example.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Step 3 – Run the terraform plan again and have a look at the output. You shouldn’t see any changes.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Step 4 – Delete the 10.1.1.1/24 subnet from the bridge domain, keeping the new subnet.​​​​​​​​​​​​​​

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Step 5 – Run another plan and see the output. You should see that Terraform will add back the 10.1.1.1/24 subnet when applied. However it doesn’t know about the new subnet ,172.16.1.1/24, so this is left untouched.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

This means we again have two subnets on the bridge domain.

Why is this happening?

Terraform tracks resources by an ID and a name. When it notices that a property (e.g. description) in a resource (e.g. aci_tenant) has changed, it updates the infrastructure to match what is in the configuration file. This is what happened with the description. Note that the ID and name of the resource didn’t change, it was still the same ACI tenant.

If you’ve worked with ACI you’ll know that you can’t rename objects. This is inherent to how ACI stores information. All objects have a unique distinguished name and this name is used when connecting various objects together. You can see this in the configuration above where a subnet points to the distinguished name of the bridge domain in which it resides.

As also previously mentioned, the Terraform ACI provider uses the Dn as the ID for the resource.

In the case of ACI a subnet is an object with a distinguished name. Since we can’t edit the name (10.1.1.1/24) we need to delete it and recreate it with a different name (172.16.1.1/24). This results in a new object and Dn and therefore a new Terraform resource and ID.

However the old subnet resource (10.1.1.1/24) still exists in the Terraform state file, while the new one hasn’t been imported. As a result, Terraform re-implements the 10.1.1.1/24 subnet and nothing happens to the 172.16.1.1/24 subnet.​​​​​​​

If you update the subnet in the Terraform configuration file you’ll see that Terraform takes care of the “renaming”. It will first delete the old subnet and then recreate a new one, making it appear as though it has been renamed.

Cisco Prep, Cisco Tutorial and Material, Cisco Learning, Cisco Guides, Cisco Study Materials, Cisco Preparation

Final Thoughts


Terraform is an extremely powerful and flexible tool however as you’ve seen so far, there are cases that may result in unexpected behaviour. Like any deployment, it’s always best to understand how you will use Terraform in your environment. The ACI simulator is a great way to learn, test, and plan any changes you wish to make before pushing to production.

Source: cisco.com

Tuesday, 26 January 2021

Introduction to Terraform with Cisco ACI, Part 1

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Many customers are starting to look at third party tools such as Terraform and Ansible to deploy and manage their infrastructure and applications. In this five-part series we’ll introduce Terraform and understand how it’s used with Cisco products such as ACI. Over the coming weeks this blog series will cover:

1. Introduction to Terraform

2. Terraform and ACI​​​​​​​

3. Explanation of the Terraform configuration files

4. Terraform Remote State and Team Collaboration

5. Terraform Providers – How are they built?

Code Example

https://github.com/conmurphy/intro-to-terraform-and-aci 

​​​​​​Infrastructure as Code

Before diving straight in, let’s quickly explore the category of tool in which Terraform resides, Infrastructure as Code (IaC). Rather than directly configuring devices through CLI or GUI, IaC is a way of describing the desired state with text files. These text files are read by the IaC tool (e.g. Terraform) which implements the required configuration.

Imagine a sysadmin needs to configure their VCenter/ESXi cluster including data centres, clusters, networks, and VMs. One option would be to click through the GUI to configure each of the required settings. Not only does this take time, but also may introduce configuration drift as individual settings are configured over the lifetime of the platform.

Recording the desired configuration settings in a file and using an IaC tool eliminates the need to click through a GUI, thus reducing the time to deployment.

Additionally, the tool can monitor the infrastructure (e.g Vcenter) and ensure the desired configuration in the file matches the infrastructure.

Here are a couple of extras benefits provided by Infrastructure as Code:

  • Reduced time to deployment
    • See above
    • Additionally, infrastructure can quickly be re-deployed and configured if a major error occurs.
  • Eliminate configuration drift
    • See above
  • Increase team collaboration
    • Since all the configuration is represented in a text file, colleagues can quickly read and understand how the infrastructure has been configured
  • Accountability and change visibility
    • Text files describing configuration can be stored using version control software such as Git, along with the ability to view the config differences between two versions.
  • Manage more than a single product
    • Most, if not all, IaC tools would work across multiple products and domains, providing you the above mentioned benefits from a single place.

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.

There are a couple of components of Terraform which we will now walk through.

Configuration Files

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

When you run commands Terraform will search through the current directory for one or multiple configuration files. These files can either be written in JSON (using the extension .tf.json), or in the Hashicorp Configuration Language (HCL) using the extension .tf.​​​​​​​

The following link provides detailed information regarding Terraform configuration files.


As an example, here is a basic configuration file to configure an ACI Tenant, Bridge Domain, and Subnet.

provider "aci" {
  # cisco-aci user name
  username = "${var.username}"
  # cisco-aci password
  password = "${var.password}"
  # cisco-aci url
  url      =  "${var.apic_url}"
  insecure = true
}

resource "aci_tenant" "terraform_tenant" {
  name        = "tenant_for_terraform"   
  description = "This tenant is created by the Terraform ACI provider"
}

resource "aci_bridge_domain" "bd_for_subnet" {
  tenant_dn   = "${aci_tenant.terraform_tenant.id}"
  name        = "bd_for_subnet"
  description = "This bridge domain is created by the Terraform ACI provider"
}

resource "aci_subnet" "demosubnet" {
  bridge_domain_dn                    = "${aci_bridge_domain.bd_for_subnet.id}"
  ip                                  = "10.1.1.1/24"
  scope                               = "private"
  description                         = "This subject is created by Terraform"

When Terraform runs (commands below), the ACI fabric will be examined to confirm if the three resources (Tenant, BD, subnet) and their properties match what is written in the configuration file.

If everything matches no changes will be made.

When there is a difference between the config file and ACI fabric, for example the subnet does not already exist in ACI, Terraform will configure a new subnet within the BD. Since the Tenant and BD already exist in ACI, no changes will be made to these objects.

Cross checking the configuration file against the resources (e.g. ACI fabric), reduces the amount of configuration drift since Terraform will create/update/delete the infrastructure to match what’s written in the config file.​​​​​​​

Resources and Providers


Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

A provider is responsible for understanding API interactions and exposing resources. Providers generally are an IaaS (e.g. Alibaba Cloud, AWS, GCP, Microsoft Azure, OpenStack), PaaS (e.g. Heroku), or SaaS services (e.g. Terraform Cloud, DNSimple, Cloudflare), however the ones that we’ll be looking at are Cisco ACI and Intersight.

Resources exist within a provider.

A Terraform resource describes one or more infrastructure objects, for example in an ACI Tenant, EPG, Contract, BD.

A resource block in a .tf config file declares a resource of a given type e.g. (“aci_tenant”) with a given local name (“my_terraform_tenant “). The local name can then be referenced elsewhere in the configuration file.

The properties of the resource are specified within the curly braces of the resource block.

Here is an ACI Tenant resource as example.

resource "aci_tenant" "my_terraform_tenant" {
  name        = "tenant_for_terraform"   
  description = "This tenant is created by the Terraform ACI provider"
}

To create a bridge domain within this ACI tenant we can use the resource, aci_bridge_domain, and provide the required properties.

resource "aci_bridge_domain" "my_terraform_bd" {
  tenant_dn   = "${aci_tenant.my_terraform_tenant.id}"
  name        = "bd_for_subnet"
  description = "This bridge domain is created by the Terraform ACI provider"
}

Since a BD exists within a tenant in ACI, we need to link both resources together.

In this case the BD resource can reference a property of the Tenant resource by using the format, “${terraform_resource.given_name_of_resource.property}”

This makes it very easy to connect resources within Terraform configuration files.

Variables and Properties


As we’ve just learnt resources can be linked together using the format, “${}”. When we need to receive input from the user you can use input variables as described in the following link.


For many resources computed values such as an ID are also available. These are not hard coded in the configuration file but provided by the infrastructure.

They can be accessed in the same way as previously demonstrated. Note that in the following example the ID property is not hard coded in the aci_tenant resource, however this is referenced in the aci_bridge_domain resource. This ID was computed behind the scenes when the tenant was created and made available to any other resource that needs it. ​​​​​​​

resource "aci_tenant" "my_terraform_tenant" {
  name        = "tenant_for_terraform"   
  description = "This tenant is created by the Terraform ACI provider"
}

resource "aci_bridge_domain" "my_terraform_bd" {
  tenant_dn   = "${aci_tenant.my_terraform_tenant.id}"
  name        = "bd_for_subnet"
}

State Files

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

In order for Terraform to know what changes need to be made to your infrastructure, it must keep track of the environment. This information is stored by default in a local file named “terraform.tfstate“

NOTE: It’s possible to move the state file to a central location and this will be discussed in a later post

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

As you can see from examining this file Terraform keeps a record of how your infrastructure should be configured. When you run the plan or apply command, your desired config (.tf files) will be cross checked against the current state (.tfstate file) and the difference calculated.

For example if a subnet exists within the config.tf file but not within the terraform.tfstate will configure a new subnet in ACI and update terraform.tfstate.

The opposite is also true. If the subnet exists in terraform.tfstate but not within the config.tf file, Terraform assumes this configuration is not required and will delete the subnet from ACI.

This is a very important point and can result in undesired behaviour if your terraform.tfstate file was to change unexpectedly for some reason.

Here’s a great real world example. ​​​​​​​


Commands


There are many Terraform commands available however the key ones you should know about are as follows:

terraform init


Initializes a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. It is safe to run this command multiple times.

During init, Terraform searches the configuration for both direct and indirect references to providers and attempts to load the required plugins.

This is important when using the Cisco infrastructure providers (ACI and Intersight)

NOTE: For providers distributed by HashiCorp, init will automatically download and install plugins if necessary. Plugins can also be manually installed in the user plugins directory, located at ~/.terraform.d/plugins on most operating systems and %APPDATA%\terraform.d\plugins on Windows.

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

terraform plan


Used to create an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are necessary to achieve the desired state specified in the configuration files.

This command is a convenient way to check whether the execution plan for a set of changes matches your expectations without making any changes to real resources or to the state. For example, terraform plan might be run before committing a change to version control, to create confidence that it will behave as expected.


Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

terraform apply


The terraform apply command is used to apply the changes required to reach the desired state of the configuration, or the pre-determined set of actions generated by a terraform plan execution plan.

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

terraform destroy


Infrastructure managed by Terraform will be destroyed. This will ask for confirmation before destroying.

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Cisco Exam Prep, Cisco Prep, Cisco Preparation, Cisco Certification, Cisco Learning, Cisco Guides, Cisco Tutorial and Material, Cisco Study Material

Source: cisco.com