Provider resource creation with a dependency on other resource

Hello, I am creating a new provider and successfully created my full first data and resource types. Now I am creating a dependant resource.

Example: user_resource, which as “id” attribute I can use during creation as unique_id so later updates work on the resource. Now I am creating “user_something_resource” that has “user_id” attribute, which will be used to create a dependency to the former user.

main.tf:

[...]
resource "myprovider_user" "user" {
   id = "myuniqueid@example.com"
}

resource "myprovider_user_something" "user" {
   user_id = myprovider_user_something.user.id
}

Now the question: how do I get all the information in the plan for the “Create” function in resource_user_something?

In the original simple “user” resource, I have something like this so I get the plan for the new “user” resource being created:

func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var plan userResourceModel
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}
	...

How can I get the plan, that I assume will include both the new user_something and de dependant user resource?

func (r *userSomethingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var plan xxxxxxxxxx // <====== ?????????????
	diags := req.Plan.Get(ctx, &plan)
	resp.Diagnostics.Append(diags...)
	if resp.Diagnostics.HasError() {
		return
	}

Thank you very much.

BTW: wonderful plugin framework and documentation…

Hi @javierjeronimo :wave:

For userSomethingResource, you will need to have a user_id attribute declared on the schema for that resource:

func (e *userSomethingResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"user_id": schema.StringAttribute{
				/* ... */
			},
			/* ... */
		},
	}
}

You will also need a corresponding entry in your data model:

type userSomethingResourceModel struct {
	UserId types.String `tfsdk:"user_id"`
	/* ... */
}

Then you will use the code that you described for the Create function:

func (r *userSomethingResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
	var plan userSomethingResourceModel

	diags := req.Plan.Get(ctx, &plan)

	resp.Diagnostics.Append(diags...)

	if resp.Diagnostics.HasError() {
		return
	}

	// do something with plan.UserId

Just to clarify. The plan that you unmarshal onto userSomethingResourceModel contains the value for user_id that was defined in the terraform configuration for userResource.

If you want to use the user_id value from the first resource as a configuration value supplied to the second resource, then the terraform configuration should look as follows:

resource "myprovider_user" "user" {
   id = "myuniqueid@example.com"
}

resource "myprovider_user_something" "user" {
   user_id = myprovider_user.user.id
}

Ok, thank you.

Then, is it possible to get, in the user_something Create function, a plan that contains both the user_somerthing and the user (referenced resource using the user_something.user_id)? Or shall I manually get the user plan data I some way?

I created user_something as a “child” resource of “user” assuming that I would get the plan data including both, so I can call user_something APIs having at my hand access to the whole plan data, not only the user_something plan which I obviously receive in its Create function.

Thanks.

Hi @javierjeronimo :wave:

I’m not quite sure if you’re asking whether it is possible to obtain the plan for one resource in another resource, but if so, there’s some discussion around this topic in Access to plan with new Terraform terraform-plugin-framework which might prove useful.