In previous articles, I walked through how to use OneFuse Naming, IPAM, DNS, and Active Directory individually within a Terraform configuration. In this article, we are going to put them all together into one single Terraform configuration to provide access to all resources.
By the end of this article, we will have created a Terraform configuration that calls OneFuse and creates a name, reserves an IP address, creates a DNS record, and creates a computer object in Active Directory.
Before we begin, there are prerequisites you will want to have ready.
Prerequisites
- The OneFuse appliance should be deployed and configured, see the following articles if you need to walk through the OneFuse deployment and configuration.
- Terraform 0.13 or higher
Creating the Terraform Configuration
To begin we will need to initialize the OneFuse Terraform provider. To do this, we will need the following statement:
Provider Declaration
terraform {
required_providers {
onefuse = {
source = "CloudBoltSoftware/onefuse"
version = ">= 1.20.0"
}
}
required_version = ">= 0.13"
}
provider "onefuse" {
scheme = "https"
address = "onefuse_fqdn"
port = "443"
user = "admin"
password = "admin"
verify_ssl = "false"
}
The OneFuse Terraform provider is available in the Terraform Registry. By point to the source “CloudBoltSoftware/onefuse” Terraform will automatically download the OneFuse provider based on the required_version specified. In the example above, that will be v1.20.0 or higher.
Data Source
We will need to call data sources for all the modules that we will be using.
// OneFuse Data Source for IPAM Policy to lookup policy ID
data "onefuse_ipam_policy" "policy" {
name = "default"
}
// OneFuse Data Source for Naming Policy to lookup policy ID
data "onefuse_naming_policy" "policy" {
name = "default"
}
// OneFuse Data Source for AD Policy to lookup policy ID
data "onefuse_ad_policy" "policy" {
name = "default"
}
// OneFuse Data Source for DNS Policy to lookup policy ID
data "onefuse_dns_policy" "policy" {
name = "default"
}
Resource
Next, we need to create a resource for each of the OneFuse modules and configure them to work together.
// OneFuse Resource for Naming Record
resource "onefuse_naming" "name" {
naming_policy_id = data.onefuse_naming_policy.policy.id
template_properties = var.template_properties
}
// OneFuse Resource for AD
resource "onefuse_microsoft_ad_computer_account" "computer" {
name = onefuse_naming.name.name
policy_id = data.onefuse_ad_policy.policy.id
template_properties = var.template_properties
}
// OneFuse Resource for IPAM Record
resource "onefuse_ipam_record" "ipam-record" {
hostname = onefuse_naming.name.name
policy_id = data.onefuse_ipam_policy.policy.id
template_properties = var.template_properties
lifecycle {
ignore_changes = [
hostname,
dns_suffix
]
}
}
// OneFuse Resource for DNS Record
resource "onefuse_dns_record" "dns-record" {
name = onefuse_naming.name.name
policy_id = data.onefuse_dns_policy.policy.id
zones = [onefuse_naming.name.dns_suffix]
value = onefuse_ipam_record.ipam-record.ip_address
template_properties = var.template_properties
}
You will notice that the outputs of some resources are being fed into others. For example, onefuse_naming.name.name
is being fed into all the modules for the name of the resource being created.
You will also notice I did not individually put the template_properties
in for each resource, instead, I am referring to a variable located in a variables.tf
file. My template_properties
looks like the following:
variable "template_properties" {
type = map
default = {
"nameEnvironment" = "p"
"nameOS" = "w"
"nameApplication" = "ap"
"nameLocation" = "atl"
"nameCompliance" = "pci"
"ouEnvironment" = "production"
"ouApplication" = "pwordpress"
"ouLocation" = "Atlanta"
"dnsSuffix" = "company.com"
}
}
Output
If we want to see the outputs from Naming, IPAM, DNS and Active Directory, we add the following declarations to the configuration.
// Naming
output "hostname" {
value = onefuse_naming.name.name
}
output "fqdn" {
value = onefuse_naming.name.id
}
// IPAM
output "ip_address" {
value = onefuse_ipam_record.ipam-record.ip_address
}
// IPAM
output "netmask" {
value = onefuse_ipam_record.ipam-record.netmask
}
// IPAM
output "gateway" {
value = onefuse_ipam_record.ipam-record.gateway
}
// IPAM
output "network" {
value = onefuse_ipam_record.ipam-record.network
}
// IPAM
output "subnet" {
value = onefuse_ipam_record.ipam-record.subnet
}
// DNS
output "primary_dns" {
value = onefuse_ipam_record.ipam-record.primary_dns
}
// DNS
output "secondary_dns" {
value = onefuse_ipam_record.ipam-record.secondary_dns
}
// Active Directory
output "ad_ou" {
value = onefuse_microsoft_ad_computer_account.computer.final_ou
}
Putting it all together
Our completed plan, will look like the following:
terraform {
required_providers {
onefuse = {
source = "CloudBoltSoftware/onefuse"
version = ">= 1.20.0"
}
}
required_version = ">= 0.13"
}
// Inititalize OneFuse Provider
provider "onefuse" {
scheme = "https"
address = "onefuse.company.com"
port = "443"
user = "admin"
password = "admin"
verify_ssl = "false"
}
variable "template_properties" {
type = map
default = {
"nameEnvironment" = "p"
"nameOS" = "w"
"nameApplication" = "ap"
"nameLocation" = "atl"
"nameCompliance" = "pci"
"ouEnvironment" = "production"
"ouApplication" = "pwordpress"
"ouLocation" = "Atlanta"
"dnsSuffix" = "company.com"
}
}
// OneFuse Data Source for IPAM Policy to lookup policy ID
data "onefuse_ipam_policy" "policy" {
name = "default"
}
// OneFuse Data Source for Naming Policy to lookup policy ID
data "onefuse_naming_policy" "policy" {
name = "default"
}
// OneFuse Data Source for AD Policy to lookup policy ID
data "onefuse_ad_policy" "policy" {
name = "default"
}
// OneFuse Data Source for DNS Policy to lookup policy ID
data "onefuse_dns_policy" "policy" {
name = "default"
}
// OneFuse Resource for Naming Record
resource "onefuse_naming" "name" {
naming_policy_id = data.onefuse_naming_policy.policy.id
template_properties = var.template_properties
}
// OneFuse Resource for AD
resource "onefuse_microsoft_ad_computer_account" "computer" {
name = onefuse_naming.name.name
policy_id = data.onefuse_ad_policy.policy.id
template_properties = var.template_properties
}
// OneFuse Resource for IPAM Record
resource "onefuse_ipam_record" "ipam-record" {
hostname = onefuse_naming.name.name
policy_id = data.onefuse_ipam_policy.policy.id
template_properties = var.template_properties
lifecycle {
ignore_changes = [
hostname,
dnsSuffix
]
}
}
// OneFuse Resource for DNS Record
resource "onefuse_dns_record" "dns-record" {
name = onefuse_naming.name.name
policy_id = data.onefuse_dns_policy.policy.id
zones = [onefuse_naming.name.dns_suffix]
value = onefuse_ipam_record.ipam-record.ip_address
template_properties = var.template_properties
}
output "hostname" {
value = onefuse_naming.name.name
}
output "ip_address" {
value = onefuse_ipam_record.ipam-record.ip_address
}
output "netmask" {
value = onefuse_ipam_record.ipam-record.netmask
}
output "gateway" {
value = onefuse_ipam_record.ipam-record.gateway
}
output "network" {
value = onefuse_ipam_record.ipam-record.network
}
output "subnet" {
value = onefuse_ipam_record.ipam-record.subnet
}
output "primary_dns" {
value = onefuse_ipam_record.ipam-record.primary_dns
}
output "secondary_dns" {
value = onefuse_ipam_record.ipam-record.secondary_dns
}
output "fqdn" {
value = onefuse_naming.name.id
}
output "ad_ou" {
value = onefuse_microsoft_ad_computer_account.computer.final_ou
}
Applying the configuration
To apply this configuration we can perform the following:
- Init
terraform init
- Plan
terraform plan
- Apply
terraform apply
- If you login to the OneFuse UI, navigate to the Naming, IPAM, DNS, and Active Directory Modules you will see your newly created records in the Managed Object lists.
- Destroy
terraform destroy
Once destroyed you will see all the Managed Objects in OneFuse have been removed and the records no longer exist.
For example Terraform configurations, visit our onefuse-examples in our GitHub repo.
Want to try OneFuse with Terraform for yourself? Check out the WWT HOL Accelerating Terraform with OneFuse.