Using the JumpCloud PowerShell Module with AWS Lambda - TheJumpCloud/support GitHub Wiki

Table of Contents

What is AWS Lambda

AWS Lambda is a serverless computing platform that lets admins run code without having to provision or manage physical (or virtual) servers.

Admins upload code and can trigger the code to run in a number of extensible scenarios.

AWS Lambda's pricing model is resource based and charged by the Gigabyte-second. The AWS Lambda free tier offers 400,000 GB-Seconds of compute time per month.

After the 400,000 free GB-Seconds are used the cost is .2 cents per 1 million GB-Seconds.

To put this unit into perspective a simple Lambda function that uses functions from the JumpCloud PowerShell module to modify 100 objects costs ~50,000 GB-Seconds.

AWS Lambda supports a wide variety of programming languages. See the AWS Lambda FAQs and PowerShell core is a natively supported language.

AWS Lambda PowerShell Prerequisites

An AWS Account

To use AWS Lambda you must have an Amazon Web Services account.

Need to setup an AWS account? Click here for account configuration steps

PowerShell Core

Lambda functions in PowerShell require PowerShell Core (Version 6.0. or greater). Windows PowerShell is not supported.

Find steps for installing PowerShell Core here.

.NET Core 2.1 SDK

The .NET Core 2.1 SDK is used by the new Lambda PowerShell publishing cmdlets to create the Lambda deployment package and must be installed.

The .NET Core 2.1 SDK is available for download using the Download .NET Core SDK button on the linked Microsoft website.

Be sure to install the SDK and not the runtime installation.

AWS PowerShell Modules

Two modules must be installed to create an run AWS Lambda functions using PowerShell.

  1. AWSPowerShell.NetCore
  2. AWSLambdaPSCore

Install AWSPowerShell.NetCore running the command:

Install-Module AWSPowerShell.NetCore -Scope CurrentUser
Import-Module AWSPowerShell.NetCore

Install AWSLambdaPSCore running the command:

Install-Module AWSLambdaPSCore -Scope CurrentUser
Import-Module AWSLambdaPSCore

Need additional help?

See Configure AWS Lambda PowerShell Core Development Environment

Configure AWS Lambda IAM Role

Prior to configuring your first AWS Lambda function create a new role in the IAM console with at least AWSLambdaBasicExecutionRole permissions.

When configuring AWS Lambda functions the parameter -IAMRoleArn of the Publish-AWSPowerShellLambda function specifies the IAM role that Lambda assumes when it executes the function.

Configure an IAM role within the AWS management console to use when using the Publish-AWSPowerShellLambda command with the following settings:

Create role > Select type of trusted entity > AWS service > Lambda
Policy: AWSLambdaBasicExecutionRole
Name: lambda-basic-execution

Follow this AWS Lambda guide for additional information.

Configure AWS Lambda Service Account

When configuring AWS Lambda functions using PowerShell the request to AWS must be authenticated using an AWS Credential file.

The PowerShell command Initialize-AWSDefaultConfiguration from the AWSPowerShell.NetCore can be used to create this credential file.

This command takes in three parameters: -accessKey -secretKey and -region

It is recommended to create a user account in AWS IAM and use this user account as a service account to create an accessKey and a secretKey.

Create the user with the following permissions from the "Add User" section of AWS IAM.

Username: lambda-service
Access Type: Programmatic access
Set permissions: Attach Existing policies directly > AWSLambdaFullAccess

Capture this users Access Key and Secret access key which will be presented when saving the user. These will be used for parameter inputs in the next step using the Initialize-AWSDefaults PowerShell command.

Create an AWS Credential File

If you have never authenticated to AWS the Initialize-AWSDefaults PowerShell command can be used to configure an AWS credentials file on your local machine.

Learn more about these credential files here.

AWS provides a number of ways to configure this credential file.

Find more information on this here.

One way to set this credential file is using the Initialize-AWSDefaults command.

This command takes in three parameters: -AccessKey, -SecretKey, and -region

Use the -AccessKey, -SecretKey created in the Configure AWS Lambda Service Account step.

Choose a AWS region to configure your AWS Lambda functions in. Often times choosing a region that is closet to your physical location makes the most sense.

Learn more about AWS regions here.

Example:

Initialize-AWSDefaults -AccessKey "THISI6SVNOTA4VALID12" -SecretKey "niB9ceTrYD/UdEThISNoTVAli7D3KE+YBROhond0" -region us-west-2

Creating an AWS Lambda Function Using PowerShell

To create an AWS Lambda Function using PowerShell the PowerShell session used to configure the function must be run as administrator.

On Windows open the PowerShell session as administrator.

On Mac launch PowerShell as administrator running the command from terminal: sudo pwsh

