Skip to content

Commit aefa9e5

Browse files
authored
Add examples for secrets providers (#630)
* Add examples for secrets providers * Address feedback Remove copy-paste errors from Azure README.md Rename Azure project to use keyvault name
1 parent 90f6fa5 commit aefa9e5

19 files changed

+534
-0
lines changed

Diff for: secrets-provider/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Setting up secrets providers for Pulumi
2+
3+
Pulumi supports [secrets-providers](https://www.pulumi.com/docs/intro/concepts/config/#configuring-secrets-encryption) which allow you to encrypt the secrets you store in the Pulumi statefile.
4+
5+
This example shows how to set up the secrets for each cloud and walks through initializing your stack using the different secrets providers.
6+

Diff for: secrets-provider/aws/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/bin/
2+
/node_modules/
3+
Pulumi.*.yaml

Diff for: secrets-provider/aws/Pulumi.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: pulumi-aws-kms
2+
runtime: nodejs
3+
description: Minimal config which shows how AWS encryption support works

Diff for: secrets-provider/aws/README.md

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Pulumi AWS KMS Encryption
2+
3+
Pulumi allows you to use KMS encryption from your cloud provider to encrypt any secrets stored in the backend.
4+
5+
This example shows how this might be done for AWS KMS. It creates an S3 bucket with a single file that has a "secret" value.
6+
7+
# Getting Started
8+
9+
To use this example, perform the following steps. This examples assumes you have the pulumi-cli installed and the aws-cli installed.
10+
11+
You should also ensure you have the correct `AWS_PROFILE` set:
12+
13+
```bash
14+
export AWS_PROFILE="myaccount"
15+
```
16+
17+
## Create an AWS KMS Key
18+
19+
```bash
20+
aws kms create-key --tags TagKey=Purpose,TagValue="Pulumi Secret Encryption" --description "Pulumi secret encryption Key"
21+
22+
# Optionally create an alias to this key
23+
aws kms create-alias --alias-name alias/pulumi-encryption --target-key-id $MY_KEY_ID
24+
```
25+
26+
_When creating your key, be sure to specify a sane key policy that restricts access to only those that need to use the key_
27+
28+
## Initialize your stack
29+
30+
Initialize your stack with Pulumi and ensure you set the `--secrets-provider` flag:
31+
32+
```bash
33+
# Using your alias
34+
pulumi stack init $PULUMI_ORG_NAME/$PULUMI_STACK_NAME --secrets-provider="awskms://alias/pulumi-encryption?region=us-west-2"
35+
36+
# Using your key id
37+
pulumi stack init $PULUMI_ORG_NAME/$PULUMI_STACK_NAME --secrets-provider="awskms://1234abcd-12ab-34cd-56ef-1234567890ab?region=us-west-2"
38+
```
39+
40+
## Verify your stack settings
41+
42+
If everything has worked as expected, you should be able to verify in your stack settings that the secretsprovider is set:
43+
44+
```bash
45+
cat Pulumi.$PULUMI_STACK_NAME.yaml
46+
secretsprovider: awskms://alias/pulumi-encryption?region=us-west-2
47+
encryptedkey: AQICAHiGajWxHHTBJxo1FU9BOztzLzxEXpr02SgLetPNGfdfLAG7c5ylmHRJJRz5jtaj2LtzAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMT+iyFkgT4bmdja9WAgEQgDuVYN+iLr6sdyFNGXJS8GfjKiqMBXVvwmn9byd3ywCfJwMsuDnpqAWSmquV5eoLBdPEEOY1D/TuBQuCLQ==
48+
```
49+
50+
## Set your configuration settings
51+
52+
```bash
53+
pulumi config set aws:region us-west-2
54+
# Set the bucketname & the secret contents
55+
pulumi config set bucketName pulumi-lbriggs
56+
pulumi config set --secret secretValue "correct-horse-battery-stable"
57+
```
58+
59+
## Create the stack
60+
61+
```bash
62+
# This will create the stack without prompting, be aware!
63+
pulumi up --yes
64+
Previewing update (aws-kms):
65+
Type Name Plan
66+
+ pulumi:pulumi:Stack pulumi-aws-kms-aws-kms create
67+
+ ├─ aws:s3:Bucket bucket create
68+
+ └─ aws:s3:BucketObject secret create
69+
70+
Resources:
71+
+ 3 to create
72+
73+
Updating (aws-kms):
74+
Type Name Status
75+
+ pulumi:pulumi:Stack pulumi-aws-kms-aws-kms created
76+
+ ├─ aws:s3:Bucket bucket created
77+
+ └─ aws:s3:BucketObject secret created
78+
79+
Outputs:
80+
bucketId: "pulumi-lbriggs"
81+
secretId: "[secret]"
82+
83+
Resources:
84+
+ 3 created
85+
86+
Duration: 8s
87+
88+
Permalink: <redacted>
89+
```
90+
91+
You'll notice the secret value is also omitted from the output!
92+
93+
## Verify the encryption
94+
95+
A quick way to verify if the encryption is using the AWS KMS key is to remove your `AWS_PROFILE` setting:
96+
97+
```bash
98+
unset AWS_PROFILE
99+
pulumi up --yes
100+
error: getting secrets manager: secrets (code=Unknown): InvalidSignatureException: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
101+
status code: 400, request id: 35ff51c6-ef88-4c06-9146-361231b8fd4a
102+
```
103+
104+
105+
106+
107+
108+

Diff for: secrets-provider/aws/index.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as pulumi from "@pulumi/pulumi";
2+
import * as aws from "@pulumi/aws";
3+
import * as awsx from "@pulumi/awsx";
4+
import { secret } from "@pulumi/pulumi";
5+
6+
// Import config
7+
const config = new pulumi.Config();
8+
9+
// Make the bucketName configurable
10+
const bucketName = config.require('bucketName');
11+
const secretValue = config.requireSecret('secretValue');
12+
13+
// Create a private bucket
14+
const bucket = new aws.s3.Bucket("bucket", {
15+
bucket: bucketName,
16+
acl: "private",
17+
});
18+
19+
// Create an object from the secret value
20+
const superSecretObject = new aws.s3.BucketObject("secret", {
21+
bucket: bucket.id,
22+
key: "secret",
23+
content: secretValue,
24+
})
25+
26+
// Export the name of the bucket and the secretValue
27+
export const bucketId = bucket.id;
28+
export const secretId = secretValue;

Diff for: secrets-provider/aws/package.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "pulumi-aws-kmstest",
3+
"devDependencies": {
4+
"@types/node": "^8.0.0"
5+
},
6+
"dependencies": {
7+
"@pulumi/pulumi": "^1.0.0",
8+
"@pulumi/aws": "^1.0.0",
9+
"@pulumi/awsx": "^0.18.10"
10+
}
11+
}

Diff for: secrets-provider/aws/tsconfig.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"outDir": "bin",
5+
"target": "es2016",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"sourceMap": true,
9+
"experimentalDecorators": true,
10+
"pretty": true,
11+
"noFallthroughCasesInSwitch": true,
12+
"noImplicitReturns": true,
13+
"forceConsistentCasingInFileNames": true
14+
},
15+
"files": [
16+
"index.ts"
17+
]
18+
}

