Skip to content

Instantly share code, notes, and snippets.

@skewl84
Created May 23, 2021 15:11
Show Gist options
  • Save skewl84/44c7e806f80fdf657c2ac586f20b918b to your computer and use it in GitHub Desktop.
Save skewl84/44c7e806f80fdf657c2ac586f20b918b to your computer and use it in GitHub Desktop.
Automates setup of cross account CDK deployments via cdk pipelines
<#
.Synopsis
Automates the CDK deploy process.
.DESCRIPTION
This script will deploy a cdk stack
.PARAMETER profile
This script will use provided user profile
.PARAMETER pipelineAccount
the pipeline / build account id
.PARAMETER pipelineBuildAdminRole
the pipeline / build account id
.PARAMETER env
workload environment ("dev", "staging", "sandbox", "prod")
.NOTES
Purpose: Automates the CDK deployment process.
Author: Samir Das
Date: 23/05/2021
#>
param (
[string]$iam_profile = "default",
[Parameter(Mandatory)]
[string]$pipelineAccount,
[Parameter(Mandatory)]
[string]$pipelineBuildAdminRole,
[ValidateSet("dev", "staging", "sandbox", "prod")]
[Parameter(Mandatory)]
[string]$env,
[string]$dryRun = $false
)
$greenCheck = @{
Object = [Char]8730
ForegroundColor = 'Green'
NoNewLine = $true
}
try {
Write-Host "Checking for toolings..."
# check if npm is installed
try {
if (Get-Command "npm") {
$nodeVersion = [int](((node -v) -replace 'v').Split( "{.}")[0])
if ($nodeVersion -lt 12) {
Write-Warning "Installed node version ($nodeVersion) is lower than 12"
}
else {
Write-Host @greenCheck
Write-Host " Node ($nodeVersion) already installed!"
}
}
}
catch {
if ($dryRun -eq $false) {
$name = "node-v14.15.0.msi"
msiexec.exe /passive /log "${name}.log" /package $name
}
}
# check if cdk is installed
try {
if (Get-Command "cdk") {
$cdkVersion = cdk --version
Write-Host @greenCheck
Write-Host " CDK CLI ($cdkVersion) already installed!"
}
}
catch {
if ($dryRun -eq $false) {
npm install -g aws-cdk@1.100.0
}
}
# check if aws cli is installed
try {
if (Get-Command "aws") {
$awsVersion = (aws --version).Split("{ }")[0]
Write-Host @greenCheck
Write-Host " AWS CLI ($awsVersion) already installed!"
}
}
catch {
if ($dryRun -eq $false) {
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi
}
}
Write-Host "`r`n"
# check with user if environment bootstrap is required
$bootstrapEnv = Read-Host "Do you need to bootstrap the $env environment for deployment? (y/n)"
if ($bootstrapEnv -eq 'y') {
Write-Host "Bootstrapping $env workload environment..."
# assume workload environment IAM administrator role
$envAccountId = Read-Host "Enter $env account id"
$envIAMRole = Read-Host "Enter $env IAM administrator role"
$envMFA = Read-Host "Enter MFA"
Write-Host "Assuming role $envIAMRole in the $env account..."
if ($dryRun -eq $false) {
& $PSScriptRoot\assume-role.ps1 -iam_profile $iam_profile -roleARNToAssume "arn:aws:iam::$envAccountId\:role/$envIAMRole" -mfa $envMFA
}
Write-Host "Assumed role $envIAMRole in the $env account."
# check if CDK toolkit exists
try {
$response = aws cloudformation describe-stacks --stack-name "CDKToolkit"
if ($null -ne $response) {
Write-Host "Account has been already bootstrapped!"
}
}
catch {
Write-Host "Environment was not bootstrapped. Proceeding to bootstrapping..."
if ($dryRun -eq $false) {
cd..
Set-Variable CDK_NEW_BOOTSTRAP=1
cdk bootstrap --cloudformation-execution-policies 'arn:aws:iam::aws:policy/AdministratorAccess' aws://$envAccountId/ap-southeast-2 --trust $pipelineAccount
}
}
}
Write-Host "`r`n"
# assume pipeline account builder role
Write-Host "Deploying the pipeline stack to the build account..."
$envMFA = Read-Host "Enter MFA"
Set-Location .\cli
Write-Host "Assuming role $pipelineBuildAdminRole in the pipeline account..."
if ($dryRun -eq $false) {
& .\assume-role.ps1 -iam_profile $iam_profile -roleARNToAssume "arn:aws:iam::$pipelineAccount\:role/$pipelineBuildAdminRole" -mfa $envMFA
}
Write-Host "Assumed role $pipelineBuildAdminRole in the pipeline account."
Write-Host "`r`n"
# synthesize the cdk stack
Write-Host "Synthesizing stack(s)..."
cd..
$synthResponse = cdk synth
if ($synthResponse) {
Write-Host "Successfully synthesized the stack(s)!"
}
Write-Host "`r`n"
# deploy the cdk stack
$stackList = ((cdk list) -split '\r?\n').Trim()
$stackIdEnvPostFix = ""
switch ($env) {
"dev" { $stackIdEnvPostFix = "Develop" }
"staging" { $stackIdEnvPostFix = "Staging" }
"sandbox" { $stackIdEnvPostFix = "Sandbox" }
"prod" { $stackIdEnvPostFix = "Prod" }
Default { $stackIdEnvPostFix = $env }
}
$envStackId = $stackList.where( { $_ -match $stackIdEnvPostFix })
if ($envStackId -ne "") {
Write-Host "Deploying $envStackId to $env environment..."
if ($dryRun -eq $false) {
cdk deploy $envStackId
}
Write-Host "Successfully deployed $envStackId to $env environment!"
}
Write-Host "`r`n"
}
catch {
Write-Error "There was problem deploying the cdk stack. See error above."
}
finally {
#remove the AWS identity variables
if ($env:AWS_ACCESS_KEY_ID) {
Remove-Item env:AWS_ACCESS_KEY_ID
}
if ($env:AWS_SECRET_ACCESS_KEY) {
Remove-Item env:AWS_SECRET_ACCESS_KEY
}
if ($env:AWS_SESSION_TOKEN) {
Remove-Item env:AWS_SESSION_TOKEN
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment