Certificate Management

1. Why Certificate Management is required.

Certificates installed on client machines are one of the critical resources in the client’s infrastructure. Monitoring certificates is critical to any company willing to successfully provide Certificate Management service. The process of manually reporting certificate details is tedious is time consuming, so it better to automate it.
The following document will explain the steps to configure AWS services to provide certificate management for customers with AWS hosted infrastructure.

2. Solution Requirements

Mentioned below are the requirements that should be fulfilled to provide proper certificate management services.

  • The Solution should scan all instances for installed Certificates
  • The solution should be able to generate Reports which include the following information
    • Instance ID of the machine the certificate is installed on
    • Subject of the Certificate
    • Days till expiration
  • The solution should be able to generate an alert if the “days to expire” falls below 30 Days.
  • The alert should be able to create a ticket which can later be worked on to rectify the situation

Note: The requirements for certificate management are prone to change based on the requirements for the clients.

3. Assumptions:

The following assumptions are considered while configuring certificate management:

  • All the EC2 instances are running proper windows PowerShell.
  • All the EC2 instances have SSM agent installed.
  • The personnel responsible for the configuration of certificate management have some understanding of IAM Roles, S3 buckets and lambda functions

4. Solutions Description:

The following services provided by Amazon will be utilized to provide certificate management

  • Windows PowerShell
  • AWS S3
  • AWS Lambda
  • AWS IAM Roles
  • Maintenances Windows

4.1      Windows PowerShell

PowerShell will be utilized to generate information about the certificate and instance id for the AMI.
Mentioned below script needs to be executed on all AMI’s to generate the certificate information.

Set-Location Cert:\LocalMachine\my #Sets the location
$CertificateDetails = get-childitem # Get all the machine certificates
$instanceId = Invoke-WebRequest -usebasicparsing -Uri # Gets the instance ID
foreach ($i in $CertificateDetails) # writes the output with certificate Thumbprint , Subject, Instance ID and Expiration Date
Write-host "Thumbprint=" $i.Thumbprint " Expiration Date="$i.NotAfter " InstanceID ="$instanceID.Content" Subject="$i.Subject 

The following output is generated as a result of the PowerShell script.

Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****CYXZ********** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah
Thumbprint= ****************** Expiration Date= 1/1/2040 10:59:59 AM InstanceID = i-******* Subject= CN=SubjectName Blah Blah Blah

Where * represents different values for different certificates.

4.1      AWS S3

The result of the PowerShell script will be posted to an S3 bucket for further use.
The EC2 instances will need write access to the nominated S3 bucket for certificate Maintenance.
S3 Bucket Name: CertificateManagement

4.2      AWS Lambda Functions

Lambda Functions will be used to perform the following activities.

  • Acquire the result of the PowerShell script from the S3 bucket
  • Process the data to determine the Days till expiration of all the certificates
  • Generate a Report
  • Email the report to the relevant recipient

The Lambda Functions would need read access to the S3 bucket and access to AWS SES to send emails to recipients.
Mentioned below is the Lambda Functions that performs the mentioned above tasks.

import boto3
import codecs
import pprint
from datetime import datetime, date, time
def lambda_handler(event,Context):
    s3 = boto3.resource('s3')
    mybucket = s3.Bucket('CertificateManagement')
    result=["this is the result","\n"]
    for file_key in mybucket.objects.all():
        body = file_key.get()['Body'].read().decode('utf-8')
        output_lines=body.splitlines() #splits data into lines.
        resulthtml = ["<h1>Client Certificate Report</h1>"] # Adds heading to the email body
        resulthtml.append('<html><body><table border="1">') # Creates a table
        resulthtml.append('<tr><b><td>InstanceID</td><td>Thumbprint</td><td>Subject</td><td>Days to Expiration</td></b></tr>')
            for line in output_lines:
                output_word=line.split() # splits every line into words
                cnlist=output_word[10:] # gets the complete subject name and adds into an array
                cnstr=" ".join(cnlist) # joins the array to create a string.
                dt = datetime.strptime(str(output_word[4]), "%m/%d/%Y") # Converts the Date values string into a date format.
                difference=dt-ct # Gets the difference between the date value and current date.
                Values = str(difference) # converts the difference into string
                Valuelist=Values.split() # converts the string into arrays.
                Days = Valuelist[0] # selcts the first value in the array which is Number of days.
                result.append(("Certificate with '{}' will expire in '{}'").format(cnstr,difference)) # to display output when testing the script in the lambda section.
                resulthtml.append(("<td>'{}'</td><td>'{}'</td><td>'{}'</td><td>'{}'</td></tr>").format(output_word[9],output_word[1],cnstr,Days)) # for the HTML email to be sent.
            print("some errors encountered")
        for i in result: # prints the result in the testing window in the Lambda console
    myhtmllist = str(''.join(resulthtml)) # converts all the resulthtml into string to be used in Email.
    myhtmllist = myhtmllist.replace("'","") #removes the "'" from the data.
    textbody="this is a text body default"
    sender = "[email protected]"
    recipient = "[email protected]"
    awsregion = "us-east-1"
    subject = "Certificate Update list"
    charset = "UTF-8"
    client = boto3.client('ses',region_name=awsregion)
        response = client.send_email(
               'ToAddresses': [
                  'Body': {
                      'Html': {
                        'Charset': charset,
                        'Data': myhtmllist,
                    'Text': {
                     'Charset': charset,
                     'Data': mylist,
                'Subject': {
                    'Charset': charset,
                    'Data': subject,
    # Display an error if something goes wrong.
    except Exception as e:
        print( "Error: ", e)
       print("Email sent!")

 4.1 AWS IAM Roles
Roles will be used to grant

  • AWS S3 write access to all the EC2 instances as they will submit the output of the PowerShell script in the S3 bucket
  • AWS SES access to Lambda Functions to send emails to relevant recipients.


Amazon Simple Email Service (Amazon SES) evolved from the email platform that Amazon.com created to communicate with its own customers. In order to serve its ever-growing global customer base, Amazon.com needed to build an email platform that was flexible, scalable, reliable, and cost-effective. Amazon SES is the result of years of Amazon’s own research, development, and iteration in the areas of sending and receiving email.( Ref. From https://aws.amazon.com/ses/).
We would be utilizing AWS SES to generate emails using AWS lambda.
The configuration of the Lambda functions can be modified to send emails to a distribution group to provide Certificate reporting, or it can be used to send emails to ticketing rsystem in order to provide alerting and ticket creation in case a certificate expiration date crosses a configured threshold.

5. Solution Work Flow

Mentioned below is the workflow for the tasks.

6Solution Configuration

6.1 Configure IAM Roles

The following Roles should be configured

  • IAM role for Lambda Function.
  • IAM for EC2 instances for S3 bucket Access

6.1.1 Role for Lambda Function

Lambda function need the following access

  • Read data from the S3 bucket
  • Send Emails using Amazon S3

To accomplish the above the following policy should be created and attached to the IAM Role

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "Stmt1501474857000",
            "Effect": "Allow",
            "Action": [
            "Resource": [
            "Sid": "Stmt1501474895000",
            "Effect": "Allow",
            "Action": [
            "Resource": [

6.1.2  Role for EC2 instance

All EC2 instances should have access to store the PowerShell output in the S3 bucket.
To accomplish the above , the following policy should be assigned to the EC2 roles

    "Version": "2012-10-17",
    "Statement": [
            "Sid": "Stmt1501475224000",
            "Effect": "Allow",
            "Action": [
            "Resource": [

6.2 Configure Maintenance Window.

The following tasks need to be performed for the maintenance window

  • Register a Run Command with Run-PowerShell Script using the script in section 4.1
  • Register targets based on the requirements
  • Select the schedule based on your requirement

Maintenance Window Ref : 

6.3 Configure Lambda Function:

The following tasks need to be performed for the Lambda Function

  • Create a blank lambda function with the S3 put event as the triggerlambda function
  • Click on Next
  • Enter the Name and Description
  • Select run time Python 3.6
  • Copy and paste the lambda function mentioned in section 4.3

6.4 Configuring AWS SES

The following tasks need to be completed before the execution of the Run-commands.

  • Email Addresses should be added to the AWS SES section of the tenant.
  • The email addresses should be verified.

 7. Result:

Based on the above configuration, whenever the run command is executed, the following report is generated and sent to the nominated email account.

8. Next Steps:

We can modify the script to only report on Certificate expiring in 45 days or less.
We can also use SNS instead of SES to send out SMS to relevant teams as well.
That will be catered in another blog

Amazon Web Services, PowerShell
, ,

Leave a Reply