Skip to content

Commit

Permalink
feat(providers) initial implementation of pulumi provider
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Gershman <[email protected]>
  • Loading branch information
agershman committed Nov 3, 2023
1 parent 01b5ab5 commit 4dec338
Show file tree
Hide file tree
Showing 7 changed files with 424 additions and 42 deletions.
59 changes: 46 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ It supports various backends including:
- 1Password Connect
- [Doppler](https://doppler.com/)
- CredHub(Coming soon)
- Pulumi State

- Use `vals eval -f refs.yaml` to replace all the `ref`s in the file to actual values and secrets.
- Use `vals exec -f env.yaml -- <COMMAND>` to populate envvars and execute the command.
Expand Down Expand Up @@ -214,6 +215,7 @@ Please see the [relevant unit test cases](https://github.com/helmfile/vals/blob/
- [GitLab](#gitlab)
- [1Password Connect](#1password-connect)
- [Doppler](#doppler)
- [Pulumi State](#pulumi-state)

Please see [pkg/providers](https://github.com/helmfile/vals/tree/master/pkg/providers) for the implementations of all the providers. The package names corresponds to the URI schemes.

Expand All @@ -234,9 +236,9 @@ Please see [pkg/providers](https://github.com/helmfile/vals/tree/master/pkg/prov

The `auth_method` or `VAULT_AUTH_METHOD` envar configures how `vals` authenticates to HashiCorp Vault. Currently only these options are supported:

* [approle](https://www.vaultproject.io/docs/auth/approle#via-the-api): it requires you pass on a `role_id` together with a `secret_id`.
* [token](https://www.vaultproject.io/docs/auth/token): you just need creating and passing on a `VAULT_TOKEN`. If `VAULT_TOKEN` isn't set, token can be retrieved from `VAULT_TOKEN_FILE` env or `~/.vault-token` file.
* [kubernetes](https://www.vaultproject.io/docs/auth/kubernetes): if you're running inside a Kubernetes cluster, you can use this option. It requires you [configure](https://www.vaultproject.io/docs/auth/kubernetes#configuration) a policy, a Kubernetes role, a service account and a JWT token. The login path can also be set using the environment variable `VAULT_KUBERNETES_MOUNT_POINT` (default is `/kubernetes`). You must also set `role_id` or `VAULT_ROLE_ID` envar to the Kubernetes role.
- [approle](https://www.vaultproject.io/docs/auth/approle#via-the-api): it requires you pass on a `role_id` together with a `secret_id`.
- [token](https://www.vaultproject.io/docs/auth/token): you just need creating and passing on a `VAULT_TOKEN`. If `VAULT_TOKEN` isn't set, token can be retrieved from `VAULT_TOKEN_FILE` env or `~/.vault-token` file.
- [kubernetes](https://www.vaultproject.io/docs/auth/kubernetes): if you're running inside a Kubernetes cluster, you can use this option. It requires you [configure](https://www.vaultproject.io/docs/auth/kubernetes#configuration) a policy, a Kubernetes role, a service account and a JWT token. The login path can also be set using the environment variable `VAULT_KUBERNETES_MOUNT_POINT` (default is `/kubernetes`). You must also set `role_id` or `VAULT_ROLE_ID` envar to the Kubernetes role.

Examples:

Expand Down Expand Up @@ -328,6 +330,7 @@ Examples:
Decrypts the URL-safe base64-encoded ciphertext using AWS KMS. Note that URL-safe base64 encoding is
the same as "traditional" base64 encoding, except it uses `_` and `-` in place of `/` and `+`, respectively.
For example, to get a URL-safe base64-encoded ciphertext using the AWS CLI, you might run

```
aws kms encrypt \
--key-id alias/example \
Expand All @@ -338,15 +341,17 @@ aws kms encrypt \
```
Valid values for `alg` include:
* `SYMMETRIC_DEFAULT` (the default)
* `RSAES_OAEP_SHA_1`
* `RSAES_OAEP_SHA_256`
- `SYMMETRIC_DEFAULT` (the default)
- `RSAES_OAEP_SHA_1`
- `RSAES_OAEP_SHA_256`
Valid value formats for `key` include:
* A key id `1234abcd-12ab-34cd-56ef-1234567890ab`
* A URL-encoded key id ARN: `arn%3Aaws%3Akms%3Aus-east-2%3A111122223333%3Akey%2F1234abcd-12ab-34cd-56ef-1234567890ab`
* A URL-encoded key alias: `alias%2FExampleAlias`
* A URL-encoded key alias ARN: `arn%3Aaws%3Akms%3Aus-east-2%3A111122223333%3Aalias%2FExampleAlias`
- A key id `1234abcd-12ab-34cd-56ef-1234567890ab`
- A URL-encoded key id ARN: `arn%3Aaws%3Akms%3Aus-east-2%3A111122223333%3Akey%2F1234abcd-12ab-34cd-56ef-1234567890ab`
- A URL-encoded key alias: `alias%2FExampleAlias`
- A URL-encoded key alias ARN: `arn%3Aaws%3Akms%3Aus-east-2%3A111122223333%3Aalias%2FExampleAlias`
For ciphertext encrypted with a symmetric key, the `key` field may be omitted. For ciphertext
encrypted with a key in your own account, a plain key id or alias can be used. If the encryption
Expand All @@ -358,13 +363,15 @@ if the encryption context is `{"foo":"bar","hello":"world"}`, then you would rep
`context=%7B%22foo%22%3A%22bar%22%2C%22hello%22%2C%22world%22%7D`.
Examples:
- `ref+awskms://AQICAHhy_i8hQoGLOE46PVJyinH...WwHKT0i3H0znHRHwfyC7AGZ8ek=`
- `ref+awskms://AQICAHhy...nHRHwfyC7AGZ8ek=#/foo/bar`
- `ref+awskms://AQICAHhy...WwHKT0i3AGZ8ek=?context=%7B%22foo%22%3A%22bar%22%2C%22hello%22%2C%22world%22%7D`
- `ref+awskms://AQICAVJyinH...WwHKT0iC7AGZ8ek=?alg=RSAES_OAEP_SHA1&key=alias%2FExampleAlias`
- `ref+awskms://AQICA...fyC7AGZ8ek=?alg=RSAES_OAEP_SHA256&key=arn%3Aaws%3Akms%3Aus-east-2%3A111122223333%3Akey%2F1234abcd-12ab-34cd-56ef-1234567890ab&context=%7B%22foo%22%3A%22bar%22%2C%22hello%22%2C%22world%22%7D`
#### Google GCS
- `ref+gcs://BUCKET/KEY/OF/OBJECT[?generation=ID]`
- `ref+gcs://BUCKET/KEY/OF/OBJECT[?generation=ID]#/yaml_or_json_key/in/secret`
Expand Down Expand Up @@ -499,6 +506,7 @@ which is equivalent to the following input for `vals`:
```
$ echo 'foo: ref+tfstates3://bucket-with-terraform-state/terraform.tfstate/module.vpc.aws_vpc.this[0].arn' | vals eval -f -
```
### Terraform in AzureRM Blob storage (tfstateazurerm)
- `ref+tfstateazurerm://{resource_group_name}/{storage_account_name}/{container_name}/{blob_name}.tfstate/RESOURCE_NAME[?az_subscription_id=SUBSCRIPTION_ID]`
Expand Down Expand Up @@ -568,7 +576,6 @@ Examples:
- `ref+echo://foo/bar` generates `foo/bar`
- `ref+echo://foo/bar/baz#/foo/bar` generates `baz`. This works by the host and the path part `foo/bar/baz` generating an object `{"foo":{"bar":"baz"}}` and the fragment part `#/foo/bar` results in digging the object to obtain the value at `$.foo.bar`.
### File
File provider reads a local text file, or the value for the specific path in a YAML/JSON file.
Expand All @@ -592,6 +599,7 @@ Retrieve secrets from Azure Key Vault. Path is used to specify the vault and sec
VAULT-NAME is either a simple name if operating in AzureCloud (vault.azure.net) or the full endpoint dns name when operating against non-default azure clouds (US Gov Cloud, China Cloud, German Cloud).
Examples:
- `ref+azurekeyvault://my-vault/secret-a`
- `ref+azurekeyvault://my-vault/secret-a/ba4f196b15f644cd9e949896a21bab0d`
- `ref+azurekeyvault://gov-cloud-test.vault.usgovcloudapi.net/secret-b`
Expand All @@ -605,6 +613,7 @@ Other authentication methods require information to be passed in environment var
For example, if using client credentials the required env vars are `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TENANT_ID` and possibly `AZURE_ENVIRONMENT` in case of accessing an Azure GovCloud.
The order in which authentication methods are checked is:
1. Client credentials
2. Client certificate
3. Username/Password
Expand All @@ -624,7 +633,6 @@ Examples:
For this provider to work you require an [access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html) exported as the environment variable `GITLAB_TOKEN`.
- `ref+gitlab://my-gitlab-server.com/project_id/secret_name?[ssl_verify=false&scheme=https&api_version=v4]`
Examples:
Expand All @@ -636,6 +644,7 @@ Examples:
For this provider to work you require a working and accessible [1Password connect server](https://developer.1password.com/docs/connect).
The following env vars have to be configured:
- `OP_CONNECT_HOST`
- `OP_CONNET_TOKEN`
Expand All @@ -645,7 +654,7 @@ Vaults, items, sections and labels can be accessed by ID or by label/name (and I
If a section does not have a label the field is only accessible via the section ID. This does not hold true for some default fields which may have no section at all (e.g.username and password for a `Login` item).
*Caution: vals-expressions are parsed as URIs. For the 1Password connect provider the host component of the URI identifies the vault (by ID or name). Therefore vaults containing certain characters not allowed in the host component (e.g. whitespaces, see [RFC-3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2) for details) can only be accessed by ID.*
_Caution: vals-expressions are parsed as URIs. For the 1Password connect provider the host component of the URI identifies the vault (by ID or name). Therefore vaults containing certain characters not allowed in the host component (e.g. whitespaces, see [RFC-3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2) for details) can only be accessed by ID._
Examples:
Expand Down Expand Up @@ -675,6 +684,30 @@ Examples:
- `ref+doppler://MyProject/development/DB_PASSWORD` fetches the value of secret with name `DB_PASSWORD` for the project named `MyProject` and environment named `development`.
- `ref+doppler://MyProject/development/#DB_PASSWORD` fetches the value of secret with name `DB_PASSWORD` for the project named `MyProject` and environment named `development`.
### Pulumi State
Obtain value in state pulled from Pulumi Cloud REST API:
- `ref+pulumistateapi://RESOURCE_TYPE/RESOURCE_LOGICAL_NAME/ATTRIBUTE_TYPE/ATTRIBUTE_KEY_PATH?project=PROJECT&stack=STACK`
* `RESOURCE_TYPE` is a Pulumi [resource type](https://www.pulumi.com/docs/concepts/resources/names/#types) of the form `<package>:<module>:<typename>`, where colons (`:`) are replaced by underscores (`_`).
* `RESOURCE_LOGICAL_NAME` is the [logical name](https://www.pulumi.com/docs/concepts/resources/names/#logicalname) of the resource in the Pulumi program.
* `ATTRIBUTE_TYPE` is either `outputs` or `inputs`.
* `ATTRIBUTE_KEY_PATH` is a [GJSON](https://github.com/tidwall/gjson/blob/master/SYNTAX.md) expression that selects the desired attribute from the resource's inputs or outputs per the chosen `ATTRIBUTE_TYPE` value. You must encode any characters that would otherwise not comply with URI syntax, for example `#` becomes `%23`.
* `project` is the Pulumi project name.
* `stack` is the Pulumi stack name.
Environment variables:
- `PULUMI_API_ENDPOINT_URL` is the Pulumi API endpoint URL. Defaults to `https://api.pulumi.com`. You may also provide this as the `pulumi_api_endpoint_url` query parameter.
- `PULUMI_ACCESS_TOKEN` is the Pulumi access token to use for authentication.
- `PULUMI_ORGANIZATION` is the Pulumi organization to use for authentication. You may also provide this as an `organization` query parameter.
Examples:
- `ref+pulumistateapi://aws-native_s3_Bucket/my-bucket/outputs/bucketName?project=my-project&stack=my-stack`
- `ref+pulumistateapi://aws-native_s3_Bucket/my-bucket/outputs/tags.%23(key==SomeKey).value?project=my-project&stack=my-stack`
## Advanced Usages
### Discriminating config and secrets
Expand Down
21 changes: 15 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.0.0
github.com/DopplerHQ/cli v0.5.11-0.20230908185655-7aef4713e1a4
github.com/a8m/envsubst v1.3.0
github.com/aws/aws-sdk-go v1.43.43
github.com/aws/aws-sdk-go v1.44.298
github.com/fujiwara/tfstate-lookup v1.1.4
github.com/getsops/sops/v3 v3.8.0
github.com/google/go-cmp v0.5.9
github.com/hashicorp/golang-lru v0.5.4
github.com/hashicorp/vault/api v1.10.0
github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.17.0
golang.org/x/oauth2 v0.12.0
google.golang.org/api v0.141.0
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -30,15 +31,15 @@ require (
cloud.google.com/go/iam v1.1.1 // indirect
cloud.google.com/go/kms v1.15.2 // indirect
filippo.io/age v1.1.1 // indirect
github.com/AlecAivazis/survey/v2 v2.3.6 // indirect
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.1.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/autorest/mocks v0.4.2 // indirect
Expand Down Expand Up @@ -76,6 +77,7 @@ require (
github.com/fatih/color v1.15.0 // indirect
github.com/getsops/gopgagent v0.0.0-20170926210634-4d7ea76ff71a // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-test/deep v1.0.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
Expand All @@ -88,6 +90,7 @@ require (
github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.2.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
Expand All @@ -96,8 +99,10 @@ require (
github.com/hashicorp/go-slug v0.8.1 // indirect
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
github.com/hashicorp/go-tfe v1.2.0 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/itchyny/gojq v0.12.11 // indirect
github.com/itchyny/timefmt-go v0.1.5 // indirect
Expand All @@ -106,7 +111,7 @@ require (
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
Expand All @@ -120,25 +125,29 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/urfave/cli v1.22.14 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/tools v0.14.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/gookit/color.v1 v1.1.6 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
Loading

0 comments on commit 4dec338

Please sign in to comment.