Create a New AWSPowerShellLambda Script

The following AWSLambdaPSCore commands are used to create a AWS Lambda PowerShell function

Get-AWSPowerShellLambdaTemplate – Returns a list of all available templates.

New-AWSPowerShellLambda – Creates an initial PowerShell script based on a template.

Publish-AWSPowerShellLambda – Publishes a given PowerShell script to Lambda.

For this example we will be using the Basic template.

Navigate to a directory where you wish to create the template script file and run the following command:

New-AWSPowerShellLambda -ScriptName JCLambda -Template Basic

This will create a directory named JCLambda and inside this directory will be a .ps1 file named JCLambda.ps1 and a readme.txt file.

/Users/buster/Desktop> New-AWSPowerShellLambda -ScriptName JCLambda -Template Basic
/Users/buster/Desktop/JCLambda> ls
JCLambda.ps1
readme.txt

Populate the AWSPowerShellLambda Script with required information to load the JumpCloud module

Using the New-AWSPowerShellLambda to create a basic template will create a blank template file that looks like:

# PowerShell script file to be executed as a AWS Lambda function.
#
# When executing in Lambda the following variables will be predefined.
#   $LambdaInput - A PSObject that contains the Lambda function input data.
#   $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment.
#
# The last item in the PowerShell pipeline will be returned as the result of the Lambda function.
#
# To include PowerShell modules with your Lambda function, like the AWSPowerShell.NetCore module, add a "#Requires" statement
# indicating the module and version.

#Requires -Modules @{ModuleName='AWSPowerShell.NetCore';ModuleVersion='3.3.390.0'}

# Uncomment to send the input event to CloudWatch Logs
# Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5)

Update this template file to look like the below example:

# PowerShell script file to be executed as a AWS Lambda function.
#
# When executing in Lambda the following variables will be predefined.
#   $LambdaInput - A PSObject that contains the Lambda function input data.
#   $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment.
#
# The last item in the PowerShell pipeline will be returned as the result of the Lambda function.
#
# To include PowerShell modules with your Lambda function, like the AWSPowerShell.NetCore module, add a "#Requires" statement 
# indicating the module and version.

#Requires -Modules @{ModuleName = 'AWSPowerShell.NetCore'; ModuleVersion = '3.3.390.0'; }, @{ModuleName = 'JumpCloud'; ModuleVersion = '1.13.2'; }

# JumpCloud PowerShell module authentication
# Add an entry with a key of JCAPIKEY and  a value of your JumpCloud API key into the JSON $payLoad used to invoke this Lambda function
$JCAPIKEY = $LambdaInput.JCAPIKEY
Connect-JCOnline $JCAPIKEY -force

# Use Write-Host to output information to CloudWatch logs
# The last PowerShell object returned from the script will be displayed as the results of the lambda function when run
## --------Input your JumpCloud PowerShell logic here below this line----------------

You must provide a ModuleVersion to load a PowerShell module. This example template loads version 1.13.2 Update this value with the latest version of the JumpCloud PowerShell module. Find the latest version of the JumpCloud PowerShell module using the Find-Module JumpCloud command.

Add JumpCloud PowerShell logic and commands to the AWSPowerShellLambda Script

Under the line ## --------Input your JumpCloud PowerShell logic here below this line---------------- of the template file input the logic you would like your script to execute.

Use the command Write-Host to output information while the script runs to the Amazon CloudWatch Logs

The last object returned from the script will be returned in the results of the PowerShell script.

When a Lambda function is invoked using Invoke-LMFunction command or run from the Lambda GUI the object $LambdaInput passes in the contents of the -Payload parameter.

This object must be in a JSON format and is then a hash table which properties can be used in the PowerShell script.

See how the $JCAPIKEY variable is set using this input object:

$JCAPIKEY = $LambdaInput.JCAPIKEY
Connect-JCOnline $JCAPIKEY -force

Example script which returns the last 10 JumpCloud users created:

# PowerShell script file to be executed as a AWS Lambda function. 
# 
# When executing in Lambda the following variables will be predefined.
#   $LambdaInput - A PSObject that contains the Lambda function input data.
#   $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment.
#
# The last item in the PowerShell pipeline will be returned as the result of the Lambda function.
#
# To include PowerShell modules with your Lambda function, like the AWSPowerShell.NetCore module, add a "#Requires" statement 
# indicating the module and version.

#Requires -Modules @{ModuleName = 'AWSPowerShell.NetCore'; ModuleVersion = '3.3.390.0'; }, @{ModuleName = 'JumpCloud'; ModuleVersion = '1.13.2'; }

