Skip to content

Instantly share code, notes, and snippets.

@techthoughts2
Last active September 30, 2022 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save techthoughts2/d5d994d6d2d336b4ad397fc5f99c0f1a to your computer and use it in GitHub Desktop.
Save techthoughts2/d5d994d6d2d336b4ad397fc5f99c0f1a to your computer and use it in GitHub Desktop.
## Synopsis This helper script can be used to bootstrap a CDK project for deploying PowerShell Lambdas using the custom PowerShell Runtime via Lambda Layers. ## Description - Quickly bootstraps a CDK project for deploying lambdas using the custom
#region settings
#! Enter all required modules you want to bootstrap for use in your PowerShell lambda layers
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
},
@{
ModuleName = 'PoshGram'
ModuleVersion = '2.2.2'
}
)
#endregion
#region example notes
<#
# 0 - (Optional) create a basic CDK project if you don't already have one
mkdir my-cdk-project
cd my-cdk-project
cdk init app --language typescript
# 1 - edit settings section of cdk_pwsh_runtime_bootstrap.ps1 to include all Required Modules for your project
# 2 - Load cdk_pwsh_runtime_bootstrap.ps1 into memory
. ./cdk_pwsh_runtime_bootstrap.ps1
# 3 - Bootstrap CDK project for using custom PowerShell Runtime for AWS Lambda
# you can remove the HelloWorld switch if you don't need a sample lambda created
Invoke-BootStrapCDKProject -RequiredModules $requiredModules -HelloWorld
# 4 - (Optional) Get CDK typescript example snippet to paste into your CDK construct
# basic CDK snippet examples to incorporate into existing Construct:
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules | Set-Clipboard
# full Construct example:
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules -FullConstruct | Set-Clipboard
# 5 - Deploy your CDK project
cdk deploy --profile profilename
#>
#endregion
#region supporting functions
function Invoke-GetPowerShell {
<#
.SYNOPSIS
Retrieves PowerShell from Github
.DESCRIPTION
Downloads specified version of PowerShell from Github
Extracts PowerShell tar to specified path in CDK project
Removes temporary downloaded PowerShell tar
.EXAMPLE
Invoke-GetPowerShell -PwshVersion '7.2.6' -PwshArchitecture 'x64'
Downloads and extracts the specified version of PowerShell from Github and extracts to the default lambda layer path in the CDK project.
.PARAMETER PwshVersion
Version of PowerShell to download
.PARAMETER PwshArchitecture
Architecture version of PowerShell to download
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.PARAMETER Force
Skip Confirmation
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
.LINK
https://aws.amazon.com/blogs/compute/introducing-the-powershell-custom-runtime-for-aws-lambda/
.LINK
https://github.com/awslabs/aws-lambda-powershell-runtime
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $true,
HelpMessage = 'Version of PowerShell to download')]
[string]
$PwshVersion,
[Parameter(Mandatory = $false,
HelpMessage = 'Architecture version of PowerShell to download')]
[ValidateSet('x64', 'arm64')]
[string]
$PwshArchitecture = 'x64',
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/',
[Parameter(Mandatory = $false,
HelpMessage = 'Skip confirmation')]
[switch]$Force
)
begin {
if (-not $PSBoundParameters.ContainsKey('Verbose')) {
$VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference')
}
if (-not $PSBoundParameters.ContainsKey('Confirm')) {
$ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
}
if (-not $PSBoundParameters.ContainsKey('WhatIf')) {
$WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
}
Write-Verbose -Message ('[{0}] Confirm={1} ConfirmPreference={2} WhatIf={3} WhatIfPreference={4}' -f $MyInvocation.MyCommand, $Confirm, $ConfirmPreference, $WhatIf, $WhatIfPreference)
} #begin
process {
$runTimePath = '{0}/pwsh-runtime/powershell' -f $Path
if ($Force -or $PSCmdlet.ShouldProcess('Download an extract PowerShell to {0}' -f $runTimePath)) {
Write-Verbose -Message ('[{0}] Reached command' -f $MyInvocation.MyCommand)
Write-Verbose -Message ('Testing if path present: {0}' -f $runTimePath)
if (-not(Test-Path $runTimePath)) {
Write-Verbose -Message 'Path not found. Creating directory.'
$newItemSplat = @{
ItemType = 'Directory'
Force = $true
Path = '{0}\pwsh-runtime\powershell' -f $Path
}
New-Item @newItemSplat | Out-Null
}
Write-Verbose -Message ('Downloading Powershell for PwshRuntimeLayer to: {0}' -f $Path)
$invokeWebRequestSplat = @{
Uri = 'https://github.com/PowerShell/PowerShell/releases/download/v{0}/powershell-{1}-linux-{2}.tar.gz' -f $PwshVersion, $PwshVersion, $PwshArchitecture
OutFile = '{0}\powershell-{1}-{2}.tar.gz' -f $Path, $PwshVersion, $PwshArchitecture
}
Invoke-WebRequest @invokeWebRequestSplat
Write-Verbose -Message ('Extracting Powershell {0} for {1} to: {2}/powershell' -f $PwshVersion, $PwshArchitecture, $Path)
tar zxf $Path/powershell-$PwshVersion-$PwshArchitecture.tar.gz -C $Path/pwsh-runtime/powershell
Write-Verbose -Message 'Deleting PowerShell tar download'
$removeItemSplat = @{
Path = '{0}/powershell-{1}-{2}.tar.gz' -f $Path, $PwshVersion, $PwshArchitecture
Force = $true
}
Remove-Item @removeItemSplat
} #if_shouldprocess
} #process
} #Invoke-GetPowerShell
function Test-PowerShellRuntimePresent {
<#
.SYNOPSIS
Evaluates if specified version of PowerShell has already been bootstrapped for the CDK project
.DESCRIPTION
Evaluates if specified version of PowerShell is already bootstrapped in the CDK project
by inspecting the manifest to determine if it is a match.
.EXAMPLE
Test-PwshRuntimePresent -PowerShellVersion 7.2.6
Evaluates if the specified version of PowerShell is already bootstrapped at the default layer path location of the CDK project
.PARAMETER PwshVersion
Version of PowerShell to download
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.OUTPUTS
System.Boolean
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
#>
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory = $true,
HelpMessage = 'Version of PowerShell to download')]
[string]
$PowerShellVersion,
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/'
)
$result = $false #assume the worst
[version]$desiredVersion = $PowerShellVersion
$manifestPath = '{0}/pwsh-runtime\powershell\_manifest\spdx_2.2\manifest.spdx.json' -f $Path
Write-Verbose -Message ('Testing if manifest is present at {0}' -f $manifestPath)
if (Test-Path -Path $manifestPath) {
Write-Verbose -Message 'Manifest file found. Evaluating PowerShell version...'
$manifestJSON = Get-Content -Path $manifestPath -Raw | ConvertFrom-Json
$psInfo = $manifestJSON.packages | Where-Object { $_.name -eq 'PowerShell Linux' }
[version]$pwshVersion = $psInfo.versionInfo
if ($pwshVersion -eq $desiredVersion) {
Write-Verbose -Message ('MATCH. Desired Version: {0} | PowerShell Version: {1}' -f $PowerShellVersion, $psInfo.versionInfo)
$result = $true
}
else {
Write-Verbose -Message ('NO MATCH. Desired Version: {0} | PowerShell Version: {1}' -f $PowerShellVersion, $psInfo.versionInfo)
}
}
else {
Write-Verbose -Message 'Manifest not found'
}
return $result
} #Test-PowerShellRuntimePresent
function Invoke-GetAWSLambdaPowerShellRuntime {
<#
.SYNOPSIS
Retrieves required AWS Lambda PowerShell runtime files to bootstrap CDK lambda layers
.DESCRIPTION
Downloads the aws-lambda-powershell-runtime zip from GitHub
Extracts the repo zip
Copies the required AWS Lambda PowerShell runtime files needed for PowerShell lambda layers
Removes the repo zip
.EXAMPLE
Invoke-GetAWSLambdaPowerShellRuntime
Downloads and extracts the AWS Lambda PowerShell runtime files to the default lambda layer path in the CDK project.
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.PARAMETER Force
Skip Confirmation
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
.LINK
https://aws.amazon.com/blogs/compute/introducing-the-powershell-custom-runtime-for-aws-lambda/
.LINK
https://github.com/awslabs/aws-lambda-powershell-runtime
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/',
[Parameter(Mandatory = $false,
HelpMessage = 'Skip confirmation')]
[switch]$Force
)
begin {
if (-not $PSBoundParameters.ContainsKey('Verbose')) {
$VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference')
}
if (-not $PSBoundParameters.ContainsKey('Confirm')) {
$ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
}
if (-not $PSBoundParameters.ContainsKey('WhatIf')) {
$WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
}
Write-Verbose -Message ('[{0}] Confirm={1} ConfirmPreference={2} WhatIf={3} WhatIfPreference={4}' -f $MyInvocation.MyCommand, $Confirm, $ConfirmPreference, $WhatIf, $WhatIfPreference)
} #begin
process {
$tempDir = '{0}pwsh-runtime/temp' -f $Path
$zipFile = '{0}runtime.zip' -f $tempDir
if ($Force -or $PSCmdlet.ShouldProcess('Download and extract pwsh runtime to {0}' -f $zipFile)) {
Write-Verbose -Message ('[{0}] Reached command' -f $MyInvocation.MyCommand)
Write-Verbose -Message ('Verifying if temp dir is present: {0}' -f $tempDir)
if (-not(Test-Path $tempDir)) {
Write-Verbose -Message 'Creating temp dir...'
New-Item -ItemType Directory -Force -Path $tempDir | Out-Null
}
else {
Write-Verbose 'dir Verified.'
}
Write-Verbose -Message ('Downloading aws-lambda-powershell-runtime zip to {0}' -f $zipFile)
$repoZIP = 'https://github.com/awslabs/aws-lambda-powershell-runtime/archive/refs/heads/main.zip'
$invokeWebRequestSplat = @{
Uri = $repoZIP
OutFile = $zipFile
ErrorAction = 'Stop'
}
Invoke-WebRequest @invokeWebRequestSplat
Write-Verbose 'Expanding aws-lambda-powershell-runtime...'
$expandArchiveSplat = @{
Path = $zipFile
DestinationPath = $tempDir
Verbose = $false
}
Expand-Archive @expandArchiveSplat
Write-Verbose ('Copying pwsh-runtime to layer path {0}' -f $Path)
$copyItemSplat = @{
Path = '{0}/aws-lambda-powershell-runtime-main/powershell-runtime/pwsh-runtime/*' -f $tempDir
Destination = '{0}/pwsh-runtime' -f $Path
Recurse = $true
Force = $true
}
Copy-Item @copyItemSplat
Write-Verbose -Message 'Removing temp directory and files...'
$removeItemSplat = @{
Path = $tempDir
Recurse = $true
Force = $true
}
Remove-Item @removeItemSplat
} #if_shouldprocess
} #process
} #Invoke-GetAWSLambdaPowerShellRuntime
function Invoke-GetRequiredModule {
<#
.SYNOPSIS
Downloads all indicated PowerShell modules to the provided Lambda layers path location in the CDK project
.DESCRIPTION
Downloads all indicated PowerShell modules from the PSGallery to the provided Lambda layers path location in the CDK project using Save-Module
.EXAMPLE
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
},
@{
ModuleName = 'PoshGram'
ModuleVersion = '2.2.2'
}
)
Invoke-GetRequiredModule -RequiredModules $RequiredModules
Downloads all indicated PowerShell modules to the default lambda layer path in the CDK project.
.PARAMETER RequiredModules
Array of Hashtable(s) containing ModuleName and ModuleVersion for each required module
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.PARAMETER Force
Skip Confirmation
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $true,
HelpMessage = 'Array of Hashtable(s) containing ModuleName and ModuleVersion for each required module')]
[array]
$RequiredModules,
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/',
[Parameter(Mandatory = $false,
HelpMessage = 'Skip confirmation')]
[switch]$Force
)
begin {
if (-not $PSBoundParameters.ContainsKey('Verbose')) {
$VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference')
}
if (-not $PSBoundParameters.ContainsKey('Confirm')) {
$ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
}
if (-not $PSBoundParameters.ContainsKey('WhatIf')) {
$WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
}
Write-Verbose -Message ('[{0}] Confirm={1} ConfirmPreference={2} WhatIf={3} WhatIfPreference={4}' -f $MyInvocation.MyCommand, $Confirm, $ConfirmPreference, $WhatIf, $WhatIfPreference)
} #begin
process {
if ($Force -or $PSCmdlet.ShouldProcess('Bootstrap CDK project lambda layers with all specified PowerShell modules.')) {
Write-Verbose -Message ('[{0}] Reached command' -f $MyInvocation.MyCommand)
foreach ($module in $RequiredModules) {
$moduleCheck = Test-Path -Path ('{0}{1}/modules/{2}/{3}' -f $Path, $module.ModuleName, $module.ModuleName, $module.ModuleVersion)
if (-not $moduleCheck) {
$modulePath = '{0}{1}/modules' -f $Path, $module.ModuleName
if (-not (Test-Path $modulePath)) {
Write-Verbose -Message ('Creating {0}' -f $modulePath)
New-Item -ItemType Directory -Path $modulePath -Force | Out-Null
}
Write-Verbose -Message ('Saving {0} - v{1} from PSGallery to {2}' -f $module.ModuleName, $module.ModuleVersion, $modulePath )
$saveModuleSplat = @{
Name = $module.ModuleName
RequiredVersion = $module.ModuleVersion
Repository = 'PSGallery'
Path = $modulePath
ErrorAction = 'Stop'
}
Save-Module @saveModuleSplat
}
else {
Write-Verbose -Message ('{0} - v{1} already present. No action taken.' -f $module.ModuleName, $module.ModuleVersion)
}
} #foreach
} #if_shouldprocess
} #process
} #Invoke-GetRequiredModules
function Get-CDKPwshLayerSnippet {
<#
.SYNOPSIS
Generates basic CDK Typescript snippet examples for deploying lambda layers using PowerShell Runtime for AWS Lambda
.DESCRIPTION
Generates basic CDK Typescript snippet examples
One layer for the PowerShell Runtime for AWS Lambda
One layer for each provided PowerShell module
Basic Hello World lambda function with all included layers
.EXAMPLE
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules
Generates basic CDK snippet examples to incorporate into existing Construct.
.EXAMPLE
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules -FullConstruct | Set-Clipboard
Generates full CDK construct example and sends to clipboard.
.EXAMPLE
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
},
@{
ModuleName = 'PoshGram'
ModuleVersion = '2.2.2'
}
)
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules
Generates basic CDK snippet examples to incorporate into existing Construct.
.EXAMPLE
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
},
@{
ModuleName = 'PoshGram'
ModuleVersion = '2.2.2'
}
)
Get-CDKPwshLayerSnippet -RequiredModules $requiredModules | Set-Clipboard
Generates basic CDK snippet examples to incorporate into existing Construct and sends to clipboard.
.PARAMETER RequiredModules
Array of Hashtable(s) containing ModuleName and ModuleVersion for each required module
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.PARAMETER FullConstruct
If specified returns a complete Construct example
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
This is just a snippet example helper function.
It is not a replacement for reading the CDK API reference.
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
.LINK
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.LayerVersion.html
.LINK
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
HelpMessage = 'Array of Hashtable(s) containing ModuleName and ModuleVersion for each required module')]
[array]
$RequiredModules,
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/',
[Parameter(Mandatory = $false,
HelpMessage = 'If specified returns a complete Construct example')]
[switch]$FullConstruct
)
$importsReminder = @'
//--add to imports--
//import * as lambda from 'aws-cdk-lib/aws-lambda'
//------------------
'@
$powershellLayer = @'
// PowerShell layer
const powershellLayer = new lambda.LayerVersion(this, 'pwsh-layer', {
compatibleRuntimes: [
lambda.Runtime.PROVIDED_AL2
],
code: lambda.Code.fromAsset('replace_path/pwsh-runtime'),
description: 'PowerShell 7 runtime',
});
'@
$baseModuleLayer = @'
// replace_modulename layer
const replace_module1 = new lambda.LayerVersion(this, 'replace_modulename-layer', {
compatibleRuntimes: [
lambda.Runtime.PROVIDED_AL2
],
code: lambda.Code.fromAsset('replace_path/replace_modulename'),
description: 'replace_modulename',
});
'@
$lambdaFunction = @'
new lambda.Function(this, 'my-function', {
code: lambda.Code.fromAsset('src/lambda/PowerShellLambda/HelloWorld/'), // replace with path your lambda code
memorySize: 1024,
timeout: cdk.Duration.seconds(5),
runtime: lambda.Runtime.PROVIDED_AL2,
handler: 'HelloWorld.ps1::handler', // replace with your lambda script
layers: [replace_modulenames],
});
'@
$finalPowershellLayer = $powershellLayer.Replace('replace_path/', $Path)
$finalModuleLayers = New-Object System.Collections.Generic.List[string]
$moduleNames = New-Object System.Collections.Generic.List[string]
$moduleNames.Add('powershellLayer')
$i = 0
foreach ($module in $RequiredModules) {
$moduleLayer = $baseModuleLayer.Replace('replace_modulename', $module.ModuleName)
$moduleLayer = $moduleLayer.Replace('replace_path/', $Path)
$moduleLayer = $moduleLayer.Replace('replace_module1', "layer$i")
$finalModuleLayers.Add($moduleLayer)
$moduleNames.Add("layer$i")
$i++
} #foreach
$finalLambdaFunction = $lambdaFunction.Replace('replace_modulenames', ($moduleNames -join ','))
if ($FullConstruct) {
$construct = @"
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda'
// import * as sqs from 'aws-cdk-lib/aws-sqs';
export class PSLambdaCDKTestStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// The code that defines your stack goes here
$finalPowershellLayer
$finalModuleLayers
$finalLambdaFunction
}
}
"@
$finalSnippet = $construct
}
else {
$finalSnippet = $importsReminder + $finalPowershellLayer + $finalModuleLayers + $finalLambdaFunction
}
return $finalSnippet
} #Get-CDKPwshLayerSnippet
#endregion
#region main
function Invoke-BootStrapCDKProject {
<#
.SYNOPSIS
Bootstraps a CDK project for deploying lambdas with lambda layers using PowerShell Runtime for AWS Lambda
.DESCRIPTION
Quickly bootstraps a CDK project for deploying lambdas using the custom PowerShell runtime.
Retrieves PowerShell from Github
Retrieves required AWS Lambda PowerShell runtime files to bootstrap CDK lambda layers
Downloads all indicated PowerShell modules to the provided Lambda layers path location in the CDK project
If HelloWorld switch specified - scaffolds a basic HelloWorld PowerShell lambda
.EXAMPLE
Invoke-BootStrapCDKProject -RequiredModules $requiredModules
Bootstraps a CDK project with all components needed to deploy PowerShell lambdas using PowerShell custom runtime.
.EXAMPLE
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
},
@{
ModuleName = 'PoshGram'
ModuleVersion = '2.2.2'
}
)
Invoke-BootStrapCDKProject -RequiredModules $requiredModules -HelloWorld -Verbose
Bootstraps a CDK project with all components needed to deploy PowerShell lambdas using PowerShell custom runtime.
Also creates a basic HelloWorld lambda.
.EXAMPLE
$requiredModules = @(
@{
ModuleName = 'AWS.Tools.Common'
ModuleVersion = '4.1.175'
}
)
Invoke-BootStrapCDKProject -CDKProjectPath 'C:\dev\cdkproject1' -PwshVersion '7.2.4' -PwshArchitecture x64 -RequiredModules $requiredModules -HelloWorld
Bootstraps a CDK project with all components needed to deploy PowerShell lambdas using PowerShell custom runtime.
Also creates a basic HelloWorld lambda.
.PARAMETER CDKProjectPath
File path to the root of CDK project
.PARAMETER PwshVersion
Version of PowerShell to download
.PARAMETER PwshArchitecture
Architecture version of PowerShell to download
.PARAMETER Path
Path in your CDK project where you want to store your Lambda layers
.PARAMETER HelloWorld
If specified a basic HelloWorld AWS Lambda PowerShell file is created
.PARAMETER Force
Skip Confirmation
.NOTES
Author: Jake Morrison - @jakemorrison - https://www.techthoughts.info/
PowerShell and PowerShell modules are checked to see if the desired version is already downloaded.
If found, they are not re-downloaded.
Currently, the PowerShell custom runtime is downloaded every time the function is run.
.COMPONENT
cdk_pwsh_runtime_bootstrap.ps1
.LINK
https://aws.amazon.com/blogs/compute/introducing-the-powershell-custom-runtime-for-aws-lambda/
.LINK
https://github.com/awslabs/aws-lambda-powershell-runtime
#>
[CmdletBinding(ConfirmImpact = 'Low',
SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory = $false,
HelpMessage = 'File path to the root of CDK project')]
[string]
$CDKProjectPath = '.',
[Parameter(Mandatory = $false,
HelpMessage = 'Version of PowerShell to download')]
[string]
$PwshVersion = '7.2.6',
[Parameter(Mandatory = $false,
HelpMessage = 'Architecture version of PowerShell to download')]
[ValidateSet('x64', 'arm64')]
[string]
$PwshArchitecture = 'x64',
[Parameter(Mandatory = $true,
HelpMessage = 'Array of Hashtable(s) containing ModuleName and ModuleVersion for each required module')]
[array]
$RequiredModules,
[Parameter(Mandatory = $false,
HelpMessage = 'Path in your CDK project where you want to store your Lambda layers')]
[string]
$Path = 'src/lambda/layers/',
[Parameter(Mandatory = $false,
HelpMessage = 'Creates a HelloWorld AWS Lambda PowerShell file')]
[switch]$HelloWorld,
[Parameter(Mandatory = $false,
HelpMessage = 'Skip confirmation')]
[switch]$Force
)
begin {
if (-not $PSBoundParameters.ContainsKey('Verbose')) {
$VerbosePreference = $PSCmdlet.SessionState.PSVariable.GetValue('VerbosePreference')
}
if (-not $PSBoundParameters.ContainsKey('Confirm')) {
$ConfirmPreference = $PSCmdlet.SessionState.PSVariable.GetValue('ConfirmPreference')
}
if (-not $PSBoundParameters.ContainsKey('WhatIf')) {
$WhatIfPreference = $PSCmdlet.SessionState.PSVariable.GetValue('WhatIfPreference')
}
Write-Verbose -Message ('[{0}] Confirm={1} ConfirmPreference={2} WhatIf={3} WhatIfPreference={4}' -f $MyInvocation.MyCommand, $Confirm, $ConfirmPreference, $WhatIf, $WhatIfPreference)
} #begin
process {
if (-not((Test-Path -Path "$CDKProjectPath/cdk.json") -and (Test-Path -Path "$CDKProjectPath/package.json"))) {
throw ('{0} does not contain expected CDK project files. Specify the root of the CDK project.' -f $CDKProjectPath)
}
if ($Force -or $PSCmdlet.ShouldProcess('Bootstrap CDK project with PowerShell lambda layer')) {
Write-Verbose -Message ('[{0}] Reached command' -f $MyInvocation.MyCommand)
$powerShellLayerCheck = Test-PowerShellRuntimePresent -PowerShellVersion $PwshVersion -Path $Path
if (-not $powerShellLayerCheck) {
Write-Verbose 'Retrieving raw pwsh files from PowerShell GitHub'
$invokeGetPowerShellSplat = @{
PwshVersion = $PwshVersion
PwshArchitecture = $PwshArchitecture
Path = $Path
Force = $true
}
Invoke-GetPowerShell @invokeGetPowerShellSplat
}
else {
Write-Verbose 'PowerShell version verified. No action taken'
}
Write-Verbose 'Retrieving raw PowerShell runtime files from aws-lambda-powershell-runtime GitHub'
Invoke-GetAWSLambdaPowerShellRuntime -Path $Path -Force
Write-Verbose 'Retrieving all specified modules from PSGallery'
Invoke-GetRequiredModule $RequiredModules -Path $Path -Force
if ($HelloWorld) {
Write-Verbose 'Creating basic HelloWorld PowerShell lambda example'
$TargetDir = 'src/lambda/PowerShellLambda/HelloWorld'
if (-not(Test-Path -Path $TargetDir -ErrorAction Stop )) {
Write-Verbose -Message ('Output directory {0} not found. Creating...' -f $TargetDir)
$newItemSplat = @{
ItemType = 'Directory'
Path = $TargetDir
ErrorAction = 'Stop'
}
try {
New-Item @newItemSplat | Out-Null
Write-Verbose -Message 'Created.'
}
catch {
Write-Warning -Message 'An error was encountered creating the output directory:'
Write-Error $_
return
}
}
else {
Write-Verbose -Message 'Output directory verified.'
}
$lambdaExample = @'
#$VerbosePreference = 'Continue'
#$VerbosePreference = 'SilentlyContinue'
Write-Verbose -Message 'Run script init tasks before handler'
Write-Verbose -Message 'Importing Modules'
Import-Module 'AWS.Tools.Common'
function handler {
[CmdletBinding()]
param(
[Parameter()]
$LambdaInput,
[Parameter()]
$LambdaContext
)
Write-Verbose -Message 'Run handler function from HelloWorld script'
Write-Verbose -Message ('Function Remaining Time: {0}' -f $LambdaContext.GetRemainingTimeInMillis())
Get-AWSRegion
Write-Host 'Hello World! ^ Those are the current AWS Regions!'
}
'@
$lambdaExamplePath = '{0}/HelloWorld.ps1' -f $TargetDir
Write-Verbose -Message ('Creating HelloWorld PowerShell Lambda at: {0}' -f $lambdaExamplePath)
$lambdaExample | Out-File -FilePath $lambdaExamplePath -Encoding utf8 -Force
}
}
} #process
} #Invoke-BootStrapCDKProject
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment