forked from hashicorp/vault-guides
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Learn] Vault Agent guide (hashicorp#80)
* Terraform for Vault Agent guide * Added the demo steps * Added a note
- Loading branch information
Showing
14 changed files
with
1,300 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Compiled files | ||
*.tfstate | ||
*.tfstate.* | ||
|
||
# Directories | ||
.terraform/ | ||
.vagrant/ | ||
|
||
# Terraform Variables | ||
*.tfvars | ||
|
||
# SSH Keys | ||
*.pem | ||
|
||
# Backup files | ||
*.bak | ||
|
||
# Ignored Terraform files | ||
*gitignore*.tf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
# Vault Agent Demo | ||
|
||
These assets are provided to provision AWS resources to perform the steps described in the [Vault Agent](https://deploy-preview-257--hashicorp-learn.netlify.com/vault/identity-access-management/vault-agent) guide. | ||
|
||
--- | ||
|
||
**NOTE:** The example Terraform in this repository is created for the demo purpose, and not suitable for production use. For production deployment, refer the following examples: | ||
|
||
- [operations/provision-vault](https://github.com/hashicorp/vault-guides/tree/master/operations/provision-vault) | ||
- [Terraform Module Registry](https://registry.terraform.io/modules/hashicorp/vault/aws/0.10.3) | ||
|
||
|
||
## Demo Steps | ||
|
||
1. Set this location as your working directory | ||
|
||
1. Set your AWS credentials as environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` | ||
|
||
1. Set the Terraform variable values in a file named `terraform.tfvars` (use `terraform.tfvars.example` as a base) | ||
|
||
```shell | ||
# SSH key name to access EC2 instances (should already exist) | ||
key_name = "vault-test" | ||
|
||
# All resources will be tagged with this | ||
environment_name = "va-demo" | ||
|
||
# If you want to use a different AWS region | ||
aws_region = "us-west-1" | ||
availability_zones = "us-west-1a" | ||
``` | ||
|
||
1. Run Terraform: | ||
|
||
```shell | ||
# Pull necessary plugins | ||
$ terraform init | ||
$ terraform plan | ||
# Output provides the SSH instruction | ||
$ terraform apply | ||
``` | ||
|
||
1. SSH into the Vault **server** instance: `ssh -i <path_to_key> ubuntu@<public_ip_of_server>` | ||
|
||
1. On the **server** instance, run the following commands: | ||
|
||
```shell | ||
# At this point, Vault hasn't been initialized | ||
$ vault status | ||
# Initialize Vault | ||
$ vault operator init -stored-shares=1 -recovery-shares=1 \ | ||
-recovery-threshold=1 -key-shares=1 -key-threshold=1 > key.txt | ||
# Auto-unseal with AWS KMS is configured. So, just re-start the server | ||
$ sudo systemctl restart vault | ||
# Log in with initial root token | ||
$ vault login $(grep 'Initial Root Token:' key.txt | awk '{print $NF}') | ||
# Create a policy file | ||
$ tee myapp.hcl <<EOF | ||
path "secret/myapp/*" { | ||
capabilities = ["read", "list"] | ||
} | ||
EOF | ||
# Create a policy named, 'myapp' | ||
$ vault policy write myapp myapp.hcl | ||
# Write some secrets in 'secret/app/config' path | ||
$ vault kv put secret/myapp/config \ | ||
ttl='30s' \ | ||
username='appuser' \ | ||
password='suP3rsec(et!' | ||
# Enable aws auth method | ||
$ vault auth enable aws | ||
# Configure aws auth method | ||
$ vault write -force auth/aws/config/client | ||
# Be sure to get the Role ARN for ${var.environment_name}-vault-client, and replace <ROLE_ARN> | ||
$ vault write auth/aws/role/dev-role-iam auth_type=iam \ | ||
bound_iam_principal_arn=<ROLE_ARN> \ | ||
policies=myapp \ | ||
ttl=24h | ||
``` | ||
1. SSH into the Vault **client** instance: `ssh -i <path_to_key> ubuntu@<public_ip_of_client>` | ||
1. On the **client** instance, run the following commands: | ||
```shell | ||
# Create the Vault Agent configuration file | ||
$ tee /home/ubuntu/auto-auth-conf.hcl <<EOF | ||
exit_after_auth = true | ||
pid_file = "./pidfile" | ||
auto_auth { | ||
method "aws" { | ||
mount_path = "auth/aws" | ||
config = { | ||
type = "iam" | ||
role = "dev-role-iam" | ||
} | ||
} | ||
sink "file" { | ||
config = { | ||
path = "/home/ubuntu/vault-token-via-agent" | ||
} | ||
} | ||
} | ||
EOF | ||
# Run Vault Agent | ||
$ vault agent -config=/home/ubuntu/auto-auth-conf.hcl -log-level=debug | ||
``` | ||
1. Verify that the Auto-Auth works: | ||
```shell | ||
# Verify that a token was written to the configured sink location | ||
$ more vault-token-via-agent | ||
# Test to make sure that the token has appropriate policy attached | ||
$ curl --header "X-Vault-Token: $(cat /home/ubuntu/vault-token-via-agent)" \ | ||
$VAULT_ADDR/v1/secret/myapp/config | jq | ||
``` | ||
1. To demonstrate the Auto-Auth with response-wrapped token, execute the following command on the **client**. | ||
```shell | ||
# Add 'wrap_ttl' in the sink block | ||
$ tee /home/ubuntu/auto-auth-conf.hcl <<EOF | ||
exit_after_auth = true | ||
pid_file = "./pidfile" | ||
auto_auth { | ||
method "aws" { | ||
mount_path = "auth/aws" | ||
config = { | ||
type = "iam" | ||
role = "dev-role-iam" | ||
} | ||
} | ||
sink "file" { | ||
wrap_ttl = "5m" | ||
config = { | ||
path = "/home/ubuntu/vault-token-via-agent" | ||
} | ||
} | ||
} | ||
EOF | ||
# Re-run Vault Agent with updated configuration file | ||
$ vault agent -config=/home/ubuntu/auto-auth-conf.hcl -log-level=debug | ||
# Unwrap the wrapped token and set it as VAULT_TOKEN environment variable | ||
$ export VAULT_TOKEN=$(vault unwrap -field=token $(jq -r '.token' /home/ubuntu/vault-token-via-agent)) | ||
# Test to make sure that the token has appropriate policy attached | ||
$ curl --header "X-Vault-Token: $VAULT_TOKEN" $VAULT_ADDR/v1/secret/myapp/config | jq | ||
``` | ||
1. Clean up | ||
```plaintext | ||
$ terraform destroy -force | ||
$ rm -rf .terraform terraform.tfstate* private.key | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//-------------------------------------------------------------------- | ||
// Providers | ||
|
||
provider "aws" { | ||
// Credentials set via env vars | ||
|
||
region = "${var.aws_region}" | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
// Data Sources | ||
|
||
data "aws_ami" "ubuntu" { | ||
most_recent = true | ||
|
||
filter { | ||
name = "name" | ||
values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] | ||
} | ||
|
||
filter { | ||
name = "virtualization-type" | ||
values = ["hvm"] | ||
} | ||
|
||
owners = ["099720109477"] # Canonical | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//-------------------------------------------------------------------- | ||
// Resources | ||
|
||
## Vault Server IAM Config | ||
resource "aws_iam_instance_profile" "vault-server" { | ||
name = "${var.environment_name}-vault-server-instance-profile" | ||
role = "${aws_iam_role.vault-server.name}" | ||
} | ||
|
||
resource "aws_iam_role" "vault-server" { | ||
name = "${var.environment_name}-vault-server-role" | ||
assume_role_policy = "${data.aws_iam_policy_document.assume_role.json}" | ||
} | ||
|
||
resource "aws_iam_role_policy" "vault-server" { | ||
name = "${var.environment_name}-vault-server-role-policy" | ||
role = "${aws_iam_role.vault-server.id}" | ||
policy = "${data.aws_iam_policy_document.vault-server.json}" | ||
} | ||
|
||
# Vault Client IAM Config | ||
resource "aws_iam_instance_profile" "vault-client" { | ||
name = "${var.environment_name}-vault-client-instance-profile" | ||
role = "${aws_iam_role.vault-client.name}" | ||
} | ||
|
||
resource "aws_iam_role" "vault-client" { | ||
name = "${var.environment_name}-vault-client-role" | ||
assume_role_policy = "${data.aws_iam_policy_document.assume_role.json}" | ||
} | ||
|
||
resource "aws_iam_role_policy" "vault-client" { | ||
name = "${var.environment_name}-vault-client-role-policy" | ||
role = "${aws_iam_role.vault-client.id}" | ||
policy = "${data.aws_iam_policy_document.vault-client.json}" | ||
} | ||
|
||
//-------------------------------------------------------------------- | ||
// Data Sources | ||
|
||
data "aws_iam_policy_document" "assume_role" { | ||
statement { | ||
effect = "Allow" | ||
actions = ["sts:AssumeRole"] | ||
|
||
principals { | ||
type = "Service" | ||
identifiers = ["ec2.amazonaws.com"] | ||
} | ||
} | ||
} | ||
|
||
data "aws_iam_policy_document" "vault-server" { | ||
statement { | ||
sid = "ConsulAutoJoin" | ||
effect = "Allow" | ||
|
||
actions = ["ec2:DescribeInstances"] | ||
|
||
resources = ["*"] | ||
} | ||
|
||
statement { | ||
sid = "VaultAWSAuthMethod" | ||
effect = "Allow" | ||
actions = [ | ||
"ec2:DescribeInstances", | ||
"iam:GetInstanceProfile", | ||
"iam:GetUser", | ||
"iam:GetRole" | ||
], | ||
resources = ["*"] | ||
} | ||
|
||
statement { | ||
sid = "VaultKMSUnseal" | ||
effect = "Allow" | ||
|
||
actions = [ | ||
"kms:Encrypt", | ||
"kms:Decrypt", | ||
"kms:DescribeKey", | ||
] | ||
|
||
resources = ["*"] | ||
} | ||
} | ||
|
||
data "aws_iam_policy_document" "vault-client" { | ||
statement { | ||
sid = "ConsulAutoJoin" | ||
effect = "Allow" | ||
|
||
actions = ["ec2:DescribeInstances"] | ||
|
||
resources = ["*"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
//-------------------------------------------------------------------- | ||
// Resources | ||
|
||
resource "aws_kms_key" "vault" { | ||
description = "Vault unseal key" | ||
deletion_window_in_days = 7 | ||
|
||
tags { | ||
Name = "${var.environment_name}-vault-kms-unseal-key" | ||
} | ||
} | ||
|
||
resource "aws_kms_alias" "vault" { | ||
name = "alias/${var.environment_name}-vault-kms-unseal-key" | ||
target_key_id = "${aws_kms_key.vault.key_id}" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
module "vault_demo_vpc" { | ||
source = "terraform-aws-modules/vpc/aws" | ||
|
||
name = "${var.environment_name}-vpc" | ||
cidr = "10.0.0.0/16" | ||
|
||
azs = ["${var.availability_zones}"] | ||
private_subnets = ["10.0.1.0/24"] | ||
public_subnets = ["10.0.101.0/24"] | ||
|
||
tags = { | ||
Name = "${var.environment_name}-vpc" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
output "endpoints" { | ||
value = <<EOF | ||
Vault Server IP (public): ${join(", ", aws_instance.vault-server.*.public_ip)} | ||
Vault Server IP (private): ${join(", ", aws_instance.vault-server.*.private_ip)} | ||
For example: | ||
ssh -i ${var.key_name}.pem ubuntu@${aws_instance.vault-server.0.public_ip} | ||
Vault Client IP (public): ${aws_instance.vault-client.public_ip} | ||
Vault Client IP (private): ${aws_instance.vault-client.private_ip} | ||
For example: | ||
ssh -i ${var.key_name}.pem ubuntu@${aws_instance.vault-client.public_ip} | ||
EOF | ||
} | ||
|
||
|
||
# output "endpoints" { | ||
# value = <<EOF | ||
|
||
# Vault Server IP (public): ${aws_instance.vault-server.*.public_ip} | ||
# Vault Server IP (private): ${aws_instance.vault-server.*.private_ip} | ||
|
||
# For example: | ||
# ssh -i ${var.key_name}.pem ubuntu@${aws_instance.vault-server.0.public_ip} | ||
|
||
# Vault Client IP (public): ${aws_instance.vault-client.*.public_ip} | ||
# Vault Client IP (private): ${aws_instance.vault-client.*.private_ip} | ||
|
||
# For example: | ||
# ssh -i ${var.key_name}.pem ubuntu@${aws_instance.vault-client.public_ip} | ||
# EOF | ||
# } |
Oops, something went wrong.