Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create noop resource #580

Closed
piavlo opened this issue Nov 19, 2014 · 10 comments
Closed

Create noop resource #580

piavlo opened this issue Nov 19, 2014 · 10 comments

Comments

@piavlo
Copy link

piavlo commented Nov 19, 2014

I need a kind of meta resource that creates nothing but can specify depends_on and invoke provisioners

for example i want to create 3 instances (on which some clustered service will be deployed) but all instances need to be in different zones, so i cannot use count=3 in one resource, i need to run a provisioner only after all 3 instances have been created

@piavlo piavlo changed the title meta resource meta/noop resource Nov 19, 2014
@sethvargo sethvargo changed the title meta/noop resource Create noop resource Nov 19, 2014
@knuckolls
Copy link
Contributor

null_resource is semi-undocumented and we use it internally in a proof of concept for this exact purpose. For example, we want to make sure that zk is settled before we fire up mesos. That zk_check_is_ready script spins localhost until the health checks pass or it times out / errors out.

resource "null_resource" "zookeeper_wait" {
  depends_on = ["aws_route53_record.zk1-staging","aws_route53_record.zk2-staging","aws_route53_record.zk3-staging"]

  provisioner "local-exec" {
    command = "../zk-check is_ready ${aws_route53_record.zk3-staging.name} 3"
  }
}

resource "null_resource" "mesos-slave_wait" {
  depends_on= ["null_resource.zookeeper_wait"]

  provisioner "local-exec" {
    command = "ssh ${aws_instance.mesos-slave1.private_ip} 'sudo /tmp/mutate.sh mesos-slave staging ${var.zk_string}'"
  }

}

I consider this a hack. What I really want, and have considered implementing, is first class support for these two concepts: "mutate" and "post deploy verification". You may ask, why local-exec's here? It's only because this is from something that was whipped up together quickly. Remote-exec may work for the mutate example.

Aside from the "these things have to come up properly before these things" concerns; the other win that we get from this is speed. For example, there is no reason to wait to fire up an instance after a whole tier is verified as up and running correctly. Instance creation should be parallelized as much as possible and then those instances should have provisioners mutate them in the right order by firing off configuration management or initialization bash scripts. Effectively, I've started to conceptualize nodes as stem cells awaiting mutation towards some specialization.

Perhaps this should be filed under a separate issue but I figured I'd put all this here in case it's helpful.

@armon
Copy link
Member

armon commented Nov 20, 2014

I agree! I think it would be interesting to support a "logical" provider that provides resources that are no-ops, but can be used to this kind of coordination. Using provisioners is our currently recommended way of doing post-deploy verification and mutation. I can see the case for more syntactic sugar, but they'd do the same thing under the hood, so it doesn't seem like much of a hack.

@knuckolls
Copy link
Contributor

I guess the reason it felt like a hack to me was that I just dug that resource out of the source code. I wasn't sure if it was meant to be used this way or since it wasn't documented if it was going to change / go away.

I like the idea of a logical provider that provides "coordination / flow control" no-ops. Although, I do agree with you -- if they don't provide anything more than syntactic sugar over the null_resource then it's not that big of a win. Documentation of the possible uses of the null_resource would likely suffice.

I do have in mind a few scenarios that would provide more functionality than just syntactic sugar over the null_resource. For example, currently I don't believe there is a way to have a null_resource participate in subsequent plans / applies beyond the initial creation of the resource. This is due to the fact that it doesn't change state past the initial creation.

Due to that, I'm not sure that true ongoing post-deploy verification fits into that model via the null_resource. I could see it being helpful to have simple serverspec-ish verification resources that confirm that each tier of the terraform config is still healthy after a subsequent plan / apply. Additionally, it would be nice if a verification resource like this could run it's checks in parallel. Currently if we set up a series of local-execs within a single "verification" null_resource, they do their checks one by one.

One thing I can think of that I would want to mutate on the machines swiftly (due to audit controls) is user account deletion upon termination. I could use a parallel ssh script, or some minimal CM system, but I feel like a first class mutate resource would allow operations like diffing an idempotent local postlaunch.sh to a provisioned postlaunch.sh and if there is a diff that it would cause the mutate resource to be re-run during the apply.

Those are two scenarios that I had in mind that I'm not sure fit into the null_resource model currently. I realize that for anything truly fancy I could write a custom plugin or shellout to a sophisticated script. I actually quite like that design decision of Terraform. Anything I'd like to do is just a local-exec away. Mutation and simple "smoke test" style post-deploy verification seem like they could be reasonably core primitives to the value that terraform brings to the table. That's why I've been batting around the idea that it might be nice to have simple implementations like these as first class resources rather than bolt on local-execs or some sort of wrapper tooling.

If I get a chance, I may PR some experiments. :)

@armon
Copy link
Member

armon commented Nov 24, 2014

Hmm yeah I see what you are saying. I didn't mean that the "null_resource" directly should be used either haha.

I think we can add a "logical" provider, that adds a few different types of resources. The simples could be a "logical_noop" which can be used as a depends on barrier and that kind of thing. But I agree, there are other types of resources that provider could have to support things like verification and mutation in a more reasonable way.

@phinze
Copy link
Contributor

phinze commented Sep 10, 2015

In the absence of a more first-class concept like what's being discussed here, I've personally found null_resource to be an absolutely invaluable--if a bit inelegant--tool in setting up complex systems. I think it's probably worth documenting it as-is until we gain something better.

@phinze
Copy link
Contributor

phinze commented Sep 10, 2015

More valuable thoughts over in #1181, which I just closed to merge the discussion back here.

@apparentlymart
Copy link
Contributor

Over in #2696 I proposed a patch that adds a resource that behaves quite a lot like null_resource except that it has a state_key property that allows the user to describe situations where the provisioners need to be re-run for some reason.

This is aimed at the same use-case as described in this issue: an "escape hatch" to run provisioners without a "real" resource to attach them to, but with the extra possibility of re-running those provisioners when the world changes around them. For example, I have prototyped using it to re-run some installation steps after pushing a new code bundle up to S3, with the S3 key (which contains a version number and build timestamp) inserted into the state_key.

@knuckolls
Copy link
Contributor

FYI I've submitted a pull request for adding additional optional "trigger" functionality to the null_resource so that it participates in the execution graph better. #3244

@phinze
Copy link
Contributor

phinze commented Oct 29, 2015

Closing this, since we're documenting null_resource now. 👍 #3659

@phinze phinze closed this as completed Oct 29, 2015
@ghost
Copy link

ghost commented Apr 30, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants