ps/Modules/Alkami.DevOps.SystemEngineering/Private/New-ServerlessServiceAccountSecret.ps1
2023-05-30 22:51:22 -07:00

118 lines
5.0 KiB
PowerShell

function New-ServerlessServiceAccountSecret {
<#
.SYNOPSIS
Creates and configures an AWS Secrets Manager secret for serverless service accounts.
.DESCRIPTION
Creates and configures an AWS Secrets Manager secret for serverless service accounts.
The first account will be in secret version 'AWSPREVIOUS' and the second account will be in
secret version 'AWSCURRENT'.
Configures replication on the created secret if the replication region is non-null, non-empty.
Does not apply a resource policy to the created secret; this will need to be applied after creation.
.PARAMETER SecretName
[string] The name of the secret to create.
.PARAMETER UserDataList
[PSCredential[]] An array with exactly two credential objects containing the usernames and passwords to use
during account creation.
.PARAMETER EnvironmentTag
[string] The 'alk:env' tag value to apply to the created secret.
.PARAMETER ProfileName
[string] The AWS profile to use during secret creation.
.PARAMETER Region
[string] The AWS region to use during user creation.
.PARAMETER ReplicationRegion
[string] The target AWS region for replicated AWS Secrets Manager secrets.
To disable replication, set this value to null or empty.
.PARAMETER Description
[string] The description of the created secret.
.EXAMPLE
New-ServerlessServiceAccountSecret -SecretName 'Example' `
-UserDataList @(( Get-AlkamiCredential -UserName 'ExampleA' -Password 'ExampleA!1Pass'), ( Get-AlkamiCredential -UserName 'ExampleB' -Password 'ExampleB!1Pass')) `
-EnvironmentTag 'prodshared' `
-ProfileName 'temp-prod' `
-Region 'us-east-1' `
-ReplicationRegion 'us-west-2' `
-Description 'Example secret'
#>
[OutputType([string[]])]
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $SecretName,
[Parameter(Mandatory = $true)]
[ValidateCount(2, 2)]
[PSCredential[]] $UserDataList,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $EnvironmentTag,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $ProfileName,
[Parameter(Mandatory = $true)]
[ValidateScript({$_ -in (Get-AWSRegion).region})]
[string] $Region,
[Parameter(Mandatory = $true)]
[AllowNull()]
[AllowEmptyString()]
[ValidateScript({([String]::IsNullOrEmpty($_) -or ($_ -in (Get-AWSRegion).region))})]
[string] $ReplicationRegion,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string] $Description
)
Import-AWSModule
$logLead = (Get-LogLeadName)
$result = @()
# Create the Secrets Manager object in AWS with the first user's data.
Write-Verbose ( "{0} : Creating secret named '{1}' with {2} data" -f $logLead, $SecretName, $UserDataList[0].UserName )
$secretString = (ConvertTo-Json -InputObject @{ 'username' = $UserDataList[0].UserName ; 'password' = (Get-PasswordFromCredential $UserDataList[0]) } -Compress -Depth 10)
$tag1 = New-Object -TypeName PSObject -Property @{ Key="alk:project" ; Value="orb" }
$tag2 = New-Object -TypeName PSObject -Property @{ Key="alk:service" ; Value="serverless" }
$tag3 = New-Object -TypeName PSObject -Property @{ Key="alk:env" ; Value="$EnvironmentTag" }
$response = New-SECSecret -SecretString $secretString -Name $SecretName -Description $Description -Tag @($tag1,$tag2, $tag3) `
-ProfileName $ProfileName -Region $Region
$result += $response.ARN
# Write the second user's data to the existing secret.
# AWS will manage the AWSPREVIOUS and AWSCURRENT tags with this call, setting
# us up for future secret rotation efforts.
Write-Verbose ( "{0} : Updating secret value for '{1}' with {2} data" -f $logLead, $SecretName, $UserDataList[1].UserName )
$secretString = (ConvertTo-Json -InputObject @{ 'username' = $UserDataList[1].UserName ; 'password' = (Get-PasswordFromCredential $UserDataList[1]) } -Compress -Depth 10)
Write-SECSecretValue -SecretString $secretString -SecretId $SecretName -ProfileName $ProfileName -Region $Region | Out-Null
# Enable replication on the secret (if the operator didn't turn off that feature).
if ( $false -eq [string]::IsNullOrWhitespace( $ReplicationRegion )) {
$replicaConfig = New-Object Amazon.SecretsManager.Model.ReplicaRegionType
$replicaConfig.Region = $ReplicationRegion
Write-Verbose "$logLead : Replicating newly created secret to $ReplicationRegion."
$response = Add-SECSecretToRegion -SecretId $SecretName -AddReplicaRegion @($replicaConfig) -ProfileName $ProfileName -Region $Region
# AWS returns the original secret's ARN, not the replicated secret's ARN. Luckily, the only thing different about the ARN is the region.
$result += ( $response.ARN -replace $Region, $ReplicationRegion )
}
return $result
}