All Projects → johandry → Terranova

johandry / Terranova

Licence: apache-2.0
Using Terraform package from Go

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Labels

Projects that are alternatives of or similar to Terranova

Kaos
open source platform for simplifying machine learning deployment
Stars: ✭ 87 (-16.35%)
Mutual labels:  terraform
Vaultron
🤖 Vault clusters Terraformed onto Docker for great fun and learning!
Stars: ✭ 96 (-7.69%)
Mutual labels:  terraform
Aws Minikube
Single node Kubernetes instance implemented using Terraform and kubeadm
Stars: ✭ 101 (-2.88%)
Mutual labels:  terraform
Terraform Provider Tls
Provides utilities for working with Transport Layer Security keys and certificates. It provides resources that allow private keys, certificates and certficate requests to be created as part of a Terraform deployment.
Stars: ✭ 88 (-15.38%)
Mutual labels:  terraform
My Cheat Sheets
A place to keep all my cheat sheets for the complete development of ASIC/FPGA hardware or a software app/service.
Stars: ✭ 94 (-9.62%)
Mutual labels:  terraform
Terraform Provider Matchbox
Terraform provider for Matchbox on-premise / bare-metal provisioning
Stars: ✭ 100 (-3.85%)
Mutual labels:  terraform
Terraform Landscape
Improve Terraform's plan output to be easier to read and understand
Stars: ✭ 1,263 (+1114.42%)
Mutual labels:  terraform
Control Tower
Deploy and operate Concourse CI in a single command
Stars: ✭ 105 (+0.96%)
Mutual labels:  terraform
Terraform Import Github Organization
Script to fully automate Terraform import of Github Org (teams, users, and repos)
Stars: ✭ 95 (-8.65%)
Mutual labels:  terraform
Terraform Provider Postgresql
As part of our introduction to self-service publishing in the Terraform Registry, this copy of the provider has been archived, and ownership has been transferred to active maintainers in the community. Please see the new location on the Terraform Registry: https://registry.terraform.io/providers/cyrilgdn/postgresql
Stars: ✭ 101 (-2.88%)
Mutual labels:  terraform
Learning Tools
A collection of tools and files for learning new technologies
Stars: ✭ 1,287 (+1137.5%)
Mutual labels:  terraform
Terraform Provider Google
Terraform Google Cloud Platform provider
Stars: ✭ 1,318 (+1167.31%)
Mutual labels:  terraform
Terraform Provider Namecheap
Terraform provider for Namecheap
Stars: ✭ 101 (-2.88%)
Mutual labels:  terraform
Clarity
A declaritive test framework for Terraform
Stars: ✭ 88 (-15.38%)
Mutual labels:  terraform
Kapitan
Generic templated configuration management for Kubernetes, Terraform and other things
Stars: ✭ 1,383 (+1229.81%)
Mutual labels:  terraform
Terraform Aws Rabbitmq
Terraform configuration for creating RabbitMQ cluster on AWS.
Stars: ✭ 86 (-17.31%)
Mutual labels:  terraform
Cobalt
Infrastructure turn-key solution for app service workloads
Stars: ✭ 97 (-6.73%)
Mutual labels:  terraform
Terraform Provider Linode
Terraform Linode provider
Stars: ✭ 105 (+0.96%)
Mutual labels:  terraform
Typhoon
Minimal and free Kubernetes distribution with Terraform
Stars: ✭ 1,397 (+1243.27%)
Mutual labels:  terraform
Blast Radius
Interactive visualizations of Terraform dependency graphs using d3.js
Stars: ✭ 1,376 (+1223.08%)
Mutual labels:  terraform

Actions Status Build Status codecov GoDoc License

Terranova

terranova

Terranova is a Go package that allows you to easily use the Terraform Go Packages instead of executing the Terraform binary. The version v0.0.2 of Terranova works with Terraform version v0.12.17.

For more information about Terranova and how to use use it, refer to the blog post Terranova: Using Terraform from Go.

How to use the Terranova package

Terranova works better as a Go module, if you don't have a go.mod file in your project, create it with go mod init [package full name]. Import Terranova in the Go code:

import (
  "github.com/johandry/terranova"
)

As soon as you execute a Go command such as go build, go test or go mod tidy it will be included in your go.mod file and downloaded.

If you are not using modules yet, using vendors or having the packages in $GOPATH, please, git clone the repository and create the vendor directory:

mkdir -p $GOPATH/src/github.com/johandry/
cd $GOPATH/src/github.com/johandry/
git clone --depth=1 https://github.com/johandry/terranova.git
GO111MODULE=on go mod vendor

After having the package, the high level use of Terranova is like follows:

  1. Create a Platform instance with the Terraform code to apply
  2. Add to the go.mod file, import and add (AddProvider()) the Terraform Provider(s) used in the code
  3. Add to the go.mod file, import and add (AddProvisioner()) the Terraform Provisioner (if any) used in the Terraform code.
  4. Add (Var() or BindVars()) the variables used in the Terraform code.
  5. (optional) Create (NewMiddleware()) a logger middleware with the default logger or a custom logger that implements the Logger interface.
  6. (optional) Create your custom Terraform Hooks and assign them to the Platform instance.
  7. Load the previous state of the infrastructure and keep it updated using PersistStateToFile().
  8. Apply the changes using the method Apply().

The following example shows how to create, scale or terminate AWS EC2 instances:

package main

import (
  "log"
  "os"

  "github.com/johandry/terranova"
  "github.com/johandry/terranova/logger"
  "github.com/terraform-providers/terraform-provider-aws/aws"
)

var code string

const stateFilename = "simple.tfstate"

func main() {
  count := 0
  keyName := "demo"

  log := log.New(os.Stderr, "", log.LstdFlags)
  logMiddleware := logger.NewMiddleware()
  defer logMiddleware.Close()

  platform, err := terranova.NewPlatform(code).
    SetMiddleware(logMiddleware).
    AddProvider("aws", aws.Provider()).
    Var("c", count).
    Var("key_name", keyName).
    PersistStateToFile(stateFilename)

  if err != nil {
    log.Fatalf("Fail to create the platform using state file %s. %s", stateFilename, err)
  }

  terminate := (count == 0)
  if err := platform.Apply(terminate); err != nil {
    log.Fatalf("Fail to apply the changes to the platform. %s", err)
  }
}

func init() {
  code = `
  variable "c"    { default = 2 }
  variable "key_name" {}
  provider "aws" {
    region        = "us-west-2"
  }
  resource "aws_instance" "server" {
    instance_type = "t2.micro"
    ami           = "ami-6e1a0117"
    count         = "${var.c}"
    key_name      = "${var.key_name}"
  }
`
}

Read the same example at terranova-examples/aws/simple/main.go and the blog post Terranova: Using Terraform from Go for a detail explanation of the code.

The git repository terranova-examples contain more examples of how to use Terranova with different clouds or providers.

Providers version

Terranova works with the latest version of Terraform (v0.12.12) but requires Terraform providers using the Legacy Terraform Plugin SDK instead of the newer Terraform Plugin SDK. If the required provider still uses the Legacy Terraform Plugin SDK select the latest release using the Terraform Plugin SDK. For more information read the Terraform Plugin SDK page in the Extending Terraform documentation.

These are the latest versions supported for some providers:

  • AWS: github.com/terraform-providers/terraform-provider-aws v1.60.1-0.20191003145700-f8707a46c6ec
  • OpenStack: github.com/terraform-providers/terraform-provider-openstack v1.23.0
  • vSphere: github.com/terraform-providers/terraform-provider-vsphere v1.13.0
  • Azure: github.com/terraform-providers/terraform-provider-azurerm v1.34.0
  • Null: github.com/terraform-providers/terraform-provider-null v1.0.1-0.20190430203517-8d3d85a60e20
  • Template: github.com/terraform-providers/terraform-provider-template v1.0.1-0.20190501175038-5333ad92003c
  • TLS: github.com/terraform-providers/terraform-provider-tls v1.2.1-0.20190816230231-0790c4b40281

