starhawking / python-terrascript

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

terrascript.terraform class vs module? #43

Closed jbscare closed 4 years ago

jbscare commented 6 years ago

This may be a dumb question, but I can't figure out how to get it to work, so I figured I'd ask here.

I have a script like this:

#!/usr/bin/env python3

import terrascript

s3_backend = terrascript.backend(
    "s3",
    bucket = "mybucket",
    key = "my.tfstate",
    region = "us-east-1"
    )

ts = terrascript.Terrascript()
ts += terrascript.terraform(backend = s3_backend)

ts += terrascript.terraform.d.remote_state(
    "another",
    backend = "s3",
    config = {
        'bucket': "mybucket",
         'key': "another.tfstate",
        'region': "us-east-1"
        }
    )

If I run this, I get an error:

Traceback (most recent call last):
  File "terrascript-modules.py", line 15, in <module>
    ts += terrascript.terraform.d.remote_state(
AttributeError: type object 'terraform' has no attribute 'd'

At this point, terrascript.terraform is a class:

>>> terrascript.terraform
<class 'terrascript.terraform'>

If I add import terrascript.terraform.d, I get a different error:

Traceback (most recent call last):
  File "terrascript-modules.py", line 14, in <module>
    ts += terrascript.terraform(backend = s3_backend)
TypeError: 'module' object is not callable

At this point, terrascript.terraform is a module:

>>> terrascript.terraform
<module 'terrascript.terraform' from '/usr/local/lib/python3.5/dist-packages/terrascript/terraform/__init__.py'>

I've tried a bunch of different stuff, but can't figure it out. :^(

It seems like the problem is that terrascript.terraform is both a module and a class; if I rename the class to Terraform in .../terrascript/__init__.py, things seem to work.

Is there some other way to do this that I'm missing?

mjuenema commented 6 years ago

Hi @jbscare, sorry for the late response but I just moved house and started a new job. Unfortunately that leaves me with very little time for other things at the moment. I promise that I am going to look into this as soon as I can. Sorry!

jbscare commented 6 years ago

No worries -- hopefully the new house and job are both great, and we're still loving everything else about Terrascript meanwhile. :^ )

mjuenema commented 6 years ago

Sorry for the long wait. I hope I can find time this week to look into this...

mjuenema commented 5 years ago

Sorry, Josh, but I hadn't touched Terrascript for weeks - well, months! I am just about to release 0.6.0 which includes all merged pull requests. I am going to look into this problem for 0.6.1.

"It seems like the problem is that terrascript.terraform is both a module and a class; if I rename the class to Terraform in .../terrascript/init.py, things seem to work." - You are absolutely right there. I should probably rename it to upper-case. I have to admit I cannot remember why I named the classes in terrascript/__init__.py in lower case which does not follow PEP-8. It was probably for consistency with the naming conventions of the Terraform project. Let me sleep over it...

jbscare commented 5 years ago

No worries; we're still using it and loving it. :^ ) Whenever you get a chance. Thanks!

mjuenema commented 4 years ago

This will hopefully resolve with the changed directory layout where all providers are in the same module.

import terrascript.provider
p = terrascript.provider.terraform(...)

I have to remind myself to create a test case for this issue.

mjuenema commented 4 years ago

So the root cause of the problem is that terraform is a top-level block and also a provider with the terraform_remote_state data source.

With the upcoming 0.8.0 release of Terrascript the best way out of your problem is to use the new module layout. I added https://github.com/mjuenema/python-terrascript/blob/develop/tests/test_issue43.py which documents this.

jbscare commented 4 years ago

Makes sense. If the new 0.8.0 layout makes this issue obsolete, feel free to close it. Thanks!

mjuenema commented 4 years ago

Closing as the solution is documented in tests/test_issue43.py.