# JumpCloud PowerShell module authentication
# Add an entry with a key of JCAPIKEY and  a value of your JumpCloud API key into the JSON $payLoad used to invoke this Lambda function
$JCAPIKEY = $LambdaInput.JCAPIKEY
Connect-JCOnline $JCAPIKEY -force

# Use Write-Host to output information to CloudWatch logs
# The last PowerShell object returned from the script will be displayed as the results of the lambda function when run
## --------Input your JumpCloud PowerShell logic here below this line----------------

$numberOfUsers = $LambdaInput.numberOfUsers
Write-Host "Searching for last $numberOfUsers users"

$Last10Users = Get-JCUser -returnProperties username, created | Sort-Object created | Select-Object -Last $numberOfUsers

Write-Host $Last10Users

Publish AWSPowerShellLambda Function

After you have populated the AWSPowerShellLambda template script with the PowerShell logic you're looking to execute you must upload this script to AWS Lambda.

The function Publish-AWSPowerShellLambda must be used to send this script to AWS.

To publish a Lambda function using PowerShell the PowerShell session used to publish the function must be run as administrator.

On Windows open the PowerShell session as administrator.

On Mac launch PowerShell as administrator running the command from terminal: sudo pwsh.

The Publish-AWSPowerShellLambda takes in four parameters:

$publishPSLambdaParams = @{
    Name       = ''      # Name of the Lambda function
    ScriptPath = ''      # Path to the PowerShell script file
    Region     = ''      # Local Region. Use Get-AWSRegion to find yours
    IAMRoleArn = ''      # IAM role used that this function will run as
}

Create a hash table and populate values for these four parameters and splat this object into the Publish-AWSPowerShellLambda command.

Example:

$publishPSLambdaParams = @{
    Name       = 'JCLambda'                 # Name of the Lambda function
    ScriptPath = '.\JCLambda\JCLambda.ps1'  # Path to the PowerShell script file
    Region     = 'us-west-2'                # Local Region. Use Get-AWSRegion to find yours
    IAMRoleArn = 'lambda-role-1'            # IAM role used that this function will run as
}
Publish-AWSPowerShellLambda @publishPSLambdaParams

Running this command will upload the AWSPowerShellLambda template script to AWS Lambda in the region you specify.

You can update the contents of this script by updating the script and then re running the Publish-AWSPowerShellLambda command.

Running AWSPowerShellLambda Functions From PowerShell

The function Invoke-LMFunction is used to run AWSPowerShellLambda from the PowerShell terminal.

Use the function Get-LMFunctionList to see available function.

This function takes in the input parameter of a region.

Example:

Get-LMFunctionList -Region us-west-2

FunctionName               Runtime       MemorySize Timeout CodeSize LastModified                 RoleName
------------               -------       ---------- ------- -------- ------------                 --------
JCDemo                     dotnetcore2.1        512      90 24056755 2019-08-27T21:10:24.696+0000 lambda_basic_execution
sajumpcloud_testfunction_1 dotnetcore2.1        512      90 23851787 2019-08-27T14:42:25.640+0000 sajumpcloud_testfunction_…
JCLambda                   dotnetcore2.1        512      90 24056972 2019-08-29T15:10:04.502+0000 lambda-role-1
InputTest                  dotnetcore2.1        512      90 23851591 2019-08-28T21:30:25.767+0000 lambda_basic_execution

The Invoke-LMFunction takes in three parameters: -FunctionName, -Payload, and -Region

Specify the function name and region you wish to execute and pass in a JSON object into the -Payload variable that corresponds with the logic in your PowerShell script.

An entry for the JCAPIKEY must be present in the $payLoad object.

Add any other objects you wish to pass to the PowerShell function in the $payLoad object.

Run the function from PowerShell using the Invoke-LMFunction command.

Example:

$payLoad = @{
    JCAPIKEY = 'n9ot59526a57n1a4p444d9i7k2534604e0272br0'
    numberOfUsers = '10'
} | ConvertTo-Json

Invoke-LMFunction -FunctionName JCLambda -Payload $payLoad -Region us-west-2

ExecutedVersion : $LATEST
FunctionError   : 
LogResult       : 
Payload         : System.IO.MemoryStream
StatusCode      : 200

A StatusCode of 200 indicates that the function has been triggered successfully.

Seeing Results of AWSPowerShellLambda Functions

The command Get-CWLFilteredLogEvent can be used to query CloudWatch logs and see the output of any Write-Host calls from within the script.

Use the below code snippet which leverages this command to query the results of cloud watch and search for a specific function name.

$FunctionName='JCLambda'
$logs = Get-CWLFilteredLogEvent -Region us-west-2 -LogGroupName /aws/lambda/$FunctionName
$logs.Events | ? Message -Like "*Information*"

Update the $FunctionName='JCLambda' variable to use this example.