Skip to content

Commit

Permalink
feat: Autogenerate provider resources mappings (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeckel authored Oct 31, 2023
1 parent 3ea6f2d commit 72cd6ac
Show file tree
Hide file tree
Showing 17 changed files with 358 additions and 102 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
repos:
- repo: 'https://github.com/pre-commit/pre-commit-hooks'
rev: 'v4.4.0'
rev: 'v4.5.0'
hooks:
- id: 'check-added-large-files'
- id: 'fix-byte-order-marker'
Expand All @@ -15,13 +15,13 @@ repos:
- id: 'check-merge-conflict'

- repo: 'https://github.com/adrienverge/yamllint.git'
rev: 'v1.29.0'
rev: 'v1.32.0'
hooks:
- id: 'yamllint'
exclude: 'azure-pipelines.yml'

- repo: https://github.com/psf/black
rev: 23.1.0
rev: 23.10.1
hooks:
- id: black

Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ After the Cookiecutter template has created the new directory for the Pulumi
provider, you can change to this directory and use the `make tfgen` command to
check whether the Terraform provider has been referenced correctly.

For guidance how to further develop the newly created Pulumi provider refer to
`README-DEVELOPMENT.md` in the provider directory.
> **Note**
> For guidance how to further develop the newly created Pulumi provider refer to
> `README-DEVELOPMENT.md` in the provider directory especially how to map
> resources and data sources from the upstream Terraform provider including the
> possbility to autogenerate hose mappings.
## Parameter details

Expand Down
4 changes: 4 additions & 0 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
"__go_version_major": "{{ cookiecutter.go_version | version_major }}",
"__go_version_minor": "{{ cookiecutter.go_version | version_minor }}",

"_jinja2_env_vars": {
"lstrip_blocks": true,
"trim_blocks": true
},
"_copy_without_render": [],
"_extensions": [
"local_extensions.LocalExtension"
Expand Down
2 changes: 1 addition & 1 deletion local_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __init__(self, environment: Environment) -> None:
super().__init__(environment)
environment.globals["get_latest_release"] = get_latest_release
environment.globals["get_latest_release_commit"] = get_latest_release_commit
environment.tests["truthy"] = is_truthy
environment.filters["truthy"] = is_truthy
environment.filters["capitalize"] = capitalize
environment.filters["go_module_version"] = go_module_version
environment.filters["go_module_name"] = go_module_name
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% raw -%}
{% raw %}
name: build

on:
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.provider}}/.github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% raw -%}
{% raw %}
name: release

on:
Expand Down
6 changes: 3 additions & 3 deletions {{cookiecutter.provider}}/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ We have a few tips and housekeeping items to help you get up and running.

## Code of Conduct

