hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.65k stars 9.55k forks source link

Run "terraform plan" without access to remote APIs #14254

Open timurb opened 7 years ago

timurb commented 7 years ago

Can something like terraform plan be run without touching real world provider endpoints? This way we could have some kind of specs run against the plan and be able to do some development staying offline.

This is actually an addition to https://github.com/hashicorp/terraform/issues/13738. This current request looks to me less straightforward implement that's why I created a separate ticket.

grubernaut commented 7 years ago

Hey @timurb, thanks for the issue

The argument -refresh on the terraform plan command can prevent Terraform from calling the internal Read function inside each provider to refresh values from the remote APIs. Using -refresh=false will only use the local configuration files and the target statefile. This can help you run some specs against the plan while staying offline, unless your statefile is also stored remotely.

tl;dr: terraform plan -refresh=false doesn't touch any real world provider endpoints and can be used to run specs against a plan offline, provided the statefile is local and not remote.

Closing for now, as it's not an active issue, but happy to discuss further if needed! Thanks again!

timurb commented 7 years ago

@grubernaut This doesn't work for me:

$ terraform plan -refresh=false spec/testing_defaults/
Error running plan: 3 error(s) occurred:

* module.m1.provider.powerdns: Error setting up PowerDNS client: Get http://local.ip.of.myorg.com/api/v1/servers: dial tcp: lookup local-ip.of.myorg.com on 8.8.8.8:53: no such host
* module.m1.provider.phpipam: Error setting up phpIPAM client: Post https://another.local.ip.of.myorg.com/api/terraform/user/: dial tcp: another.local.ip.of.myorg.com: no such host
* module.m1.provider.vsphere: Error setting up client: Post https://local.ip.for.vcenter.of.myorg.com/sdk: dial tcp: lookup local.ip.for.vcenter.of.myorg.com on 8.8.8.8:53: no such host

(I removed any *.tfstate files from the tree prior to running the command)

My intent was to run this operation completely disconnected from any provider endpoints and with no previous state -- say in CI. Either the current refresh=false feature is different to that (for example requires a state) or it has a bug.

timurb commented 7 years ago

Hello, is this issue still in some distant future scope (say TF 1.0+) or should I open a new similar one with additional clarifications for that?

grubernaut commented 7 years ago

Hey @timurb sorry for the late reply to this.

Apologies for suggesting -refresh=false, looks like the provider initialization happens regardless of that flag. I'll re-open this, and tag accordingly so we can take a look at it. Thanks!

Daviey commented 7 years ago

Confirming this is the same with AWS provider. I hoped to be able to do some offline plan work, but currently this is not possible.

josephholsten commented 7 years ago

@grubernaut is the provider initialization a separate issue? In an ideal world, is terraform plan -refresh=false the command that we want to work this way?

apparentlymart commented 7 years ago

Unfortunately it seems likely that over time this will become less possible, because we will want to do more validation at plan time and some of it will inevitably involve reaching out to services for information.

Out of curiosity, what sorts of things are you all hoping to be able to do that involves offline planning? Is it primarily about validation? We have the terraform validate command which can do some things, and will likely get better capabilities in future as we improve Terraform's type system. Would that be helpful/sufficient?

timurb commented 7 years ago

I'm doing TDD of my TF modules and plan command is the one against which I'm running RSpec. This way requiring the connection to APIs prevents me from developing offline and slows down test runs, that's why I've opened the issue.

If you are interested my specs look like this:

module m1
  using module with extended parameters
    VMWare server
      creates 5 VMs
      processes LVM sizes
      processes datacenter
      processes datastore
      processes disk size
      processes folder
      processes vm_image
      processes resource_pool
      processes nic_label
      processes cpu count
      processes ram size
      processes dns servers
      processes dns suffixes
    IPAM
      creates 5 IPAM entries
      assigns correct hostname
      processes ip_section param
      processes ip_subnet param
    DNS
      creates 5 DNS entries
      creates 5 reverse DNS entries
      assigns hostnames to DNS entries
      uses zone in DNS entries
      assigns records to reverse DNS entries (PENDING: Update TerraformPlan to process records)

So basically I'm testing that all input params to my module are converted to expected results and probably I don't need data returned by APIs for that.

leonardoauribe commented 1 year ago

Has any progress been made with this? I manage several resources in an isolated environment and would like to be able to run tf plans against the state file prior to promoting changes to staging/production without having to make calls to the provider.

apparentlymart commented 1 year ago

This request essentially amounts to having a mocking system to allow stubbing out provider functionality while still behaving realistically enough for the resulting tests to yield useful results. I've done some prototyping of such things but so far nothing that's usable enough to be shippable.

At the moment the appropriate design is unclear and so nothing is implementable yet.