Hello, I'm new to Pulumi, I need to deploy infras ...
# package-authoring
r
Hello, I'm new to Pulumi, I need to deploy infras on VMWare NSX-T and Vsphere clusters. Unfortunately, although VSphere is officially supported by Pulumi, it's not the case of NSX-T 😢 However, VMware is actually providing a TF provider here: https://github.com/vmware/terraform-provider-nsxt so I decided to create my own pulumi provider following the doc here https://github.com/pulumi/pulumi-tf-provider-boilerplate ! My forked project is here https://github.com/SCC-Hyperscale-fr/pulumi-nsxt I'm not familiar with golang, and unfortunately
make tfgen
is failing with this call stack:
Copy code
$ make tfgen
[ -x /home/rico/bin/pulumi ] || curl -fsSL <https://get.pulumi.com> | sh
pulumi plugin install resource random 4.3.1
(cd provider && go build -o /home/rico/projects/hyperscale/pulumi-nsxt/bin/pulumi-tfgen-nsxt -ldflags "-X <http://github.com/SCC-Hyperscale-fr/pulumi-nsxt/provider/pkg/version.Version=0.0.1-alpha.1697732185+d136c29f.dirty|github.com/SCC-Hyperscale-fr/pulumi-nsxt/provider/pkg/version.Version=0.0.1-alpha.1697732185+d136c29f.dirty>" <http://github.com/SCC-Hyperscale-fr/pulumi-nsxt/provider/cmd/pulumi-tfgen-nsxt)|github.com/SCC-Hyperscale-fr/pulumi-nsxt/provider/cmd/pulumi-tfgen-nsxt)>
# <http://github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim/sdk-v2|github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim/sdk-v2>
/home/rico/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/v3@v3.62.0/pkg/tfshim/sdk-v2/resource.go:24:26: r.tf.SchemaMap undefined (type *schema.Resource has no field or method SchemaMap)
/home/rico/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/v3@v3.62.0/pkg/tfshim/sdk-v2/resource.go:90:67: r.tf.SchemaMap undefined (type *schema.Resource has no field or method SchemaMap)
/home/rico/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/v3@v3.62.0/pkg/tfshim/sdk-v2/resource.go:91:22: r.tf.SchemaMap undefined (type *schema.Resource has no field or method SchemaMap)
/home/rico/go/pkg/mod/github.com/pulumi/pulumi-terraform-bridge/v3@v3.62.0/pkg/tfshim/sdk-v2/schema.go:137:23: e.SchemaMap undefined (type *schema.Resource has no field or method SchemaMap)
make: *** [Makefile:51 : tfgen] Erreur 1
No idea what's going on, so any suggestion would be appreciated ! Thanks 🙂
b
@rough-island-84087 You may find my Cookiecutter template useful in this case. Easier to use than the boilerplate repo. Read the docu closely, especially around how to specify the version of the upstream provider. https://github.com/tmeckel/pulumi-tf-provider-cookiecutter
Yep, the TF provider has an invalid module definition in the `go.mod`file. Use a git commit hash to specify the desired upstream version.
And wow, this is a huge provider 😮 you have to have a close look how to map all those resources and data sources to different namespaces in Pulumi.
Gave it quick shot: worked like a charm 🙂
r
@big-architect-71258 thanks for the tips, I'm going to have a try this way...
I'm quite surprised that a so critical brick is not officially supported out of the box by Pulumi : I can't believe I'm the only one interested by automating NSX-T in Pulumi world ?
b
@rough-island-84087 Appreciate all feedback, negative or positive, about the Cookiecutter template.
r
sure, but actually I found the issue with the boilerplate:
Copy code
// replace <http://github.com/hashicorp/terraform-plugin-sdk/v2|github.com/hashicorp/terraform-plugin-sdk/v2> => <http://github.com/pulumi/terraform-plugin-sdk/v2|github.com/pulumi/terraform-plugin-sdk/v2> v2.0.0-20220824175045-450992f2f5b9
replace <http://github.com/hashicorp/terraform-plugin-sdk/v2|github.com/hashicorp/terraform-plugin-sdk/v2> => <http://github.com/pulumi/terraform-plugin-sdk/v2|github.com/pulumi/terraform-plugin-sdk/v2> v2.0.0-20230710100801-03a71d0fca3d
So I try to go(lang😅) next, to see if it can work. As you said, NSX is a huge package with a lot of resources and datasources... I'm digging into the code to catch them all
@big-architect-71258
Copy code
[5/24] terraform_provider_module (<http://github.com/vmware/terraform-provider-nsxt/v3|github.com/vmware/terraform-provider-nsxt/v3>):
I have no clue of what cookiecutter expects, but seems the default "/v3" is not the right choice... And I didn't find any reference on upstrem tf provider ?
b
No V3 is not the right choice because, as already stated earlier, the module statement in the the top-level
go.mod
file defines it as
<http://github.com/vmware/terraform-provider-nsxt|github.com/vmware/terraform-provider-nsxt>
. Thus use a commit hash for the template parameter
terraform_provider_version_or_commit
https://github.com/tmeckel/pulumi-tf-provider-cookiecutter#parameter-details
r
yes, got it.
b
These are the settings I used successfully yesterday evening
Copy code
"terraform_provider_name": "nsxt",
    "terraform_provider_org": "vmware",
    "terraform_provider_source": "github.com/vmware/terraform-provider-nsxt",
    "terraform_provider_version_or_commit": "1c47f8ee58d4e992bae27c188cf336edd67fa251",
    "terraform_provider_module": "github.com/vmware/terraform-provider-nsxt",
    "terraform_provider_package_name": "nsxt",
    "terraform_sdk_version": "2",
r
I'm stuck because go 1.20 is installed on my system, but it require 1.19
b
I know, this is still an issue with the template, because currently the template has static configuration for GO 1.19.8.
Change the GO Version settings in the Makefile and in the github workflows.
Or you edit the Cookiecuttre replay file at
vi ~/.cookiecutter_replay/pulumi-tf-provider-cookiecutter.json
and start cookiecutter with the
--replay
option.
r
vscode is not happy with resource declaration: seems mainMod is not correctly declared ?
b
The comments are a a leftover from the boilerplate code. Try to use
Tok: makeResource(mainMod, "<put-resourcename-here>"),
r
looks better. what about Pulumi naming convention ? should I rename `nsxt_dhcp_relay_profile`` to
dhcpRelayProfile
as suggested in boilerplate readme ?
b
The (local)
makeResource
and
makeDatasource
call
convertName
which will automatically create this name. But as I said the NSXT Provider is huge and perhaps you should move resources to separate namespaces. As I have the same isssue with the Fortios provider, I extended the `convertName`method to the following:
Copy code
var module_overrides = map[string]string{}

func convertName(tfname string) (module string, name string) {
	tfNameItems := strings.Split(tfname, "_")
	contract.Assertf(len(tfNameItems) >= 2, "Invalid snake case name %s", tfname)
	contract.Assertf(tfNameItems[0] == "fortios", "Invalid snake case name %s. Does not start with fortios", tfname)
	if len(tfNameItems) == 2 {
		module = mainMod
		name = tfNameItems[1]
	} else {
		module = tfNameItems[1]
		name = strings.Join(tfNameItems[2:], "_")
	}
	if v, ok := module_overrides[module]; ok {
		module = v
	}
	contract.Assertf(!unicode.IsDigit(rune(module[0])), "Pulumi namespace must not start with a digit: %s", name)
	contract.Assertf(!unicode.IsDigit(rune(name[0])), "Pulumi name must not start with a digit: %s", name)
	name = strcase.ToPascal(name)
	return
}
It will move resources/datasources automatically along the underscores to separate namespaces.
With the
module_overrides
hashtable this can be fine tuned if required. E.g. In Fortios there are resources which match the `firewallconsolidated`namespace. But with
Copy code
var module_overrides = map[string]string{
	"firewallconsolidated":           "firewall/consolidated",
They are moved to the
firewall/consolidated
namespace. But be aware that with
dotnet
there seems to be an issue with the language generator.
r
interesting. but as a first attempt i'd like to get the package compile and a unique NS sounds easier. Moreover i'm not yet at target :
Copy code
warning: Found <elided> in description for [nsxt_vlan_logical_switch]. The description and any examples will be dropped in the Pulumi provider.
warning: Unexpected code snippets in section 'Importing' for resource 'nsxt_vm_tags'. The HCL code will be converted if possible, but may not display correctly in the generated docs.
warning: Found <elided> in description for [nsxt_vm_tags]. The description and any examples will be dropped in the Pulumi provider.
error: failed to gather package metadata: problem gathering resources: 7 errors occurred:
	* Pulumi token "nsxt:index/edgeHighAvailabilityProfile:EdgeHighAvailabilityProfile" is mapped to TF provider resource "nsxt_edge_high_availability_profile", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/nodeUser:NodeUser" is mapped to TF provider resource "nsxt_node_user", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/policyHostTransportNode:PolicyHostTransportNode" is mapped to TF provider resource "nsxt_policy_host_transport_node", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/policyHostTransportNodeCollection:PolicyHostTransportNodeCollection" is mapped to TF provider resource "nsxt_policy_host_transport_node_collection", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/policyUplinkHostSwitchProfile:PolicyUplinkHostSwitchProfile" is mapped to TF provider resource "nsxt_policy_uplink_host_switch_profile", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/policyUserManagementRole:PolicyUserManagementRole" is mapped to TF provider resource "nsxt_policy_user_management_role", but no such resource found. The mapping will be ignored in the generated provider
	* Pulumi token "nsxt:index/policyUserManagementRoleBinding:PolicyUserManagementRoleBinding" is mapped to TF provider resource "nsxt_policy_user_management_role_binding", but no such resource found. The mapping will be ignored in the generated provider
I have no clue why some mappings are not found while they are explicitly declared here : https://github.com/vmware/terraform-provider-nsxt/blob/master/nsxt/provider.go
i'm stupid: my HEAD on vmware repo was misplaced 😄
b
Just for info: had the same errors and thought if the resources really exist 😄
r
got tfgen successful. (with log of warning due to missing docs) make provider also succeeded !
the still unclear part is how do I get my python sdk now ?
b
To solve the doc issues, I guess you need to clone the upstream provider with the required version to the `upstream`directory and set the
UpstreamRepoPath: "./upstream",
property in
tfbridge.ProviderInfo
. To automate this the Makefile should be extended as well:
Copy code
upstream/.git:
	@echo "Initializing upstream" ; \
	git clone  --depth 1 --branch <branch-name> <https://github.com/><repo> upstream
Whereas the
upstream/.git
target should be a dependency for the
tfgen
target.
To build the SDKs call
make build_sdks
r
Big thanks for your help ! once it's done it looks almost easy actually 😄
now I need to document, test, and enhance. I agree with you : this package should be splitted into namespaces (and fix docs)
b
As I said, perhaps you could adopt the way I'm using with the Fortios provider. Oh and, just preparing a PR to fix the mentioned issue with the dotnet codegen, with deeply nested namespaces.
@rough-island-84087 I don't know a far you already got with the NSX-T provider. But I already released a new version of the Cookiecutter Template. In it there is now a GO generator to create missing resource and data source mappings. You can simply copy the
provider/generator.go
file to your repo and add a line
//go:generate go run generate.go
to the
provider/resources.go
and you can use
go generate
to let the generator add missing mapping automatically.