Diff for: secrets-provider/azure/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/bin/
2+
/node_modules/

Diff for: secrets-provider/azure/Pulumi.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: pulumi-azure-keyvault
2+
runtime: nodejs
3+
description: Minimal config which shows how Azure encryption support works

Diff for: secrets-provider/azure/README.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Pulumi Azure KMS Encryption
2+
3+
Pulumi allows you to use Azure Keyvault encryption from your cloud provider to encrypt any secrets stored in the backend.
4+
5+
This example shows how this might be done for Azure Keyvault. It creates a storage bucket with a single file that has a "secret" value.
6+
7+
# Getting Started
8+
9+
To use this example, perform the following steps. This examples assumes you have the pulumi-cli installed and the Azure CLI installed.
10+
11+
You should also ensure:
12+
13+
* You azure command line tool installed
14+
* You are logging in via the `az` command line tool.
15+
* You have created a resource-group
16+
* You must have the environment variable `AZURE_KEYVAULT_AUTH_VIA_CLI` set to `true` eg: `export AZURE_KEYVAULT_AUTH_VIA_CLI=true`
17+
18+
## Create an Azure Keyvault Key
19+
20+
```bash
21+
# First, create a keyvault
22+
az keyvault create -l westus -n pulumi --resource-group $RESOURCE_GROUP_NAME
23+
24+
# Then, create a key
25+
az keyvault key create --name pulumi-secret --vault-name pulumi
26+
27+
# Finally, set the relevant permissions on the keyvault
28+
az keyvault set-policy --name pulumi --object-id $YOUR_OBJECT_ID --key-permissions decrypt get create delete list update import backup restore recover
29+
```
30+
31+
_When creating your key, be sure to specify a permissions that restricts access to only those that need to use the key_
32+
33+
## Initialize your stack
34+
35+
Initialize your stack with Pulumi and ensure you set the `--secrets-provider` flag:
36+
37+
```bash
38+
# Using your vault and key name
39+
pulumi stack init $PULUMI_ORG_NAME/$PULUMI_STACK_NAME --secrets-provider="azurekeyvault://pulumi.vault.azure.net/keys/pulumi-secret"
40+
```
41+
42+
## Verify your stack settings
43+
44+
If everything has worked as expected, you should be able to verify in your stack settings that the secretsprovider is set:
45+
46+
```bash
47+
cat Pulumi.$PULUMI_STACK_NAME.yaml
48+
secretsprovider: azurekeyvault://pulumi.vault.azure.net/keys/pulumi-secret/b636b47f2b474b2a8de3526561eae81b
49+
encryptedkey: Q2U5a1ZuTWsxLXVWOFdhVEdfaGExdWR1SzhzTlVFMldhWGlxU3RJVVdUWFJBcmM4M1ZlYzZOVVlpU3J2dW1NX2RIelMwV1h4el9hSjFibjcwdjVXcEgxZVlFa2c1LTlGUTBwX2ZnamcyNXh0V2RnYXlKaUNWSzd0VmlhY0ZyT2NCNGJ2SG40NkE4OFR2d0NWVzVEOUZOaUpGNm03TTlLUEl4VC0tbG9fYUJSSUlrZDJuUmNxVTJ2cWxDUjYtdVJYYjJKUjFoTlRYYkNaaEVTUzY4dGtNajZNRXBOQ1k4OGc4d0RTeUVBVGhweEswbUVXc3RaaGUtdnpQdktVY2tFUGFCVkdOaHZHOU1SYU91RWJ6QVZnLUtVdExHYlFHd19vUU15T3I4d3ZvajdJQ0liS0QtUTNLY0h4Q0JsMGNjd1A5ZXNWRUNNQ0tQZGhPY1cySTJwU1BR
50+
51+
```
52+
53+
## Set your configuration settings
54+
55+
```bash
56+
pulumi config set azure:location westus
57+
# Set the bucketname & the secret contents
58+
pulumi config set bucketName pulumilbriggs
59+
pulumi config set --secret secretValue "correct-horse-battery-stable"
60+
```
61+
62+
## Create the stack
63+
64+
```bash
65+
# This will create the stack without prompting, be aware!
66+
Previewing update (azure-keyvault):
67+
Type Name Plan
68+
pulumi:pulumi:Stack pulumi-azure-keyvault-azure-keyvault
69+
+ ├─ azure:core:ResourceGroup resourceGroup create
70+
+ ├─ azure:storage:Account storage create
71+
+ ├─ azure:storage:Container container create
72+
+ └─ azure:storage:Blob blob create
73+
74+
Outputs:
75+
+ connectionString: output<string>
76+
77+
Resources:
78+
+ 4 to create
79+
1 unchanged
80+
81+
Updating (azure-keyvault):
82+
Type Name Status
83+
pulumi:pulumi:Stack pulumi-azure-keyvault-azure-keyvault
84+
+ ├─ azure:core:ResourceGroup resourceGroup created
85+
+ ├─ azure:storage:Account storage created
86+
+ ├─ azure:storage:Container container created
87+
+ └─ azure:storage:Blob blob created
88+
89+
Outputs:
90+
+ connectionString: "DefaultEndpointsProtocol=https;AccountName=pulumilbriggs;AccountKey=Efa63L/xDstQgyvgsYHZqzl3oIlQA4scS4NeX/O1TeBI3mbwMcKxiHIkAGkwJj21EPzHebiuAUM09i7dVv3f/A==;EndpointSuffix=core.windows.net"
91+
92+
Resources:
93+
+ 4 created
94+
1 unchanged
95+
96+
Duration: 31s
97+
98+
Permalink: https://app.pulumi.com/jaxxstorm/pulumi-azure-keyvault/azure-keyvault/updates/3
99+
```
100+
101+
You'll notice the secret value is also omitted from the output!
102+
103+
## Verify the encryption
104+
105+
A quick way to verify if the encryption is using the Azure Keyvault key is to remove your application credentials temporarily:
106+
107+
```
108+
unset AZURE_KEYVAULT_AUTH_VIA_CLI
109+
```