Please make sure to read and observe our [Code of Conduct]({%- if cookiecutter.provider_github_organization.lower() == "pulumiverse" -%}
Please make sure to read and observe our [Code of Conduct]({% if cookiecutter.provider_github_organization.lower() == "pulumiverse" %}
https://github.com/pulumiverse/.github/blob/main/CODE_OF_CONDUCT.md
{%- else -%}
{% else %}
./CODE-OF-CONDUCT.md
{%- endif -%}
{% endif %}
)

## Community Expectations
Expand Down
3 changes: 3 additions & 0 deletions {{cookiecutter.provider}}/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ help::
sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\033[93m"`\1`printf "\033[0m"` \3 [\2]/" | \
expand -t20

generate::
go generate provider/resources.go

clean::
rm -rf sdk/{dotnet,nodejs,go,python} sdk/go.sum

Expand Down
91 changes: 57 additions & 34 deletions {{cookiecutter.provider}}/README-DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
This document describes the procedures for developing and maintaining a Pulumi
provider based on the Pulumi Terraform Bridge.

- [Developing with a Terraform Bridge Provider](#developing-with-a-terraform-bridge-provider)
- [Creating a Pulumi Terraform Bridge Provider](#creating-a-pulumi-terraform-bridge-provider)
- [Prerequisites](#prerequisites)
- [Publishing checklist](#publishing-checklist)
- [Composing the Provider Code - Prerequisites](#composing-the-provider-code---prerequisites)
- [Adding Mappings, Building the Provider and SDKs](#adding-mappings-building-the-provider-and-sdks)
- [Autogeneration of mapping](#autogeneration-of-mapping)
- [Manually add mapping](#manually-add-mapping)
- [Building the provider and SDKs](#building-the-provider-and-sdks)
- [Sample Program](#sample-program)
- [Add End-to-end Testing](#add-end-to-end-testing)
{% if cookiecutter.create_github_workflows | truthy %}
- [CI/CD with GitHub Actions](#cicd-with-github-actions)
{% endif %}

## Creating a Pulumi Terraform Bridge Provider

The following instructions cover:
Expand Down Expand Up @@ -113,6 +128,24 @@ cohesion of a provider's code, thereby making it easier for developers to use.
If your provider has a large number of resources, consider using namespaces to
improve usability.

### Autogeneration of mapping

The repository contains a GO generator (`provider/generator.go`) to
automatically create reported missing data sources and resources from `tfgen`.

The generator can be executed at any time by _building_ the target `generate`
from the Makefile:

```bash
make generate
```

The generator will report all added resources and/or data sources if any where
detected. If any missing mappings where detected and resolved the `resources.go`
file will be formatted using `go fmt`.

### Manually add mapping

The following instructions all pertain to `provider/resources.go`, in the
section of the code where we construct a `tfbridge.ProviderInfo` object:

Expand Down Expand Up @@ -193,7 +226,10 @@ section of the code where we construct a `tfbridge.ProviderInfo` object:
},
```
1. Build the provider binary and ensure there are no warnings about unmapped resources and no warnings about unmapped data sources:
### Building the provider and SDKs
1. Build the provider binary and ensure there are no warnings about unmapped
resources and no warnings about unmapped data sources:
```bash
make provider
Expand Down Expand Up @@ -327,44 +363,31 @@ We can run integration tests on our examples using the `*_test.go` files in the
```bash
cd examples && go test -v -tags=nodejs
```
{% if cookiecutter.create_github_workflows | truthy %}

## Configuring CI with GitHub Actions

### Third-party providers
## CI/CD with GitHub Actions

1. Follow the instructions laid out in the [deployment templates](./deployment-templates/README-DEPLOYMENT.md).
The repository contains two GitHub workflows for publishing new releases and
performing build validation for pull requests:

### Pulumi Internal
- Release workflow: `.github/workflows/release.yml`
- Pull Request validation: `.github/workflows/pull-request.yml`

In this section, we'll add the necessary configuration to work with GitHub
Actions for Pulumi's standard CI/CD workflows for providers.
The GitHub release workflow requires the following GitHub secrets (variables) to
be configured in the workflow envinronment. Refer to the [GitHub documentation](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions)
how to configure secrets and variables for workflows for any details.

1. Generate GitHub workflows per [the instructions in the ci-mgmt
repository](https://github.com/pulumi/ci-mgmt/) and copy to `.github/` in
this repository.
- `GITHUB_TOKEN`: The GitHhub is required to push a new release of the provider
to GitHub. Thus the GitHub token must include the permission `contents:
write`
- `NPM_TOKEN`: The token is used to authenticate towards NPMJS.com to push the NodeJS SDK
- `NUGET_PUBLISH_KEY`: The token is required to publish the dotnet SDK to nuget.org
- `PYPI_PASSWORD`: The token is used to publish the Python SDK on PyPi.org

1. Ensure that any required secrets are present as repository-level
[secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
in GitHub. These will be used by the integration tests during the CI/CD
process.

1. Repository settings: Toggle `Allow auto-merge` on in your provider repo to
automate GitHub Actions workflow updates.

## Final Steps

1. Ensure all required configurations (API keys, etc.) are documented in README.md.

1. If publishing the npm package fails during the "Publish SDKs" Action, perform the following steps:

1. Go to [NPM Packages](https://www.npmjs.com/) and sign in as pulumi-bot.

1. Click on the bot's profile pic and navigate to "Packages".
1. On the left, under "Organizations, click on the Pulumi organization.
1. On the last page of the listed packages, you should see the new package.
1. Under "Settings", set the Package Status to "public".
> **Note:**
> The release workflow will be triggred when a new version tag (format: `v*`) is
> pushed to the repository.

Now you are ready to use the provider, cut releases, and have some well-deserved :ice_cream:!
{% endif %}

4 changes: 2 additions & 2 deletions {{cookiecutter.provider}}/docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ layout: overview

The {{ cookiecutter.terraform_provider_name | capitalize }} provider for Pulumi can be used to provision any of the cloud resources available in {{ cookiecutter.terraform_provider_name | capitalize }}.

{%- if cookiecutter.provider_category != "utility" -%}
{% if cookiecutter.provider_category != "utility" %}
The {{ cookiecutter.terraform_provider_name | capitalize }} provider must be configured with credentials to deploy and update resources in {{ cookiecutter.terraform_provider_name | capitalize }}.
{%- endif -%}
{% endif %}
4 changes: 2 additions & 2 deletions {{cookiecutter.provider}}/go.work
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ go 1.18

use (
./provider
{%- if cookiecutter.terraform_provider_package_name.startswith("internal") %}
{% if cookiecutter.terraform_provider_package_name.startswith("internal") %}
./provider/shim
{%- endif %}
{% endif %}
// ******
// Add ./sdk folder when SDK has been published the first time
// ./sdk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@
package main

import (
{% if cookiecutter.terraform_sdk_version == "plugin-framework" -%}
{% if cookiecutter.terraform_sdk_version == "plugin-framework" %}
"context"
{% endif -%}
{% endif %}
_ "embed"

{% if cookiecutter.terraform_sdk_version != "plugin-framework" -%}
{% if cookiecutter.terraform_sdk_version != "plugin-framework" %}
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge"
"github.com/{{ cookiecutter.provider_github_organization }}/pulumi-{{ cookiecutter.terraform_provider_name }}/provider/pkg/version"
{% else %}
"github.com/pulumi/pulumi-terraform-bridge/pf/tfbridge"
{% endif -%}
{% endif %}
{{ cookiecutter.terraform_provider_name }} "github.com/{{ cookiecutter.provider_github_organization }}/pulumi-{{ cookiecutter.terraform_provider_name }}/provider"
)

//go:embed schema-embed.json
var pulumiSchema []byte

func main() {
{% if cookiecutter.terraform_sdk_version != "plugin-framework" -%}
{% if cookiecutter.terraform_sdk_version != "plugin-framework" %}
tfbridge.Main("{{ cookiecutter.terraform_provider_name }}", version.Version, {{ cookiecutter.terraform_provider_name }}.Provider(), pulumiSchema)
{% else -%}
{% else %}
meta := tfbridge.ProviderMetadata{PackageSchema: pulumiSchema}
tfbridge.Main(context.Background(), "{{ cookiecutter.terraform_provider_name }}", {{ cookiecutter.terraform_provider_name }}.Provider(), meta)
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ package main

import (
{{ cookiecutter.terraform_provider_name }} "github.com/{{ cookiecutter.provider_github_organization }}/pulumi-{{ cookiecutter.terraform_provider_name }}/provider"
{% if cookiecutter.terraform_sdk_version != "plugin-framework" -%}
{% if cookiecutter.terraform_sdk_version != "plugin-framework" %}
"github.com/{{ cookiecutter.provider_github_organization }}/pulumi-{{ cookiecutter.terraform_provider_name }}/provider/pkg/version"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfgen"
{% else -%}
{% else %}
"github.com/pulumi/pulumi-terraform-bridge/pf/tfgen"
{% endif -%}
{% endif %}
)

func main() {
{% if cookiecutter.terraform_sdk_version != "plugin-framework" -%}
{% if cookiecutter.terraform_sdk_version != "plugin-framework" %}
tfgen.Main("{{ cookiecutter.terraform_provider_name }}", version.Version, {{ cookiecutter.terraform_provider_name }}.Provider())
{% else -%}
{% else %}
tfgen.Main("{{ cookiecutter.terraform_provider_name }}", {{ cookiecutter.terraform_provider_name }}.Provider())
{% endif -%}
{% endif %}
}
Loading

0 comments on commit 72cd6ac

Please sign in to comment.