starhawking / python-terrascript

Create Terraform files using Python scripts.
BSD 2-Clause "Simplified" License
516 stars 76 forks source link

Terrascript doesn't support multiple providers properly #74

Closed tkocemba closed 5 years ago

tkocemba commented 5 years ago

I run slightly modified example

from terrascript import Terrascript, provider, module
from terrascript.aws.r import aws_instance

ts = Terrascript()

aws_main = provider('aws', access_key='ACCESS_KEY_HERE',
               secret_key='SECRET_KEY_HERE', region='us-east-1')

aws_dr = provider('aws', alias="recovery", access_key='ACCESS_KEY_HERE',
               secret_key='SECRET_KEY_HERE', region='us-west-1')

ts += aws_main
ts += aws_dr

inst = ts.add(module('example',
                     source="git@github.com:repoorg/repo-name?ref=v0.1.2//modules/resource_group",
                     providers={
                         "aws": aws_main,
                         "aws_dr": aws_dr
                     },
                     instance_type='t2.micro')

              )

# Print the JSON-style configuration to stdout.
print(ts.dump())

and library generated following output

{
   "module": {
     "example": {
       "instance_type": "t2.micro",
       "providers": {
         "aws": "provider.__DEFAULT__",
         "aws_dr": "provider.recovery"
       },
       "source": "git@github.com:repoorg/repo-name?ref=v0.1.2//modules/resource_group"
     }
   },
   "provider": {
     "aws": {
       "__DEFAULT__": {
         "access_key": "ACCESS_KEY_HERE",
         "region": "us-east-1",
         "secret_key": "SECRET_KEY_HERE"
       },
       "recovery": {
         "access_key": "ACCESS_KEY_HERE",
         "alias": "recovery",
         "region": "us-west-1",
         "secret_key": "SECRET_KEY_HERE"
       }
     }
   }
 }

structure for providers is not proper, references passed to module cannot be found. Its problematic because we intensively uses modules and multiple providers. Expected output is described here https://github.com/hashicorp/terraform/pull/2015

Cheers, Tomek

nielsonsantana commented 5 years ago

Hi @tkocemba. I think that this thread https://github.com/hashicorp/terraform/pull/2015 is for describe multiples providers. Not for use theses multiples provides in a resource/module. Based on terraform documentation(Resources, Providers), is possible use only one provider per resource. Here a example:


from terrascript import Terrascript
from terrascript import provider
from terrascript.aws.r import aws_instance

ts = Terrascript()

AWS_REGION_LIST = [
    'us-east-1',
    'ap-southeast-1',
    'eu-central-1',
]

aws_providers_map = {}
for _region in AWS_REGION_LIST:
    _provider = ts.add(provider(
        'aws',
        version="~> 1.38",
        access_key='AWS_ACCESS_KEY',
        secret_key='AWS_SECRET_KEY',
        region=_region,
        alias=_region,
    ))
    aws_providers_map[_region] = _provider

# Default Provider
ts.add(provider(
    'aws',
    version="~> 1.38",
    access_key='AWS_ACCESS_KEY',
    secret_key='AWS_SECRET_KEY',
    region='us-east-1',
))

instance_example1 = ts.add(aws_instance(
    'example2', ami='ami-2757f631', instance_type='t2.micro',
    provider=aws_providers_map['us-east-1'].id,
))

print(ts.dump())

Output:

{
  "provider": {
    "aws": {
      "__DEFAULT__": {
        "access_key": "AWS_ACCESS_KEY",
        "region": "us-east-1",
        "secret_key": "AWS_SECRET_KEY",
        "version": "~> 1.38"
      },
      "ap-southeast-1": {
        "access_key": "AWS_ACCESS_KEY",
        "alias": "ap-southeast-1",
        "region": "ap-southeast-1",
        "secret_key": "AWS_SECRET_KEY",
        "version": "~> 1.38"
      },
      "eu-central-1": {
        "access_key": "AWS_ACCESS_KEY",
        "alias": "eu-central-1",
        "region": "eu-central-1",
        "secret_key": "AWS_SECRET_KEY",
        "version": "~> 1.38"
      },
      "us-east-1": {
        "access_key": "AWS_ACCESS_KEY",
        "alias": "us-east-1",
        "region": "us-east-1",
        "secret_key": "AWS_SECRET_KEY",
        "version": "~> 1.38"
      }
    }
  },
  "resource": {
    "aws_instance": {
      "example2": {
        "ami": "ami-2757f631",
        "instance_type": "t2.micro",
        "provider": "${provider.aws.us-east-1.id}"
      }
    }
  }
}
mjuenema commented 5 years ago

@tkocemba do you have a working example in Terraform HCL language?

mjuenema commented 5 years ago

@tkocemba @nielsonsantana I think this is similar to this: https://www.terraform.io/docs/configuration/modules.html#passing-providers-explicitly

tkocemba commented 5 years ago

Hey,

Sorry for updating sooner, busy with current task. Thanks for this link this is exactly how we use it. Its best practice to pass providers to module.