This tutorial uses Terraform to bootstrap a HashiCorp Vault server running in dev mode and walks through how to enable the Azure Auth Method that can be used to authenticate with Vault.
Install Azure CLI
brew update && brew install azure-cli
Perform a login into Microsoft Azure account
az login
Once logged in, list all subscriptions
az account list
[
{
"cloudName": "AzureCloud",
"id": "00000000-0000-0000-0000-000000000000",
"isDefault": true,
"name": "PAYG Subscription",
"state": "Enabled",
"tenantId": "00000000-0000-0000-0000-000000000000",
"user": {
"name": "user@example.com",
"type": "user"
}
}
]
Set a default subscription using the id
field from the above response. You may want to use one of the subscriptions
as the default subscription to use with Terraform.
az account set --subscription="$SUBSCRIPTION_ID"
Clone git repository
git clone https://github.com/anubhavmishra/vault-on-azure.git
Create Azure infrastructure for the vault demo
cd vault-on-azure
Initialize Terraform
terraform init
Execute Terraform Apply
terraform apply
Enter "yes" to create the resources
After the terraform apply
is complete, expect an output like this
Apply complete! Resources: 5 added, 0 changed, 2 destroyed.
Outputs:
vault-demo_private_ip = x.x.x.x
vault-demo_public_ip = x.x.x.x
vault-demo_ssh = ssh azureuser@x.x.x.x -i /Users/username/projects/terraform-vault-azurerm/.ssh/id_rsa
SSH into the vault demo server
$(terraform output vault-demo_ssh)
The above command will also create a tunnel from the local machine where Terraform is being executed from to the virtual machine running Vault.
Perform a vault root login
vault login "root"
WARNING: This is not a best practice for running Vault in production. This is only done for the demo purposes.
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token root
token_accessor ddb2366e-e853-e26d-b19d-df56ba89bce2
token_duration ∞
token_renewable false
token_policies [root]
On local machine, open http://localhost:8200 in the browser
Open a new terminal window to run the command below.
open http://localhost:8200
Login with password root
Follow the docs here to enable and configure the Azure Auth Method using the CLI.
Follow the steps below for configuring it using the UI
- Go to "Settings" in the Vault UI located at http://localhost:8200/ui/vault/secrets.
- Select "Auth Methods" from the left sidebar.
- Select "Azure" from the "Type dropdown.
- In the "Tenant ID" field, enter the Directory ID from the Active Directory Menu blade in the "Properties" section of the Azure console.
- In the "Resource" field, enter "https://management.azure.com/".
- Expand the "Azure Options" section and enter the "Client ID" and "Client secret" for the application.
- Click on the "Enable Method" button.
You have successfully mounted the Azure Auth Method.
SSH into the vault demo server
$(terraform output vault-demo_ssh)
The above command will also create a tunnel from the local machine where Terraform is being executed from to the virtual machine running Vault.
Perform a vault root login
vault login "root"
Write a dev policy file
echo 'path "secret/example" {
capabilities = ["read", "list"]
}' > dev.hcl
Create a policy called "dev" in vault
vault policy write dev dev.hcl
Create a role called "dev-role" in vault and associate the "dev" policy to it
vault write auth/azure/role/dev-role \
policies="dev" \
bound_subscription_ids=SUBSCRIPTION_ID \
bound_resource_groups=azure-vault-demo \
ttl=24h \
max_ttl=48h
Store some example secrets into vault
vault kv put secret/example foo=bar
Read the secrets using the CLI
vault kv get secret/example
Expected output
====== Metadata ======
Key Value
--- -----
created_time 2018-05-23T02:07:57.96424783Z
deletion_time n/a
destroyed false
version 1
=== Data ===
Key Value
--- -----
foo bar
Get JWT token from Azure Resource Manager
curl -s 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F' -H Metadata:true
Expected output
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6ImlCakwxUmNxemhpeTRmcHhJeGRacW9oTTJZayIsImtpZCI6ImlCakwxUmNxemhpeTRmcHhJeGRacW9oTTJZayJ9.eyJhdWQiOiJodHRwczovL21hbmFnZW1lbnQuYXp1cmUuY29tLyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzBlM2UyZTg4LThjYWYtNDFjYS1iNGRhLWUzYjMzYjZjNTJlYy8iLCJpYXQiOjE1MjcwNDA2OTIsIm5iZiI6MTUyNzA0MDY5MiwiZXhwIjoxNTI3MDQ0NTkyLCJhaW8iOiJZMmRnWUdqTVk5ZzMvU0x2cjRmTS96c0QyellvO4Qf2sQHeqYW3YyxcWxXrAyohi-0SLgQ34rOXDUKyNpPY1mFtRJLRk_mx_jYJcJVW_PDXsJYAitvsoI51DIqS0ZqPWcdKN0TGYOtzmzSUO0rUqJslXgEHET-7Fn2huMHeuk99fmtB_t15-8IeEpgNadycJvdvSbq3c0Zv4WNRNSO4zcRcmd8nAHi3Xqw3K8yulDk9jxDmHtEtSsekU_gupt0XuBnzMeRViN6woeiQa8PfI4Zzz6Fp-Viep_5a8jVz5_SPhvhbF57On5he3LYK3fxGBSYw-29w5lGNqhdj_rUgb17cGvm9wMS-SgvcW6RvVXuzkNszwAjiOjQYtTf2g
Perform vault login
vault write auth/azure/login role="dev-role" jwt="JWT_TOKEN_HERE" subscription_id="SUBSCRIPTION_ID" resource_group_name="RESOURCE_GROUP_NAME" vm_name="VM_NAME"
Expected output
Key Value
--- -----
token 430a2bfc-f660-e867-092a-bdd69b629e19
token_accessor f3988a11-c099-1926-27c4-1274b9cce50a
token_duration 24h
token_renewable true
token_policies [default dev]
token_meta_role dev-role
In order to auto inject the vault token into the environment, use the command below
export VAULT_TOKEN=$(vault write -field=token auth/azure/login role="dev-role" jwt="" subscription_id="SUBSCRIPTION_ID" resource_group_name="RESOURCE_GROUP_NAME" vm_name="VM_NAME")
The field=token
option filters the results and only returns the vault token.
Read secrets for the example application
vault kv get secret/example
Expected output
====== Metadata ======
Key Value
--- -----
created_time 2018-05-23T02:07:57.96424783Z
deletion_time n/a
destroyed false
version 1
=== Data ===
Key Value
--- -----
foo bar
Try reading a secret that isn't specified in the vault policy
vault kv get secret/foo
Expected output
Error reading secret/data/foo: Error making API request.
URL: GET http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:
* permission denied