├── .gitignore ├── README.md ├── manifest-example.yml └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.hcl 2 | vault 3 | vcap.json 4 | manifest.yml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vault on Cloud Foundry 2 | 3 | **This repository is not for production use.** 4 | 5 | This vault server uses MySQL as a storage backend. 6 | 7 | ## Create mysql instance 8 | 9 | 10 | If you are using [Pivotal Web Services](https://run.pivotal.io): 11 | 12 | ``` 13 | cf create-service cleardb spark vault-db 14 | ``` 15 | 16 | If your are using Pivotal Cloud Foundry: 17 | 18 | ``` 19 | cf create-service p-mysql 100mb-dev vault-db 20 | ``` 21 | 22 | ## Deploy Vault 23 | 24 | [Download Vault (Linux 64-bit)](https://www.vaultproject.io/downloads.html) and save the binary on this directory. 25 | 26 | ``` 27 | cp manifest-example.yml manifest.yml 28 | ``` 29 | 30 | Change `name` if needed, then 31 | 32 | ``` 33 | cf push 34 | ``` 35 | 36 | you can see vault has started successfully as following: 37 | 38 | ``` 39 | $ cf logs vault --recent 40 | 41 | 2020-02-23T19:49:13.61+0900 [CELL/0] OUT Cell 6d545859-b729-4434-8158-8d0ae0e3dd0a successfully created container for instance 2f6f4417-7bec-4292-5c1f-7252 42 | 2020-02-23T19:49:14.11+0900 [CELL/0] OUT Downloading droplet... 43 | 2020-02-23T19:49:18.60+0900 [CELL/0] OUT Downloaded droplet (45.5M) 44 | 2020-02-23T19:49:18.60+0900 [CELL/0] OUT Starting health monitoring of container 45 | 2020-02-23T19:49:29.21+0900 [APP/PROC/WEB/0] OUT detected cleardb 46 | 2020-02-23T19:49:30.04+0900 [APP/PROC/WEB/0] OUT #### Starting Vault... 47 | 2020-02-23T19:49:33.17+0900 [APP/PROC/WEB/0] OUT ==> Vault server configuration: 48 | 2020-02-23T19:49:33.20+0900 [APP/PROC/WEB/0] OUT Cgo: disabled 49 | 2020-02-23T19:49:33.31+0900 [APP/PROC/WEB/0] OUT Listener 1: tcp (addr: "0.0.0.0:8080", cluster address: "0.0.0.0:8081", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled") 50 | 2020-02-23T19:49:33.32+0900 [APP/PROC/WEB/0] OUT Log Level: info 51 | 2020-02-23T19:49:33.35+0900 [APP/PROC/WEB/0] OUT Mlock: supported: true, enabled: false 52 | 2020-02-23T19:49:33.37+0900 [APP/PROC/WEB/0] OUT Recovery Mode: false 53 | 2020-02-23T19:49:33.39+0900 [APP/PROC/WEB/0] OUT Storage: mysql (HA disabled) 54 | 2020-02-23T19:49:33.40+0900 [APP/PROC/WEB/0] OUT Version: Vault v1.3.2 55 | 2020-02-23T19:49:33.44+0900 [APP/PROC/WEB/0] OUT ==> Vault server started! Log data will stream in below: 56 | 2020-02-23T19:49:33.44+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:49:31.994Z [INFO] proxy environment: http_proxy= https_proxy= no_proxy= 57 | 2020-02-23T19:49:33.44+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:49:33.137Z [WARN] no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set 58 | 2020-02-23T19:49:34.78+0900 [CELL/0] OUT Container became healthy 59 | 2020-02-23T19:50:30.30+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:30.306Z [ERROR] core: no seal config found, can't determine if legacy or new-style shamir 60 | 2020-02-23T19:50:30.46+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:30.460Z [INFO] core: security barrier not initialized 61 | 2020-02-23T19:50:30.65+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:30.654Z [INFO] core: security barrier initialized: stored=1 shares=5 threshold=3 62 | 2020-02-23T19:50:30.83+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:30.830Z [INFO] core: post-unseal setup starting 63 | 2020-02-23T19:50:31.33+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.335Z [INFO] core: loaded wrapping token key 64 | 2020-02-23T19:50:31.33+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.337Z [INFO] core: successfully setup plugin catalog: plugin-directory= 65 | 2020-02-23T19:50:31.38+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.387Z [INFO] core: no mounts; adding default mount table 66 | 2020-02-23T19:50:31.45+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.450Z [INFO] core: successfully mounted backend: type=cubbyhole path=cubbyhole/ 67 | 2020-02-23T19:50:31.47+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.460Z [INFO] core: successfully mounted backend: type=system path=sys/ 68 | 2020-02-23T19:50:31.51+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:31.510Z [INFO] core: successfully mounted backend: type=identity path=identity/ 69 | 2020-02-23T19:50:32.14+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.142Z [INFO] core: successfully enabled credential backend: type=token path=token/ 70 | 2020-02-23T19:50:32.14+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.142Z [INFO] core: restoring leases 71 | 2020-02-23T19:50:32.14+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.143Z [INFO] rollback: starting rollback manager 72 | 2020-02-23T19:50:32.18+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.184Z [INFO] expiration: lease restore complete 73 | 2020-02-23T19:50:32.30+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.306Z [INFO] identity: entities restored 74 | 2020-02-23T19:50:32.32+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.324Z [INFO] identity: groups restored 75 | 2020-02-23T19:50:32.43+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.432Z [INFO] core: post-unseal setup complete 76 | 2020-02-23T19:50:32.51+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.514Z [INFO] core: root token generated 77 | 2020-02-23T19:50:32.51+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.514Z [INFO] core: pre-seal teardown starting 78 | 2020-02-23T19:50:32.51+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.514Z [INFO] rollback: stopping rollback manager 79 | 2020-02-23T19:50:32.51+0900 [APP/PROC/WEB/0] ERR 2020-02-23T10:50:32.519Z [INFO] core: pre-seal teardown complete 80 | ``` 81 | 82 | Now, you can access Vault via like `https://cf-vault.cfapps.io`. Subdomain should be different for your case. 83 | 84 | ## Initialize vault 85 | 86 | 87 | ``` 88 | export VAULT_ADDR=https://.cfapps.io 89 | vault operator init 90 | ``` 91 | 92 | you'll see five unseal keys and root token 93 | 94 | ``` 95 | Unseal Key 1: w6rUcrlOEd4tI0MNtCYxG2uUoGj8wG9euXm4RiHq7BDh 96 | Unseal Key 2: tkGGsCQJeNyORbz2uRyWjCq03kj/OPtGzmM/Bjv9+RTP 97 | Unseal Key 3: 584Sg15Itt8zJpiJOBh+1IVKp56Hv9FiryiK63dztA7C 98 | Unseal Key 4: +ZqZetBMtslvfKfWJ0uCAup51Z5Qx5qobzVjxwqD2rlz 99 | Unseal Key 5: TFYSjAWOjHBARjXBblZuVovtxNnHnSuuHwBthhym8VxL 100 | Initial Root Token: db2c7fae-7162-d09e-7901-66d47360c62f 101 | ``` 102 | 103 | 104 | Unseal Vault with three of five unseal keys, for example: 105 | 106 | ``` 107 | vault operator unseal w6rUcrlOEd4tI0MNtCYxG2uUoGj8wG9euXm4RiHq7BDh 108 | vault operator unseal tkGGsCQJeNyORbz2uRyWjCq03kj/OPtGzmM/Bjv9+RTP 109 | vault operator unseal 584Sg15Itt8zJpiJOBh+1IVKp56Hv9FiryiK63dztA7C 110 | ``` 111 | 112 | Authenticate with the root token, for example: 113 | 114 | ``` 115 | vault login db2c7fae-7162-d09e-7901-66d47360c62f 116 | ``` 117 | 118 | Finally, you can read and write Valut :) 119 | 120 | ``` 121 | vault secrets enable -path=kv kv 122 | vault kv put kv/hello target=world 123 | ``` 124 | 125 | ## Unseal when restarting 126 | 127 | Because Vault seals when it restarts, you need to unseal automatically in order to keep Vault available in CF environment. 128 | 129 | If you set environment variables `VAULT_UNSEAL_KEY1`, `VAULT_UNSEAL_KEY2` and `VAULT_UNSEAL_KEY3`, Vaule will be unsealed at the start up 130 | 131 | For example: 132 | 133 | ``` 134 | cf set-env vault VAULT_UNSEAL_KEY1 w6rUcrlOEd4tI0MNtCYxG2uUoGj8wG9euXm4RiHq7BDh 135 | cf set-env vault VAULT_UNSEAL_KEY2 tkGGsCQJeNyORbz2uRyWjCq03kj/OPtGzmM/Bjv9+RTP 136 | cf set-env vault VAULT_UNSEAL_KEY3 584Sg15Itt8zJpiJOBh+1IVKp56Hv9FiryiK63dztA7 137 | ``` 138 | 139 | Even if you do `cf restart vault` or `cf restage vault`, `vault` will be available. 140 | Of course you can set these variables in your `manifest.yml`. 141 | 142 | Note that this way is [not recommended](https://www.vaultproject.io/docs/concepts/seal.html#unsealing) by Hashicorp. 143 | 144 | ## Deploy service broker 145 | 146 | You can also deploy [Vault Service Broker](https://github.com/hashicorp/cf-vault-service-broker) prodivedby Hashicorp easily :) 147 | -------------------------------------------------------------------------------- /manifest-example.yml: -------------------------------------------------------------------------------- 1 | applications: 2 | - name: vault 3 | random-route: true 4 | buildpack: binary_buildpack 5 | memory: 64m 6 | command: './run.sh' 7 | services: 8 | - vault-db 9 | # for PCF 10 | # cf cs p-mysql 100mb-dev vault-db 11 | # for PWS 12 | # cf cs cleardb spark vault-db 13 | #env: 14 | # VAULT_UNSEAL_KEY1: w6rUcrlOEd4tI0MNtCYxG2uUoGj8wG9euXm4RiHq7BDh 15 | # VAULT_UNSEAL_KEY2: tkGGsCQJeNyORbz2uRyWjCq03kj/OPtGzmM/Bjv9+RTP 16 | # VAULT_UNSEAL_KEY3: 584Sg15Itt8zJpiJOBh+1IVKp56Hv9FiryiK63dztA7C 17 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CLEARDB=`echo $VCAP_SERVICES | grep "cleardb"` 4 | PMYSQL=`echo $VCAP_SERVICES | grep "p-mysql"` 5 | 6 | if [ "$CLEARDB" != "" ];then 7 | SERVICE="cleardb" 8 | elif [ "$PMYSQL" != "" ]; then 9 | SERVICE="p-mysql" 10 | fi 11 | 12 | echo "detected $SERVICE" 13 | 14 | HOSTNAME=`echo $VCAP_SERVICES | jq -r '.["'$SERVICE'"][0].credentials.hostname'` 15 | PASSWORD=`echo $VCAP_SERVICES | jq -r '.["'$SERVICE'"][0].credentials.password'` 16 | PORT=`echo $VCAP_SERVICES | jq -r '.["'$SERVICE'"][0].credentials.port'` 17 | USERNAME=`echo $VCAP_SERVICES | jq -r '.["'$SERVICE'"][0].credentials.username'` 18 | DATABASE=`echo $VCAP_SERVICES | jq -r '.["'$SERVICE'"][0].credentials.name'` 19 | 20 | cat < cf.hcl 21 | ui = true 22 | disable_mlock = true 23 | storage "mysql" { 24 | username = "$USERNAME" 25 | password = "$PASSWORD" 26 | address = "$HOSTNAME:$PORT" 27 | database = "$DATABASE" 28 | table = "vault" 29 | max_parallel = 4 30 | } 31 | listener "tcp" { 32 | address = "0.0.0.0:8080" 33 | tls_disable = 1 34 | } 35 | EOF 36 | 37 | echo "#### Starting Vault..." 38 | 39 | ./vault server -config=cf.hcl & 40 | 41 | if [ "$VAULT_UNSEAL_KEY1" != "" ];then 42 | export VAULT_ADDR='http://127.0.0.1:8080' 43 | echo "#### Waiting..." 44 | sleep 1 45 | echo "#### Unsealing..." 46 | if [ "$VAULT_UNSEAL_KEY1" != "" ];then 47 | ./vault operator unseal $VAULT_UNSEAL_KEY1 48 | fi 49 | if [ "$VAULT_UNSEAL_KEY2" != "" ];then 50 | ./vault operator unseal $VAULT_UNSEAL_KEY2 51 | fi 52 | if [ "$VAULT_UNSEAL_KEY3" != "" ];then 53 | ./vault operator unseal $VAULT_UNSEAL_KEY3 54 | fi 55 | fi --------------------------------------------------------------------------------