user389955
user389955

Reputation: 10487

Terraform: how to support different providers

I have a set of terraform codes in a directory called myproject:

\myproject\ec2.tf
\myproject\provider.tf
\myproject\s3.tf
      ....

the provider.tf shows:

provider "aws" {
  region  = "us-west-1"
  profile = "default"
}

so, if I terraform apply in myproject folder, a set of aws resources are launched in us-west-1 under my account.

Now I want to introduce a AWS Glue resource, which is only available in a different region us-west-2. then how do I layout glue.tf file?

Currently I store it in a sub-directory under myproject and run terraform apply in that sub-directory i.e.

\myproject\glue\glue.tf
\myproject\glue\another_provider.tf

another_provider.tf is:

provider "aws" {
  region  = "us-west-2"
  profile = "default"
}

Is it the only way to store a file launching resources in different regions? any better way?

If there is no better way, then I need to have another backend file in glue sub-folder as well, besides, some common variables in myproject directory cannot be shared.

--------- update: I followed the link posted by Phuong Nguyen,

provider "aws" {
  region  = "us-west-1"
  profile = "default"
}

provider "aws" {
  alias  = "oregon"
  region = "us-west-2"
  profile = "default"
}

resource "aws_glue_connection" "example" {
  provider = "aws.oregon"
   ....
}

But I saw:

Error: aws_glue_connection.example: Provider doesn't support resource:     aws_glue_connection

Upvotes: 1

Views: 2064

Answers (2)

Yordan Georgiev
Yordan Georgiev

Reputation: 5460

Read my comment ...

Which basically means that you should keep out aws profiles and regions and what not from your terraform code as much as possible and use them as configuration as follows:

terraform {
    required_version = "1.0.1"

    required_providers {
      aws = {
        version = ">= 3.56.0"
        source  = "hashicorp/aws"
      }
    }

    backend "s3" {}
  }

  provider "aws" {
    region  = var.region
    profile = var.profile
  }

Than use tfvars configuration files:

  cat cnf/env/spe/prd/tf/03-static-website.backend-config.tfvars

  profile        = "prd-spe-rcr-web"
  region         = "eu-north-1"
  bucket         = "prd-bucket-spe"
  foobar         = "baz"

  

which you will apply during the terraform plan and apply calls as follows:

    terraform -chdir=$tf_code_path plan -var-file=<<line-one-^^^>>.tfvars 

    terraform -chdir=$tf_code_path plan -var-file=<<like-the-one-^^^>>.tfvars -auto-approve

As a rule of thumb you SHOULD separate your code and configuration always, the more mixed they are the deeper you will get into troubles ... this applies to ANY programming language / project etc. Now some wise heads will argue that terraform code is in itself configuration , but no it is not. The terraform code in your application is the declarative source code, which is used to provision your binary infrastructure used by the application source code etc. in your application ...

Upvotes: 1

Phuong Nguyen
Phuong Nguyen

Reputation: 3090

you can use provider alias to define multiple providers, .e.g.

# this is default provider
provider "aws" {
  region  = "us-west-1"
  profile = "default"
}

# additional provider
provider "aws" {
  alias  = "west-2"
  region  = "us-west-2"
  profile = "default"
}

and then in your glue.tf, you can refer to alias provider as:

resource "aws_glue_job" "example" {
  provider = "aws.west-2"

  # ...
}

More details at Multiple Provider Instances section: https://www.terraform.io/docs/configuration/providers.html

Upvotes: 2

Related Questions