Include the code line in the require section of your go.mod file for the provider you are importing, for example:

require (
  github.com/hashicorp/terraform v0.12.12
  github.com/johandry/terranova v0.0.3
  github.com/terraform-providers/terraform-provider-openstack v1.23.0
  github.com/terraform-providers/terraform-provider-vsphere v1.13.0
)

If you get an error for a provider that you are not directly using (i.e. TLS provider) include the required version in the replace section of the go.mod file, for example:

replace (
  github.com/terraform-providers/terraform-provider-tls => github.com/terraform-providers/terraform-provider-tls v1.2.1-0.20190816230231-0790c4b40281
)

If the required provider is not in this list, you can identify the version like this:

  1. Go to the GitHub project of the provider
  2. Locate the provider.go file located in the directory named like the provider name (i.e. was/provider.go)
  3. If the file imports terraform-plugin-sdk/terraform go to the previous git tag.
  4. Repeat step #3 until you find the latest tag importing terraform/terraform (i.e. the latest tag for AWS is v2.31.0)
  5. If the tag can be used in the go.mod file, just include it after the module name, for example: terraform-provider-vsphere v1.13.0
  6. If the tag cannot be used in the go.mod file, for example v2.31.0 for AWS:
    1. Find the release generated from the git tag (i.e. v2.31.0)
    2. Locate the hash number assigned to the release (i.e. f8707a4)
    3. Include the number in the go.mod file and execute go mod tidy or any other go command such as go test or go build.

If this is not working and need help to identify the right version, open an issue and you'll be help as soon as possible.

Logs

Using Terranova without a Log Middleware cause to print to Stderr all the Terraform logs, a lot, a lot of lines including traces. This may be uncomfortable or not needed. To discard the Terraform logs or filter them (print only the required log entries) you have to use the Log Middleware and (optionally) a custom Logger.

To create a Log Middleware use:

logMiddleware := logger.NewMiddleware()
defer logMiddleware.Close()

...

platform.SetMiddleware(logMiddleware)

You can decide when the Log Middleware starts intercepting the standard log with logMiddleware.Start(), if you don't the Log Middleware will start intercepting every line printed by the standard log when Terranova execute an action that makes Terraform to print something to the standard log. Every line intercepted by the Log Middleware is printed by the provided logger. This hijack ends when the Log Middleware is closed. To make the platform use the middleware, add it with SetMiddleware() to the platform.

A logger is an instance of the interface Logger. If the Log Middleware is created without parameter the default logger will be used, it prints the INFO, WARN and ERROR log entries of Terraform. To create your own logger check the examples in the Terranova Examples repository.

IMPORTANT: It's recommended to create your own instance of log to not use the standard log when the Log Middleware is in use. Everything that is printed using the standard log will be intercepted by the Log Middleware and processed by the Logger. So, use your own custom log or do something like this before creating the Log Middleware:

log := log.New(os.Stderr, "", log.LstdFlags)
...
log.Printf("[DEBUG] this line is not captured by the Log Middleware")

Sources

All this research was done reading the Terraform documentation and source code.

Please, feel free to comment, open Issues and Pull Requests, help us to improve Terranova.

Contribute and Support

A great way to contribute to the project is to send a detailed report when you encounter an issue/bug or when you are requesting a new feature. We always appreciate a well-written, thorough bug report, and will thank you for it!

The GitHub issue tracker is for bug reports and feature requests. If you already forked and modified Terranova with a new feature or fix, please, open a Pull Request at GitHub

General support can be found at Gopher's Slack #terraform channel or message me directly @johandry

Stars over time

Stargazers over time

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].