From d56ed5a5d2518293ba48418058443b81fd41a295 Mon Sep 17 00:00:00 2001 From: Pat Gavlin Date: Tue, 14 May 2024 09:34:55 -0700 Subject: [PATCH] Add ESC + Terraform guide (#4271) Add a page that explains how to integrate ESC with the Terraform CLI. --- .../docs/esc/other-integrations/_index.md | 3 +- .../docs/esc/other-integrations/terraform.md | 150 ++++++++++++++++++ .../aws-ec2-vpc-resources-go/go.mod.txt | 4 +- .../aws-iampolicy-jsonparse-go/go.mod.txt | 5 +- .../aws-s3-bucket-resources-go/go.mod.txt | 4 +- .../go.mod.txt | 4 +- .../go.mod.txt | 5 + 7 files changed, 164 insertions(+), 11 deletions(-) create mode 100644 themes/default/content/docs/esc/other-integrations/terraform.md create mode 100644 themes/default/static/programs/aws-simulated-server-interpolate-go/go.mod.txt diff --git a/themes/default/content/docs/esc/other-integrations/_index.md b/themes/default/content/docs/esc/other-integrations/_index.md index 6f7f6a81a4e..87977815db5 100644 --- a/themes/default/content/docs/esc/other-integrations/_index.md +++ b/themes/default/content/docs/esc/other-integrations/_index.md @@ -18,6 +18,7 @@ To learn how to configure common integrations, follow the links below. | Tool | Description | |---------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| | [Pulumi IaC](/docs/esc/get-started/integrate-with-pulumi-iac) | Pulumi IaC has builtin support for sourcing stack configuration from ESC environments. | -| [Direnv](/docs/esc/other-integrations/direnv) | Pulumi ESC can be integrated with Direnv to source environment variables, secrets, and configuration from ESC environments. | +| [Direnv](/docs/esc/other-integrations/direnv) | Pulumi ESC can integrate with Direnv to source environment variables, secrets, and configuration from ESC environments. | | [Docker](/docs/esc/other-integrations/docker) | Pulumi ESC can be used to configure environment variables, secrets, and configuration for Docker operations. | | [Kubernetes](/docs/esc/other-integrations/kubernetes) | Pulumi ESC can be used to connect to a Kubernetes cluster. | +| [Terraform](/docs/esc/other-integrations/terraform) | Pulumi ESC can integrate with the Terraform and OpenTofu CLIs to supply cloud credentials and input variables from ESC environments. | diff --git a/themes/default/content/docs/esc/other-integrations/terraform.md b/themes/default/content/docs/esc/other-integrations/terraform.md new file mode 100644 index 00000000000..09296441fcf --- /dev/null +++ b/themes/default/content/docs/esc/other-integrations/terraform.md @@ -0,0 +1,150 @@ +--- +title_tag: Integrate with Terraform | Pulumi ESC +title: Terraform +h1: "Pulumi ESC: Integrate with Terraform" +meta_desc: This page provides an overview on how to use Pulumi ESC with Terraform. +weight: 2 +menu: + pulumiesc: + parent: esc-other-integrations + identifier: esc-other-integrations-terraform +--- + +## Overview + +Pulumi ESC integrates with [Terraform](https://www.terraform.io) and [OpenTofu](https://opentofu.org) to help developers provision Terraform-managed infrastructure using centrally-managed, composable configuration and temporary credentials. + +## Prerequisites + +To complete the steps in this tutorial, you will need to install the following prerequisites: + +- the [Pulumi ESC CLI](/docs/esc-cli/) +- the [Terraform CLI](https://developer.hashicorp.com/terraform/install) + +{{% notes type="info" %}} +Although this guide is written for the Terraform CLI, OpenTofu users can also follow along by replacing the usage of the `terraform` commands with the equivalent `tofu` commands. In most cases, this is as simple as replacing `terraform` with `tofu`. +{{% /notes %}} + +## Create and initialize a Terraform workspace + +Create a directory to hold your infrastructure code, then copy and paste the following into a file named `main.tf`: + +```hcl +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.16" + } + } + + required_version = ">= 1.2.0" +} + +variable "instance_type" { + type = string +} + +variable "region" { + type = string +} + +provider "aws" { + region = var.region +} + +data "aws_ami" "amazon_linux_2" { + most_recent = true + owners = ["amazon"] + filter { + name = "name" + values = ["amzn2-ami-hvm*"] + } +} + +resource "aws_instance" "app_server" { + ami = data.aws_ami.amazon_linux_2.id + instance_type = var.instance_type + + tags = { + Name = "ESCExampleAppServer" + } +} +``` + +This sample code will create an EC2 instance running Amazon Linux 2. The instance's region and instance type are supplied by the user via [input variables](https://developer.hashicorp.com/terraform/language/values/variables). + +Once you have created your `main.tf` file, run `terraform init` to install the necessary Terraform providers: + +```bash +$ terraform init +``` + +## Create an ESC environment with Terraform variables + +ESC integrates with Terraform by exporting environment variables from an opened environment. These environment variables typically come in two flavors: those used by Terraform providers and those used to provide values for Terraform input variables. The former are specific to each Terraform provider, while the latter are of the form [`TF_VAR_`](https://developer.hashicorp.com/terraform/language/values/variables#environment-variables). + +For this guide, we'll create an environment that supplies both temporary credentials for the Terraform AWS provider as well as values for our confguration's `region` and `instance_type` input variables: + +```yaml +values: + # Fetch temporary AWS credentials via OIDC + aws: + login: + fn::open::aws-login: + oidc: + duration: 1h + roleArn: + sessionName: pulumi-environments-session + environmentVariables: + # Export AWS Credentials + AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId} + AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey} + AWS_SESSION_TOKEN: ${aws.login.sessionToken} + + # Export Terraform variables + TF_VAR_region: us-west-2 + TF_VAR_instance_type: t3.small +``` + +## Run Terraform + +Once you've created the example environment, you can now use the Terraform CLI with `esc run` to invoke Terraform with credentials and configuration: + +```bash +$ esc run -i -- terraform apply +``` + +This will open your ESC environment, export its environment variables, and then invoke `terraform apply` with those environment variables. The `-i` instructs `esc` to run in interactive mode, which is necessary for programs like the Terraform CLI that expect user input. + +## Run Terraform with `-var-file` + +While simple Terraform input variables work well with environment variables, it can be difficult to set variables with complex types (e.g. arrays, objects). If your Terraform input variables have complex types, you can use `-var-file` to supply their values. + +```yaml +values: + # Fetch temporary AWS credentials via OIDC + aws: + login: + fn::open::aws-login: + oidc: + duration: 1h + roleArn: + sessionName: pulumi-environments-session + files: + TFVARS: + fn::toJSON: + region: us-west-2 + instance_type: t3.small + environmentVariables: + # Export AWS Credentials + AWS_ACCESS_KEY_ID: ${aws.login.accessKeyId} + AWS_SECRET_ACCESS_KEY: ${aws.login.secretAccessKey} + AWS_SESSION_TOKEN: ${aws.login.sessionToken} +``` + +With this environment, the `esc` CLI will write the value of the `TFVARS` property to a temporary file, then export the path to that temporary file in the `TFVARS` environment variable. You can then pass the path to this file to the Terraform CLI. This is slightly more involved because the Terraform CLI requires that the contents of the vars file is either valid HCL or JSON, and JSON files must have a `.json` extension: + +```bash +$ esc run -i -- sh -c 'mv $TFVARS $TFVARS.json && terraform apply -var-file=$TFVARS.json' +``` diff --git a/themes/default/static/programs/aws-ec2-vpc-resources-go/go.mod.txt b/themes/default/static/programs/aws-ec2-vpc-resources-go/go.mod.txt index a21543113ec..fa450cf9861 100644 --- a/themes/default/static/programs/aws-ec2-vpc-resources-go/go.mod.txt +++ b/themes/default/static/programs/aws-ec2-vpc-resources-go/go.mod.txt @@ -5,6 +5,6 @@ go 1.21 toolchain go1.22.1 require ( - github.com/pulumi/pulumi-aws/sdk/v6 v6.29.1 - github.com/pulumi/pulumi/sdk/v3 v3.112.0 + github.com/pulumi/pulumi-aws/sdk/v6 v6.24.0 + github.com/pulumi/pulumi/sdk/v3 v3.108.1 ) diff --git a/themes/default/static/programs/aws-iampolicy-jsonparse-go/go.mod.txt b/themes/default/static/programs/aws-iampolicy-jsonparse-go/go.mod.txt index 973891a1226..a8b954c64ae 100644 --- a/themes/default/static/programs/aws-iampolicy-jsonparse-go/go.mod.txt +++ b/themes/default/static/programs/aws-iampolicy-jsonparse-go/go.mod.txt @@ -4,7 +4,4 @@ go 1.21 toolchain go1.22.1 -require ( - github.com/pulumi/pulumi-aws/sdk/v6 v6.24.0 - github.com/pulumi/pulumi/sdk/v3 v3.108.1 -) +require github.com/pulumi/pulumi/sdk/v3 v3.108.1 diff --git a/themes/default/static/programs/aws-s3-bucket-resources-go/go.mod.txt b/themes/default/static/programs/aws-s3-bucket-resources-go/go.mod.txt index cdeca74dea8..807f8b299b6 100644 --- a/themes/default/static/programs/aws-s3-bucket-resources-go/go.mod.txt +++ b/themes/default/static/programs/aws-s3-bucket-resources-go/go.mod.txt @@ -5,6 +5,6 @@ go 1.21 toolchain go1.22.1 require ( - github.com/pulumi/pulumi-aws/sdk/v6 v6.29.1 - github.com/pulumi/pulumi/sdk/v3 v3.112.0 + github.com/pulumi/pulumi-aws/sdk/v6 v6.24.0 + github.com/pulumi/pulumi/sdk/v3 v3.108.1 ) diff --git a/themes/default/static/programs/aws-s3-bucketpolicy-jsonstringify-go/go.mod.txt b/themes/default/static/programs/aws-s3-bucketpolicy-jsonstringify-go/go.mod.txt index 577645d6fb6..5ab3a2edfcd 100644 --- a/themes/default/static/programs/aws-s3-bucketpolicy-jsonstringify-go/go.mod.txt +++ b/themes/default/static/programs/aws-s3-bucketpolicy-jsonstringify-go/go.mod.txt @@ -5,6 +5,6 @@ go 1.21 toolchain go1.21.9 require ( - github.com/pulumi/pulumi-aws/sdk/v6 v6.29.1 - github.com/pulumi/pulumi/sdk/v3 v3.112.0 + github.com/pulumi/pulumi-aws/sdk/v6 v6.24.0 + github.com/pulumi/pulumi/sdk/v3 v3.108.1 ) diff --git a/themes/default/static/programs/aws-simulated-server-interpolate-go/go.mod.txt b/themes/default/static/programs/aws-simulated-server-interpolate-go/go.mod.txt new file mode 100644 index 00000000000..8607a8660e4 --- /dev/null +++ b/themes/default/static/programs/aws-simulated-server-interpolate-go/go.mod.txt @@ -0,0 +1,5 @@ +module aws-simulated-server-interpolate-go + +go 1.20 + +require github.com/pulumi/pulumi/sdk/v3 v3.102.0