SAM 101 – Build and Deploy your Lambda Function Using AWS SAM

Hello!

I came across a use case, where I have to deploy a CloudFormation template which creates a lambda resource under my AWS account.

To provide Lambda function code to CFN template I have two ways:

  1. Use Inline lambda function inside the CFN template.
  2. Use the Serverless Application Model (SAM) by creating Lambda function artifacts under S3 and putting codeURI in the CFN template.

An inline function is a straightforward approach with a code limitation of 4 KB.

I will explain in this blog how to use SAM as an extension of AWS CloudFormation.

Note: Serverless application is more than just a lambda function, it can include additional resources such as APIs, databases and event source mappings.

SAM Deployment

Note: Make sure you have SAM CLI installed on your machine and I use Visual Studio Code for AWS CLI

  • Download a sample application

# sam init

You can see a sample app folder structure created by the name sam_app under your current folder

init

  • Add your application code and update CloudFormation Template
    • Lambda Function – Added a folder under sam_app by the name myLambda containing my Lambda function (ssm_Lambda.py) and requirments.txt file.
    • CloudFormation Template – Replaced existing template.yaml with my CFN which will create a lambda resource using a function defined under myLambda Folder (You can see CodeUri: myLambda/)

code_place

  • Build your application

# sam build

The ‘sam build’ command iterates through the functions in your application, looks for a manifest file (such as requirements.txt ) that contains the dependencies and automatically creates deployment artifacts.

build

A new folder with all artifacts gets created with the name build under .aws-sam

after_build

  • Package application

#  sam package –s3-bucket abhishek-bucket-lambda –output-template-file template-with-artifacts.yaml –no-verify-ssl

Packages an AWS SAM application. It creates a ZIP file of your code and dependencies and uploads it to Amazon S3. It then returns a copy of your AWS SAM template, replacing references to local artifacts with the Amazon S3 location where the command uploaded the artifacts. (Screenshots shows the uploaded zip file using above command and the SAM template template-with-artifacts.yaml)

s3

artifacts

  • Deploy Stack with SAM CLI

# sam deploy –stack-name “Sample-CFN-Stack” –s3-bucket abhishek-bucket-lambda –capabilities CAPABILITY_NAMED_IAM –template-file template-with-artifacts.yaml –region “eu-west-1” –no-verify-ssl

Or, you can also deploy your stack with CloudFormation CLI

# aws cloudformation deploy –template-file C:\Users\abhishek\sam-app\template-with-artifacts.yaml –stack-name “Sample-CFN-Stack”

The CloudFormation is deployed now and it has created the Lambda resource too.

Cheers !!

Decrypt PSCredential object password and it’s applications

Hello Everyone,

I feel it’s no more a secret that you can decrypt PSCredential Object and read/get the password in plain text. Wait…, I do not know what is PSCredntial objectThis is what you must be thinking. I feel you stumble upon PSCredential object if you do basic PowerShell for system administration.

Get-Credential is the cmdlet that will prompt you for username and password. once you enter your username and password then its basically a PSCredential object for you.

gc

Now, Let’s take a look at the PSCredential Object.

I have stored credentials in a variable $cred which is now a PSCredential Object. When you do Get-member you will come to know more about this PSCredential Object. Look at the below screenshot to understand more.

gc1

When I get $cred in the last command, It does show you a username and password. but if you notice Password than you will come to know that it’s stored as a secure string. This is good because you do not want PowerShell to store the password in plain text.

However, this is sometimes a need to reuse the same credential to authenticate with some other processes in your PowerShell script which requires plain text password as an input. Also, there is a limitation of the PSCredential Object. PSCredential Object will work on cmdlets that know what a PSCredential Object is. In fact, not all the .Net Classes understand what PSCredential Object is. So if you have a cmdlet which is written in .Net class rather than a PowerShell class than you can’t reuse the PSCredential object. In Order to use this, you need to decrypt the password from PSCredential Object and reuse the password to the respective class. Another example is invoking REST APIs, Not all REST APIs understand PSCredential so this means that you need to pass the username and password as a plain text.

Check the below example script, Here I need to invoke a REST method POST which requires username and password to authenticate. I have 2 parameters Pwd(Password) and Name (Username). This specific API does not understand the PSCredential so I need to pass the credential password in plain text.

Now, if I have this script than obviously, it is not secure because whoever has the access to the script will be able to know the credential which you don’t want to do obviously.

So what is the Solution?  Let’s try something.

Can I access the password directly from the PSCredential object

No, You can’t as it’s stored as a secure string. Look at this example.

gc2

  • $cred.Password will not return you the Password as plain text
  • $cred.Password|Convertfrom-SecureString will give you cipher data rather than a password as a plain text.

So what’s the solution. Well, the solution is in the PSCredential object itself. Do $cred|Get-member. 

gc3

PSCredential object has a method called GetNetworkCredential() method. you can use this method to decrypt the password in PSCredential object.

When I invoke this method and do Get-Member, it will show you the properties of the object and you will find a property called Password. use the last command $cred.GetNetworkCredential().Password and it will return the password in plain text. Please refer to the below screenshot.

gc4

So now I have modified the same script as below,

Conclusion: 

Yes, PSCredential stores the password in a secure string but it has a built-in function GetNetworkCredential() to decrypt the same.

Is it safe to use?

I feel No. Once script execution stops or runtime environment close, variables get disposed and you no longer have access to the variable. However, there are ways in which you can obviously exploit this feature with some tweaks in your Powershell script. for example, I wrote this to a text file. So yes, a PowerShell developer can write this line of code to a txt file and exploit a feature that was intended to be there to help you out.

gc5

I am not sure what is the right way to use credentials in PowerShell script. if you know a method which is definitely a secure way than do let me know with your comments here.


Thanks,