Friday, November 6, 2020

AWS RDS Secret Rotation configuration with Terraform

Problem:

AWS Secret Manager has an optional feature to automatically rotate the secret with specified intervals and they are using expandable design where entire rotation mechanism is based on prebuilt lambda function provided through AWS SAM (Serverless Application Model) Repository. This repository has several ready made password rotation lambda function for standard RDS database such as MySQL, Postgres, Oracle ect. 

When the secret rotation is enabled from the console GUI, AWS setup everything in the background to enable the key rotation without any manual user input. However if you are configuring Key rotation inside a Terraform configuration, all the operations done internally by GUI has to be performed by the terraform script. This article shows the steps required and some background information as well.

Solution:

Since AWS SAM Repository applications are provided as  CloudFormation templates, first we need to deploy the required stack from CloudFormation template using aws_cloudformation_stack resource. for this resource there are few required parameters to provided by argument template_body as a JSON document for the stack. This type of stack are called as a nested stack because instead of defining the required resources directly from JSON the template its utilize external template resources identified by an AWS arn to create the stack. For the JSON document:
  • The argument capabilities should be set with CAPABILITY_AUTO_EXPAND
  • Transform should be AWS:Serverless-2016-10-31 for CloudForm to identify this as a nested application stack
  • Type should be set to AWS::Serverless::application
  • Under the properties, ApplicationId specify the prebuilt rotation function and supportive resources such as execution policies to be created inside your AWS account before linking it with the Secret Manager. This parameter accept the standard AWS arn of the application that can be retrived on SAM Repository Console. for example arn:aws:serverlessrepo:us-east-1:297356227824:applications/<name_of_the_application>. name_of_the_application should be selected based on the type of RDS database and the type of authentication mode used.  "SecretsManagerRDSPostgreSQLRotationSingleUser" is used in this example to deploy the secret rotation lambda function and related resources for a RDS Postgres instance with Single user credentials mode. details of other available applications can be found here.
  • SemanticVersion is used to specify the version of the function as as AWS team keep developing this git repository and made available over the SAM Repository. As of the time of writing there was no way to determine the latest version of the application so I had to use AWS CLI command
    aws serverlessrepo list-application-versions --application-id <ApplicationId>
     to get the list of version available.  For the version it is recommended to use the latest version.
  • depending on the ApplicationId and the SemanticVersion parameters should be specified and terraform apply will fail with validation errors if not supplied correctly.

resource "aws_cloudformation_stack" "myappstack" {
  name = "myapp-stack"
  capabilities=["CAPABILITY_IAM","CAPABILITY_AUTO_EXPAND"]


  template_body = <<STACK
Transform: AWS::Serverless-2016-10-31
Resources:
  mySAR:
    Type: AWS::Serverless::Application
    Properties:
      Location:
        ApplicationId: "arn:aws:serverlessrepo:us-east-1:297356227824:applications/SecretsManagerRDSPostgreSQLRotationSingleUser"
        SemanticVersion: 1.1.80
      Parameters:
        endpoint: "https://secretsmanager.us-east-1.amazonaws.com"
        functionName: SecretsManager-new-version
        vpcSecurityGroupIds: "sg-012716d1a55d60278"
        vpcSubnetIds: "subnet-03f0cbeb7bd7f8f06,subnet-0d44efcaa26a2eb98"
STACK
}

Once the stack created resulting lambda function can be associated with with the secret by associating the lambda arn to the rotation_lambda_arnr argument. Although the aws_cloudformation_stack has an attribute outputs as a map of Cloudformation output values, terraform does not support those parameters and always returns an empty array.  as a workaround data resource aws_lambda_function can be used with the functionName given in the parameter block of the JSON document. optionally  depends_on can be used to make sure that data resources should be created after the completion of the stack.

data "aws_lambda_function" "db-rotation" {
    depends_on = [aws_cloudformation_stack.myappstack]
    function_name = "SecretsManager-new-version"
}

Then using the data resource defined above, lambda function arn can be assigned to the secret manager using aws_secretmanager_secret_rotation as follows

resource "aws_secretsmanager_secret_rotation" "database" {
    rotation_lambda_arn = data.aws_lambda_function.db-rotation.arn
    secret_id           = aws_secretsmanager_secret.db.id
    rotation_rules {
        automatically_after_days = 1
    }
}

reference:




Sunday, July 22, 2012

curl with HTTPS support on Windows

cURL is a great command line tool for accessing web resources. the download page offers pre-built binaries for many platforms including windows. They normally provide 2 flavors of the program

1. curl without SSL support (easy to get)
2. curl With SSL support.

i was not so fortunate to just download the binaries and use cURL with my HTTPS Server due to several missing depandancies. so i had to build cURL + SSL with following steps.

1. Download binaries (with SSL) from http://curl.haxx.se/latest.cgi?curl=win32-ssl-devel-msvc

when trying to execute the program we get following error due to the missing dependency libsasl.dll. this dll should be built and added to the cURL path.


2. the libsasl package itself depend on another package called Berkeley DB currently distributed by oracle. so the first step is to download 4.4.20 and build it using VS2008. 

Visual Studio 2008

  1. Choose File -> Open -> Project/Solution.... In the build_win32, select Berkeley_DB and click Open.
  2. You will be prompted to convert the project files to current Visual C++ format. Select "Yes to All".
  3. Choose the project configuration from the drop-down menu on the tool bar (usually Debug or Release for Win32).
  4. To build, right-click on the build_all target and select Build.
3. download cyrus sasl development source from ftp://ftp.cyrusimap.org/cyrus-sasl/cyrus-sasl-2.1.23.tar.gz and build using the instructions provided in <root>/doc/windows.html

the typical command line for the build like, (using VS2008 command prompt)

C:\sasl> nmake /f NTMakefile DB_INCLUDE=I:\db-4.4.20\build_win32 DB_LIBPATH=I:\db-4.4.20\build_win32\Release DB_LIB=libdb44s.lib

this will create libsasl.dll under C:\sasl\lib and copy it to cURL folder.

Now you can access HTTPS urls from curl.

Important: if curl complaining about SSL Certificate issue try using -k option