implemented aws.#Config and aws/cloudformation packages in stdlib
Signed-off-by: Sam Alba <sam.alba@gmail.com>
This commit is contained in:
parent
98a06c67d2
commit
64ab495c82
10
stdlib/aws/aws.cue
Normal file
10
stdlib/aws/aws.cue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package aws
|
||||||
|
|
||||||
|
#Config: {
|
||||||
|
// AWS region
|
||||||
|
region: string
|
||||||
|
// AWS access key
|
||||||
|
accessKey: string // FIXME: should be a secret
|
||||||
|
// AWS secret key
|
||||||
|
secretKey: string // FIXME: should be a secret
|
||||||
|
}
|
101
stdlib/aws/cloudformation/cloudformation.cue
Normal file
101
stdlib/aws/cloudformation/cloudformation.cue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package cloudformation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"dagger.io/dagger"
|
||||||
|
"dagger.io/alpine"
|
||||||
|
"dagger.io/aws"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AWS CloudFormation Stack
|
||||||
|
#Stack: {
|
||||||
|
|
||||||
|
// AWS Config
|
||||||
|
config: aws.#Config
|
||||||
|
|
||||||
|
// Source is the Cloudformation template (JSON/YAML string)
|
||||||
|
source: string
|
||||||
|
|
||||||
|
// Stackname is the cloudformation stack
|
||||||
|
stackName: string
|
||||||
|
|
||||||
|
// Stack parameters
|
||||||
|
parameters: [string]: _
|
||||||
|
|
||||||
|
// Behavior when failure to create/update the Stack
|
||||||
|
onFailure: *"DO_NOTHING" | "ROLLBACK" | "DELETE"
|
||||||
|
|
||||||
|
// Timeout for waiting for the stack to be created/updated (in minutes)
|
||||||
|
timeout: *10 | uint
|
||||||
|
|
||||||
|
// Never update the stack if already exists
|
||||||
|
neverUpdate: *false | bool
|
||||||
|
|
||||||
|
#files: {
|
||||||
|
"/entrypoint.sh": #Code
|
||||||
|
"/src/template.json": source
|
||||||
|
if len(parameters) > 0 {
|
||||||
|
"/src/parameters.json": json.Marshal(
|
||||||
|
[ for key, val in parameters {
|
||||||
|
ParameterKey: "\(key)"
|
||||||
|
ParameterValue: "\(val)"
|
||||||
|
}])
|
||||||
|
"/src/parameters_overrides.json": json.Marshal([ for key, val in parameters {"\(key)=\(val)"}])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs: {
|
||||||
|
[string]: string
|
||||||
|
|
||||||
|
#dagger: compute: [
|
||||||
|
dagger.#Load & {
|
||||||
|
from: alpine.#Image & {
|
||||||
|
package: bash: "=5.1.0-r0"
|
||||||
|
package: jq: "=1.6-r1"
|
||||||
|
package: "aws-cli": "=1.18.177-r0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dagger.#Mkdir & {
|
||||||
|
path: "/src"
|
||||||
|
},
|
||||||
|
for dest, content in #files {
|
||||||
|
dagger.#WriteFile & {
|
||||||
|
"dest": dest
|
||||||
|
"content": content
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dagger.#Exec & {
|
||||||
|
args: [
|
||||||
|
"/bin/bash",
|
||||||
|
"--noprofile",
|
||||||
|
"--norc",
|
||||||
|
"-eo",
|
||||||
|
"pipefail",
|
||||||
|
"/entrypoint.sh",
|
||||||
|
]
|
||||||
|
env: {
|
||||||
|
AWS_CONFIG_FILE: "/cache/aws/config"
|
||||||
|
AWS_ACCESS_KEY_ID: config.accessKey
|
||||||
|
AWS_SECRET_ACCESS_KEY: config.secretKey
|
||||||
|
AWS_DEFAULT_REGION: config.region
|
||||||
|
AWS_REGION: config.region
|
||||||
|
AWS_DEFAULT_OUTPUT: "json"
|
||||||
|
AWS_PAGER: ""
|
||||||
|
if neverUpdate {
|
||||||
|
NEVER_UPDATE: "true"
|
||||||
|
}
|
||||||
|
STACK_NAME: stackName
|
||||||
|
TIMEOUT: "\(timeout)"
|
||||||
|
ON_FAILURE: onFailure
|
||||||
|
}
|
||||||
|
dir: "/src"
|
||||||
|
mount: "/cache/aws": "cache"
|
||||||
|
},
|
||||||
|
dagger.#Export & {
|
||||||
|
source: "/outputs.json"
|
||||||
|
format: "json"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
108
stdlib/aws/cloudformation/code.cue
Normal file
108
stdlib/aws/cloudformation/code.cue
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package cloudformation
|
||||||
|
|
||||||
|
#Code: #"""
|
||||||
|
set +o pipefail
|
||||||
|
|
||||||
|
aws cloudformation validate-template --template-body file:///src/template.json
|
||||||
|
parameters=""
|
||||||
|
|
||||||
|
function getOutputs() {
|
||||||
|
aws cloudformation describe-stacks \
|
||||||
|
--stack-name "$STACK_NAME" \
|
||||||
|
--query 'Stacks[].Outputs' \
|
||||||
|
--output json \
|
||||||
|
| jq '.[] | map( { (.OutputKey|tostring): .OutputValue } ) | add' \
|
||||||
|
> /outputs.json
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the stack exists
|
||||||
|
aws cloudformation describe-stacks --stack-name "$STACK_NAME" 2>/dev/null || {
|
||||||
|
if [ -f /src/parameters.json ]; then
|
||||||
|
parameters="--parameters file:///src/parameters.json"
|
||||||
|
cat /src/parameters.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
aws cloudformation create-stack \
|
||||||
|
--stack-name "$STACK_NAME" \
|
||||||
|
--template-body "file:///src/template.json" \
|
||||||
|
--capabilities CAPABILITY_IAM \
|
||||||
|
--on-failure "$ON_FAILURE" \
|
||||||
|
--timeout-in-minutes "$TIMEOUT" \
|
||||||
|
$parameters \
|
||||||
|
|| {
|
||||||
|
# Create failed, display errors
|
||||||
|
aws cloudformation describe-stack-events \
|
||||||
|
--stack-name "$STACK_NAME" \
|
||||||
|
--max-items 10 \
|
||||||
|
| >&2 jq '.StackEvents[] | select((.ResourceStatus | contains("FAILED")) or (.ResourceStatus | contains("ERROR"))) | ("===> ERROR: " + .LogicalResourceId + ": " + .ResourceStatusReason)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
aws cloudformation wait stack-create-complete \
|
||||||
|
--stack-name "$STACK_NAME"
|
||||||
|
|
||||||
|
getOutputs
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# In case there is an action already in progress, we wait for the corresponding action to complete
|
||||||
|
wait_action=""
|
||||||
|
stack_status=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" | jq -r '.Stacks[].StackStatus')
|
||||||
|
case "$stack_status" in
|
||||||
|
"CREATE_FAILED")
|
||||||
|
echo "Deleting previous failed stack..."
|
||||||
|
aws cloudformation delete-stack --stack-name "$STACK_NAME"
|
||||||
|
aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
"CREATE_IN_PROGRESS")
|
||||||
|
echo "Stack create already in progress, waiting..."
|
||||||
|
aws cloudformation wait stack-create-complete --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
"UPDATE_IN_PROGRESS")
|
||||||
|
# Cancel update to avoid stacks stuck in deadlock (re-apply then works)
|
||||||
|
echo "Stack update already in progress, waiting..."
|
||||||
|
aws cloudformation cancel-update-stack --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
"ROLLBACK_IN_PROGRESS")
|
||||||
|
echo "Stack rollback already in progress, waiting..."
|
||||||
|
aws cloudformation wait stack-rollback-complete --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
"DELETE_IN_PROGRESS")
|
||||||
|
echo "Stack delete already in progress, waiting..."
|
||||||
|
aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
"UPDATE_COMPLETE_CLEANUP_IN_PROGRESS")
|
||||||
|
echo "Stack update almost completed, waiting..."
|
||||||
|
aws cloudformation wait stack-update-complete --stack-name "$STACK_NAME" || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -n "$NEVER_UPDATE" ] && {
|
||||||
|
getOutputs
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Stack exists, trigger an update via `deploy`
|
||||||
|
if [ -f /src/parameters_overrides.json ]; then
|
||||||
|
parameters="--parameter-overrides file:///src/parameters_overrides.json"
|
||||||
|
cat /src/parameters_overrides.json
|
||||||
|
fi
|
||||||
|
echo "Deploying stack $STACK_NAME"
|
||||||
|
aws cloudformation deploy \
|
||||||
|
--stack-name "$STACK_NAME" \
|
||||||
|
--template-file "/src/template.json" \
|
||||||
|
--capabilities CAPABILITY_IAM \
|
||||||
|
--no-fail-on-empty-changeset \
|
||||||
|
$parameters \
|
||||||
|
|| {
|
||||||
|
# Deploy failed, display errors
|
||||||
|
echo "Failed to deploy stack $STACK_NAME"
|
||||||
|
aws cloudformation describe-stack-events \
|
||||||
|
--stack-name "$STACK_NAME" \
|
||||||
|
--max-items 10 \
|
||||||
|
| >&2 jq '.StackEvents[] | select((.ResourceStatus | contains("FAILED")) or (.ResourceStatus | contains("ERROR"))) | ("===> ERROR: " + .LogicalResourceId + ": " + .ResourceStatusReason)'
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
getOutputs
|
||||||
|
"""#
|
Reference in New Issue
Block a user