Skip to content

Instantly share code, notes, and snippets.

@5290charlie
Created April 7, 2017 21:56
Show Gist options
  • Save 5290charlie/8e2be002966aa28e088343f62a607c23 to your computer and use it in GitHub Desktop.
Save 5290charlie/8e2be002966aa28e088343f62a607c23 to your computer and use it in GitHub Desktop.
Simple PHP + AWS-CLI to update AWS ACM certificates
<?php
date_default_timezone_set('UTC');
function out($msg) {
$now = date('Y-m-d H:i:s');
echo "[{$now}] {$msg}\n";
}
function run($cmd) {
$cmd_end = ' 2>&1';
return trim(`{$cmd} ${cmd_end}`);
}
$str_sep = str_repeat('#', 50);
$elb_name = 'example-elb';
$cert_name = 'example.com';
$cert_path = '/etc/letsencrypt/live/' . $cert_name;
$prev_cert = false;
$try_wait = 1;
$max_tries = 10;
out($str_sep);
out("Uploading & Updating AWS ELB SSL certificate");
out($str_sep);
out("\t ELB Name: {$elb_name}");
out("\tCert Name: {$cert_name}");
out("\tCert Path: {$cert_path}");
out("\tMax Tries: {$max_tries}");
out("\t Try Wait: {$try_wait}s");
out($str_sep);
$options_arr = [
"--server-certificate-name {$cert_name}",
"--certificate-body file://{$cert_path}/cert.pem",
"--certificate-chain file://{$cert_path}/chain.pem",
"--private-key file://{$cert_path}/privkey.pem"
];
$options_str = implode(' ', $options_arr);
$lookup_cmd = "aws elb describe-load-balancers --load-balancer-names {$elb_name}";
out("Running AWS ELB lookup: '{$lookup_cmd}'");
$lookup_response = run($lookup_cmd);
$lookup_response_obj = json_decode($lookup_response);
if ($lookup_response_obj && $lookup_response_obj->LoadBalancerDescriptions && is_array($lookup_response_obj->LoadBalancerDescriptions)) {
if (count($lookup_response_obj->LoadBalancerDescriptions) === 1) {
$elb_info = $lookup_response_obj->LoadBalancerDescriptions[0];
if ($elb_info->ListenerDescriptions && is_array($elb_info->ListenerDescriptions)) {
$ssl_listeners = array_filter($elb_info->ListenerDescriptions, function($entry) {
$listener = $entry->Listener;
return $listener && $listener->InstancePort === 443 && $listener->InstanceProtocol === 'HTTPS';
});
if (count($ssl_listeners) === 1) {
$ssl_listener = array_values($ssl_listeners)[0]->Listener;
$ssl_cert_parts = explode('server-certificate/', $ssl_listener->SSLCertificateId);
if (count($ssl_cert_parts) === 2) {
$prev_cert = $ssl_cert_parts[1];
out("Existing ELB SSL cert: '{$prev_cert}'");
} else {
out("Unknown ELB listener SSL cert ARN: '{$ssl_listener->SSLCertificateId}'");
}
} else {
if (count($ssl_listeners) > 1) {
$amount = 'more than one';
} else {
$amount = 'zero';
}
out("Found {$amount} SSL listeners for ELB: '{$elb_name}'");
}
} else {
out("Invalid ELB listener descriptions! (Should be array)");
}
} else {
if (count($lookup_response_obj->LoadBalancerDescriptions) > 1) {
$amount = 'more than one';
} else {
$amount = 'zero';
}
out("Found {$amount} load balancers with name: '{$elb_name}'");
}
} else {
out("Invalid ELB info response!");
}
$upload_cmd = "aws iam upload-server-certificate {$options_str}";
out("Running AWS cert upload: '{$upload_cmd}'");
$upload_response = run($upload_cmd);
$upload_response_obj = json_decode($upload_response);
if ($upload_response_obj && $upload_response_obj->ServerCertificateMetadata && $upload_response_obj->ServerCertificateMetadata->Arn) {
out("Attempting to update ELB listener SSL cert...");
$update_success = $delete_success = false;
$update_try = $delete_try = 0;
$update_cmd = "aws elb set-load-balancer-listener-ssl-certificate --load-balancer-name {$elb_name} --load-balancer-port 443 --ssl-certificate-id {$upload_response_obj->ServerCertificateMetadata->Arn}";
while (!$update_success && $update_try < $max_tries) {
$update_try++;
$out_prefix = "(Attempt #{$update_try}) -";
out("{$out_prefix} Running AWS cert update: '{$update_cmd}'");
$update_response = run($update_cmd);
if ($update_response === '') {
$update_success = true;
out("{$out_prefix} Updated ELB SSL Cert with cert: '{$cert_name}'");
} else {
out("{$out_prefix} Unable to update ELB listener SSL cert!");
out("{$out_prefix} Response was: {$update_response}");
sleep($try_wait);
}
}
if (!$update_success) {
out("FAILURE - Max attempts ({$max_tries}) exceeded for cert update");
} else if ($prev_cert !== false) {
out("Removing previous ELB SSL cert: '{$prev_cert}'...");
$delete_cmd = "aws iam delete-server-certificate --server-certificate-name {$prev_cert}";
while (!$delete_success && $delete_try < $max_tries) {
$delete_try++;
$out_prefix = "(Attempt #{$delete_try}) -";
out("{$out_prefix} Running AWS cert delete: '{$delete_cmd}'");
$delete_response = run($delete_cmd);
if ($delete_response === '') {
$delete_success = true;
out("{$out_prefix} Deleted cert: '{$prev_cert}'");
} else {
out("{$out_prefix} Failed to delete cert: '{$prev_cert}'");
out("{$out_prefix} Response was: {$delete_response}");
sleep($try_wait);
}
}
if (!$delete_success) {
out("FAILURE - Max attempts ({$max_tries}) exceeded for cert removal");
} else {
out("Finished.");
}
} else {
out("Finished.");
}
} else {
out("Unknown response attempting to upload SSL cert to AWS: '${upload_response}'");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment