Skip to content

Instantly share code, notes, and snippets.

@devops-adeel
Last active February 15, 2023 18:11
Show Gist options
  • Save devops-adeel/cf21c2f78a259eb91e53c9009e4d2d0c to your computer and use it in GitHub Desktop.
Save devops-adeel/cf21c2f78a259eb91e53c9009e4d2d0c to your computer and use it in GitHub Desktop.
Non-Interactive Consumption Pattern for Vault PKI
data "aws_billing_service_account" "default" {}
resource "aws_iam_user" "default" {
name = "vault-aws-auth-user"
}
resource "aws_iam_access_key" "default" {
user = aws_iam_user.default.name
}
resource "aws_iam_user_policy" "default" {
name = "vault"
user = aws_iam_user.default.name
policy = data.aws_iam_policy_document.default.json
}
data "aws_iam_policy_document" "default" {
version = "2012-10-17"
statement {
sid = "AllowVaultAuth"
effect = "Allow"
resources = ["*"]
actions = [
"ec2:DescribeInstances",
"iam:GetInstanceProfile",
"iam:GetUser",
"iam:GetRole"
]
}
statement {
sid = "ManageOwnAccessKeys"
effect = "Allow"
resources = [aws_iam_user.default.arn]
actions = [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:GetUser",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
]
}
}
resource "vault_auth_backend" "default" {
type = "aws"
}
resource "vault_aws_auth_backend_client" "default" {
backend = vault_auth_backend.default.path
access_key = aws_iam_access_key.default.id
secret_key = aws_iam_access_key.default.secret
}
resource "vault_generic_endpoint" "rotate_root" {
ignore_absent_fields = true
data_json = jsonencode({})
path = format(
"%s/config/rotate-root",
vault_aws_auth_backend_client.default.backend
)
}
resource "vault_aws_auth_backend_role" "default" {
backend = vault_auth_backend.default.path
role = "pki"
auth_type = "ec2"
bound_account_ids = [aws_billing_service_account.default.id]
inferred_entity_type = "ec2_instance"
token_ttl = 60
token_max_ttl = 120
token_policies = [vault_policy.default.name]
}
locals {
domain = format("%s.com", var.application)
common_name = var.api_name
}
data "hcp_packer_iteration" "default" {
bucket_name = var.hcp_bucket
channel = var.hcp_channel
}
data "hcp_packer_image" "default" {
bucket_name = data.hcp_packer_iteration.default.bucket_name
iteration_id = data.hcp_packer_iteration.default.ulid
cloud_provider = "aws"
}
resource "aws_instance" "default" {
ami = data.hcp_packer_image.default.cloud_image_id
instance_type = "t2.micro"
tags = {
common_name = local.common_name
}
}
resource "aws_ec2_tag" "default" {
resource_id = aws_instance.default.instance_id
key = "domain_name"
value = local.domain_name
}
resource "aws_route53_record" "default" {
zone_id = aws_route53_zone.default.zone_id
name = format("%s.%s", local.common_name, local.domain)
type = "A"
ttl = 300
records = [aws_instance.default.public_ip]
}
locals {
domain = format("%s.com", var.application)
}
resource "aws_route53_zone" "default" {
name = local.domain
}
resource "vault_pki_secret_backend_role" "default" {
backend = vault_mount.pki.path
name = var.application
key_type = "rsa"
ttl = 3600
allow_ip_sans = true
key_bits = 4096
allowed_domains = tolist(local.domain)
}
data "vault_policy_document" "default" {
rule {
capabilities = ["read"]
description = "Allow issuing certs"
path = format(
"%s/issue/%s",
vault_mount.pki.path,
replace(local.domain, ".", "-dot-")
)
}
}
resource "vault_policy" "default" {
name = local.domain
policy = data.vault_policy_document.default.hcl
}
template_config {
exit_on_retry_failure = true
static_secret_render_interval = "10m"
}
template {
source = "/tmp/agent/server-cert.crt.ctmpl"
destination = "/etc/pki/tls/certs/foo.example.com.chained.crt"
error_on_missing_key = true
}
template {
source = "/tmp/agent/server-cert.key.ctmpl"
destination = "/etc/pki/tls/certs/foo.example.com.key"
error_on_missing_key = true
}
packer {
required_plugins {
amazon = {
version = ">= 1.1.1"
source = "github.com/hashicorp/amazon"
}
}
}
data "amazon-ami" "default" {
filters = {
virtualization-type = "hvm"
name = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
root-device-type = "ebs"
}
owners = ["099720109477"]
most_recent = true
}
source "amazon-ebs" "default" {
ami_name = var.image_name
ssh_username = var.ssh_username
instance_type = var.instance_type
region = var.region
source_ami = data.amazon-ami.default.id
}
build {
sources = ["source.amazon-ebs.default"]
provisioner "shell" {
script = "../ansible/install_ansible.sh"
}
provisioner "ansible-local" {
galaxy_file = "../ansible/requirements.yml"
playbook_file = "../ansible/install.yml"
galaxy_roles_path = "/usr/share/ansible/roles"
extra_arguments = [
"--extra-vars",
"'packer_build=true vault_version=${var.vault_version}'",
]
}
provisioner "shell" {
script = "../ansible/uninstall_ansible.sh"
}
}
build {
hcp_packer_registry {
bucket_name = "learn-packer-ubuntu"
bucket_labels = {
owner = "platform-team"
os = "Ubuntu"
ubuntu-version = "Focal 20.04"
}
sources = [
"source.amazon-ebs.default",
]
}
}
#!/bin/bash
DOMAIN=$(curl -s http://169.254.169.254/latest/meta-data/tags/instance/domain)
CN=$(curl -s http://169.254.169.254/latest/meta-data/tags/instance/common_name)
cat <<EOF > /tmp/server-cert.crt.tmpl
{{ with pkiCert "pki/issue/$DOMAIN-dot-com" "common_name=$CN.$DOMAIN.com" }}
{{ .Data.Cert }}
{{ .Data.CA }}
{{ end }}
EOF
cat <<EOF > /tmp/server-cert.key.tmpl
{{ with pkiCert "pki/issue/$DOMAIN-dot-com" "common_name=$CN.$DOMAIN.com" }}
{{ .Data.Key }}
{{ end }}
EOF
service vault-agent start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment