Git Product home page Git Product logo

Comments (8)

sheerun avatar sheerun commented on June 7, 2024 3

How about child resources to define dependencies on parent resources instead? So following is possible:

resource "aws_security_group" "foo" {
  // ...
  resource "aws_security_group_rule" {
    // ...
  }
}

Because aws_security_group_rule is nested inside aws_security_group it knows to set following defaults:

  • name to "${aws_security_group.name}"
  • depends_on to ["${aws_security_group.foo}"]
  • security_group_id to "${aws_security_group.foo.id}"

Note that aws_security_group doesn't need to know about aws_security_group_rule or any other possible resource to nest in it. The default for any nested resource is just name and depends_on.

from terraform-plugin-sdk.

displague avatar displague commented on June 7, 2024 2

If I wasn't bound by current limitations and conventions (WIP), I may have approached the Linode Instance resource differently.

I think you would want to be able to access your parent's attributes within these sub-resources (explicitly and implicitly within plugins for the parent.ID)). schema.Resource semantics would offer CRUD functions and the Test helpers would provide the means to verify and destroy these sub-resources between tests.

The API required order for this example schema to be applied would be:

  • create bare instance
  • create disk sub-resources (referring to instance ID)
  • create config sub-resources (referring to disk ID)
  • boot instance (referring to config ID)
// The instance can be created with a simple API call
// This automatically creates physical 'config' and 'disk' sub-resources
// TF parent resources *should* have the ability to import child resources.
resource "linode_instance" "simple" {
  region = "us-east"
  type = "g6-nanode-1"
  image = "linode/debian9.1"
}

// .. more complex configurations require more API calls and CRUD operations on 
// REST sub-resources /instance/123/config/456, /instance/123/disk/456
resource "linode_instance" "complex" {
  region = "us-east"
  type = "g6-nanode-1"
 
  // the instance can be created bare and unpowered, but provisioners need it running 
  // creating the disk, via API, requires the instance be created but not running
  disk "diskA" {
    label = "diskA"
    size=1000
    image = "linode/debian9.1"
  }

  disk "scratch" {
    count = 3
    label = "scratch${count.index}"
    size=1000    
  }

  config "configA" {
    // ...
    devices = {
       sda = { disk_id = "${self.disk.diska.id}" }
       sdb = { disk_id = "${self.disk.scratch.0.id}" }
       sdc = { disk_id = "${self.disk.scratch.1.id}" }
       sdd = { disk_id = "${self.disk.scratch.2.id}" }
    }
  }

  config "configsB" {
     label = "configb-${count.index}"
     count = "3"
     devices = {
        sda = { disk_id = "${self.disk.diska.id}" } 
        sdb = { disk_id = "${element(self.disk.scratch.*.id, count.index)}" }
     }
  }

  boot_config_id = "${self.config.configsB.2.id}"
}

from terraform-plugin-sdk.

ojongerius avatar ojongerius commented on June 7, 2024

🙌

from terraform-plugin-sdk.

blakestoddard avatar blakestoddard commented on June 7, 2024

Is there any update available on this? I've got an issue at the moment where I create a bulk of a route table (and it's routes) via the aws_route_table resource, but have the possibility of needing to tack on another route if a conditional is passed. It looks like I can't currently do that because you cannot mix aws_route and aws_route_table objects?

from terraform-plugin-sdk.

nbering avatar nbering commented on June 7, 2024

Concept

I was thinking something similar to this. It would be nice if some resources could have child resources that are opaque in the configuration, but behaved sort of like submodules in the plan.

I actually arrived to this conclusion that nested resources would be beneficial to Terraform after reading The Idea of Lisp on the Practical Developer. Therein is discussed the idea that lisp Macros are simply functions built in lisp that return lisp code, thereby providing a fluid extension point for writing additional language features. My thinking is you could have "macro resources", which behave as a resource - being defined by the plugin and not imported as a configuration - but return multiple sub-resources to be included in the graph and applied to the plan and stored individually in the state file.

I think the key difference between this idea and that of submodules is that nested resources would be defined by the provider plugin, and not by user configuration.

Configuration Benefits

Examples of where this would be useful are things like assignments and security group rules, where there is already an option on the resource, and a separate resource entity, and they are not compatible.

State Benefits

Having the separate resource entity as a child resource might allows something like terraform state mv on a subresource, which would be helpful for refactors of complex infrastructures without having to remove and import resources.

User Experience Benefits

Nested resources as a concept simplifies the complex relationships between some resources by allowing "associative" resources to be used in compatibility with config blocks on parent resources.

This would specifically provide a nice bridge from beginner to power-user. I have a theory that a beginner would use config blocks attached to the parent resource until they run into a limitation of that configuration style, and then transition to what power users would be more likely to use - the separate resource, and make submodules to compose resources together.

from terraform-plugin-sdk.

nbering avatar nbering commented on June 7, 2024

Oh... it would also be kind of neat if the sub-resources did not have to come from the same provider. Ie, you could do a meta-resource like "dns_record" that took configuration common to a bunch of the DNS providers, and a property that said which one to use, making it simpler to switch between providers when used in submodules. For example, some of my projects have different DNS providers just because of who my clients work with. That would allow me to share my VM configuration submodule between clients without having to write a some hacky thing with a count of zero, etc. I do imagine the implementation of such an idea would require non-computed fields much like count does now, but would delegate a portion of the graph builder to the provider plugin to determine what sort of resource a particular node would be.

from terraform-plugin-sdk.

paultyng avatar paultyng commented on June 7, 2024

Going to merge this to #220

0.12 supports "named blocks", and once that is supported in the SDK, it should cover some of the use cases described here. Anything more significant, including handling of resources invoking other resources, is probably better left to upstream Terraform. If the usecase for the true nesting of real resources is just about code reusability, we can achieve that in other ways.

from terraform-plugin-sdk.

 avatar commented on June 7, 2024

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.

from terraform-plugin-sdk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.