I am trying to create a TLS certificate for server authentication on Docker on a Terraformed system. To create the TLS server certificate I did the following
resource "tls_private_key" "master-1" {
algorithm = "RSA"
rsa_bits = "2048"
}
resource "tls_cert_request" "master-1" {
key_algorithm = "RSA"
private_key_pem = "${tls_private_key.master-1.private_key_pem}"
subject {
common_name = "${aws_instance.master-1.public_dns}"
}
dns_names = [
"${aws_instance.master-1.public_dns}",
"${aws_instance.master-1.private_dns}",
]
ip_addresses = [
"${aws_instance.master-1.public_ip}",
"${aws_instance.master-1.private_ip}",
]
}
resource "tls_locally_signed_cert" "master-1" {
ca_key_algorithm = "RSA"
cert_request_pem = "${tls_cert_request.master-1.cert_request_pem}"
ca_private_key_pem = "${tls_private_key.devops.private_key_pem}"
ca_cert_pem = "${tls_self_signed_cert.devops.cert_pem}"
validity_period_hours = 8760
allowed_uses = [
"server_auth",
"digital_signature",
"key_encipherment",
]
}
In the resource "tls_cert_request" "master-1"
section I added references to the master-1
aws_instance
In the instance I have the following provisioner which uses the values from the signed certificate
provisioner "remote-exec" {
inline = [
"echo ${tls_self_signed_cert.devops.cert_pem} > /tmp/ca.pem",
"echo ${tls_locally_signed_cert.master-1.cert_pem} > /tmp/cert.pem",
"echo ${tls_private_key.master-1.private_key_pem} > /tmp/key.pem",
]
}
I know it's technically a cycle and when doing a terraform plam
it errors out with
Error: Error asking for user input: 1 error(s) occurred:
* Cycle: aws_instance.master-1, tls_cert_request.master-1, tls_locally_signed_cert.master-1
So I wanted to ask if there's a way to avoid that other than using openssl and doing the TLS generation in the provisioner script?
This is what I did for my Vagrant environment which I am about to port to terraform
mkdir -p /var/lib/docker
openssl genrsa -out /var/lib/docker/key.pem 4096 2> /dev/null
openssl req -subj "/CN=$(hostname)" -sha256 -new -key /var/lib/docker/key.pem -out /tmp/server.csr
echo subjectAltName = DNS:$(hostname),IP:$(hostname -I | awk '{print $1}'),IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> /tmp/extfile.cnf
openssl x509 -req -days 365 -sha256 -in /tmp/server.csr -CA /vagrant/ca/ca.pem -CAkey /vagrant/ca/ca-key.pem -CAcreateserial -out /var/lib/docker/cert.pem -extfile extfile.cnf -passin file:/vagrant/ca/passphrase
rm /tmp/server.csr /tmp/extfile.cnf
Use a
null_resource
to deploy the certificates instead of doing that in the AWS_instance.