Multiple resources into single resource handler go file

Hello,

I am developing a provider using Plugin Framework.

My cloud infrastructure supports 100s of object types. The question is if there is a way to create a single resource handler(maybe call it with a parameter containing the resource type) to handle all the objects schemas.

eg.

func (p *MyProvider) Resources(ctx context.Context) []func() resource.Resource {
	return []func() resource.Resource{
		func() resource.Resource {
			objectType := "myType1"
			return NewObjectResource(objectType)
		},
		func() resource.Resource {
			objectType := "myType2"
			return NewObjectResource(objectType)
		},
		func() resource.Resource {
			objectType := "myType3"
			return NewObjectResource(objectType)
		},
	}
}

One object may be a struct with 3 fields and another with 10 fields. I wanted to avoid writing a resource file for each of the objects and come up with a generic way of handling all objects.

For data sources I managed to achieve this easy by using a data field in the schema which is of type.Dynamic, since the response will be a json string. But what about CRUD operations on resources, I need to somehow based on the type of object to generate dynamically the schema and the model to be able to extract config info from the terraform configuration file into the provider for further processing.

Any help is appreciated
Thanks

Hi @DodinViorel :wave:

One of the core Terraform concepts is that a Resource represents an infrastructure object (e.g., a compute instance). These objects have relationships to one another, for example, a compute instance and the network to which the instance is connected. When specifying individual resources with Terraform, it’s possible to specify the relationship between infrastructure objects. For example,

resource "aws_vpc" "my_vpc" {
  cidr_block = "172.16.0.0/16"
  // further config
}

resource "aws_subnet" "my_subnet" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "172.16.10.0/24"
  availability_zone = "us-west-2a"
  // further config
}

resource "aws_network_interface" "foo" {
  subnet_id   = aws_subnet.my_subnet.id
  private_ips = ["172.16.10.100"]
  // further config
}

resource "aws_instance" "foo" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  network_interface {
    network_interface_id = aws_network_interface.foo.id
    device_index         = 0
  }

  // further config
}

The compute instance has a dependency upon a network interface, associated with a subnet on a vpc. This relationship is managed by Terraform, which ensures that, for example, the vpc is created prior to the subnet, network interface and compute instance.

With the approach that you have described, you would have to be responsible for managing all of the dependencies between the infrastructure objects within the provider itself. The recommended approach is therefore to separate management of infrastructure objects into logical resources rather than trying to manage multiple different types of infrastructure objects from a single resource. The AWS provider is a great example of this sort of separation.