Diff for: secrets-provider/azure/index.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as pulumi from "@pulumi/pulumi";
2+
import * as azure from "@pulumi/azure";
3+
4+
const config = new pulumi.Config();
5+
6+
// Make the bucketName configurable
7+
const bucketName = config.require('bucketName');
8+
const secretValue = config.requireSecret('secretValue');
9+
10+
// Create an Azure Resource Group
11+
const resourceGroup = new azure.core.ResourceGroup("resourceGroup", {
12+
name: "lbriggs-pulumi"
13+
});
14+
15+
// Create an Azure resource (Storage Account)
16+
const account = new azure.storage.Account("storage", {
17+
name: bucketName,
18+
// The location for the storage account will be derived automatically from the resource group.
19+
resourceGroupName: resourceGroup.name,
20+
accountTier: "Standard",
21+
accountReplicationType: "LRS",
22+
});
23+
24+
const container = new azure.storage.Container("container", {
25+
name: bucketName,
26+
storageAccountName: account.name,
27+
})
28+
29+
const blob = new azure.storage.Blob("blob", {
30+
storageAccountName: account.name,
31+
storageContainerName: container.name,
32+
sourceContent: secretValue,
33+
type: "Block",
34+
})
35+
36+
37+
// Export the connection string for the storage account
38+
export const connectionString = account.primaryConnectionString;
39+
40+

Diff for: secrets-provider/azure/package.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "pulumi-azure-keyvault",
3+
"devDependencies": {
4+
"@types/node": "^8.0.0"
5+
},
6+
"dependencies": {
7+
"@pulumi/pulumi": "^1.0.0",
8+
"@pulumi/azure": "^2.0.0"
9+
}
10+
}

Diff for: secrets-provider/azure/tsconfig.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"strict": true,
4+
"outDir": "bin",
5+
"target": "es2016",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"sourceMap": true,
9+
"experimentalDecorators": true,
10+
"pretty": true,
11+
"noFallthroughCasesInSwitch": true,
12+
"noImplicitReturns": true,
13+
"forceConsistentCasingInFileNames": true
14+
},
15+
"files": [
16+
"index.ts"
17+
]
18+
}

Diff for: secrets-provider/gcloud/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/bin/
2+
/node_modules/

Diff for: secrets-provider/gcloud/Pulumi.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: pulumi-gcloud-kms
2+
runtime: nodejs
3+
description: Minimal config to check gcloud encryption support

0 commit comments

Comments
 (0)