Skip to content
This repository has been archived by the owner on Mar 16, 2024. It is now read-only.

Commit

Permalink
Add hook and snapshot lists (#50)
Browse files Browse the repository at this point in the history
Signed-off-by: Bill Maxwell <[email protected]>
  • Loading branch information
cloudnautique authored Oct 18, 2023
1 parent a3c884f commit 8c4752e
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 15 deletions.
19 changes: 10 additions & 9 deletions rds/aurora/mysql/cluster/Acornfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ args: {
instanceSize: "medium"
// RDS MySQL Database Parameters to apply to the cluster. Must be k/v string pairs(ex. max_connections: "1000").
parameters: {}
// Creates a new cluster from this snapshot or revert the existing database cluster to this snapshot. Once this has been set, should remain the same on subsequent runs. Default is "".
restoreFromSnapshotArn: ""
// Do not take a final snapshot on delete or update and replace operations. Default is false. If skip is enabled the DB will be gone forever if deleted or replaced.
skipSnapshotOnDelete: false
// Enable Performance insights. Default is false.
Expand All @@ -39,15 +41,7 @@ services: rds: {
}

jobs: apply: {
build: {
context: "../../../"
dockerfile: "../../../mysql.Dockerfile"
buildArgs: MAIN: "cluster"
additionalContexts: {
common: "../../../../libs"
utils: "../../../../utils"
}
}
build: images.cdk.containerBuild
files: "/app/config.json": std.toJSON(args)
memory: 512Mi
env: {
Expand Down Expand Up @@ -126,6 +120,13 @@ images: user: containerBuild: {
target: "user"
}

images: cdk: containerBuild: {
context: "../../../"
dockerfile: "../../../mysql.Dockerfile"
buildArgs: MAIN: "cluster"
additionalContexts: common: "../../../../libs"
}

secrets: admin: {
type: "generated"
params: job: "apply"
Expand Down
7 changes: 7 additions & 0 deletions rds/aurora/mysql/cluster/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
}),
})

if props.RestoreSnapshotArn != "" {
awscdk.Aspects_Of(cluster).Add(rds.NewSnapshotAspect(props.RestoreSnapshotArn))
}

port := "3306"
pSlice := strings.SplitN(*cluster.ClusterEndpoint().SocketAddress(), ":", 2)
if len(pSlice) == 2 {
Expand All @@ -87,6 +91,9 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
awscdk.NewCfnOutput(stack, jsii.String("adminpasswordarn"), &awscdk.CfnOutputProps{
Value: cluster.Secret().SecretArn(),
})
awscdk.NewCfnOutput(stack, jsii.String("clusterid"), &awscdk.CfnOutputProps{
Value: cluster.ClusterIdentifier(),
})

return stack
}
Expand Down
2 changes: 2 additions & 0 deletions rds/aurora/mysql/serverless-v1/Acornfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ args: {
auroraCapacityUnitsMax: 8
// Time in minutes to pause Aurora serverless-v1 DB cluster after it's been idle. Default is 10 set to 0 to disable.
autoPauseDurationMinutes: 10
// Create a new cluster from this snapshot or revert the existing database cluster to this snapshot. Once this has been set, should remain the same on subsequent runs. Default is "".
restoreFromSnapshotArn: ""
// Do not take a final snapshot on delete or update and replace operations. Default is false. If skip is enabled the DB will be gone forever if deleted or replaced.
skipSnapshotOnDelete: false
// Key value pairs of tags to apply to the RDS cluster and all other resources.
Expand Down
7 changes: 7 additions & 0 deletions rds/aurora/mysql/serverless-v1/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
ParameterGroup: parameterGroup,
})

if props.RestoreSnapshotArn != "" {
awscdk.Aspects_Of(cluster).Add(rds.NewSnapshotAspect(props.RestoreSnapshotArn))
}

port := "3306"
pSlice := strings.SplitN(*cluster.ClusterEndpoint().SocketAddress(), ":", 2)
if len(pSlice) == 2 {
Expand All @@ -76,6 +80,9 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
awscdk.NewCfnOutput(stack, jsii.String("adminpasswordarn"), &awscdk.CfnOutputProps{
Value: cluster.Secret().SecretArn(),
})
awscdk.NewCfnOutput(stack, jsii.String("clusterid"), &awscdk.CfnOutputProps{
Value: cluster.ClusterIdentifier(),
})

return stack
}
Expand Down
2 changes: 2 additions & 0 deletions rds/aurora/mysql/serverless-v2/Acornfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ args: {
auroraCapacityUnitsV2Max: *8.0 | float | int
// RDS MySQL Database Parameters to apply to the cluster. Must be k/v string pairs(ex. max_connections: "1000").
parameters: {}
// Creates a new cluster from this snapshot or revert the existing database cluster to this snapshot. Once this has been set, should remain the same on subsequent runs. Default is "".
restoreFromSnapshotArn: ""
// Do not take a final snapshot on delete or update and replace operations. Default is false. If skip is enabled the DB will be gone forever if deleted or replaced.
skipSnapshotOnDelete: false
// Enable Performance Insights. Default is false.
Expand Down
7 changes: 7 additions & 0 deletions rds/aurora/mysql/serverless-v2/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
ParameterGroup: parameterGroup,
})

if props.RestoreSnapshotArn != "" {
awscdk.Aspects_Of(cluster).Add(rds.NewSnapshotAspect(props.RestoreSnapshotArn))
}

port := "3306"
pSlice := strings.SplitN(*cluster.ClusterEndpoint().SocketAddress(), ":", 2)
if len(pSlice) == 2 {
Expand All @@ -78,6 +82,9 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
awscdk.NewCfnOutput(stack, jsii.String("adminpasswordarn"), &awscdk.CfnOutputProps{
Value: cluster.Secret().SecretArn(),
})
awscdk.NewCfnOutput(stack, jsii.String("clusterid"), &awscdk.CfnOutputProps{
Value: cluster.ClusterIdentifier(),
})

return stack
}
Expand Down
2 changes: 2 additions & 0 deletions rds/aurora/postgres/cluster/Acornfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ args: {
instanceSize: "medium"
// RDS PostgreSQL Database Parameters to apply to the cluster. Must be k/v string pairs(ex. max_connections: "1000").
parameters: {}
// Create a new cluster from this snapshot or revert the existing database cluster to this snapshot. Once this has been set, should remain the same on subsequent runs. Default is "".
restoreFromSnapshotArn: ""
// Do not take a final snapshot on delete or update and replace operations. Default is false. If skip is enabled the DB will be gone forever if deleted or replaced.
skipSnapshotOnDelete: false
// Enable Performance insights. Default is false.
Expand Down
7 changes: 7 additions & 0 deletions rds/aurora/postgres/cluster/rds.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
}),
})

if props.RestoreSnapshotArn != "" {
awscdk.Aspects_Of(cluster).Add(rds.NewSnapshotAspect(props.RestoreSnapshotArn))
}

port := "5432"
pSlice := strings.SplitN(*cluster.ClusterEndpoint().SocketAddress(), ":", 2)
if len(pSlice) == 2 {
Expand All @@ -82,6 +86,9 @@ func NewRDSStack(scope constructs.Construct, props *rds.RDSStackProps) awscdk.St
awscdk.NewCfnOutput(stack, jsii.String("adminpasswordarn"), &awscdk.CfnOutputProps{
Value: cluster.Secret().SecretArn(),
})
awscdk.NewCfnOutput(stack, jsii.String("clusterid"), &awscdk.CfnOutputProps{
Value: cluster.ClusterIdentifier(),
})

return stack
}
Expand Down
18 changes: 17 additions & 1 deletion rds/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type RDSStackProps struct {
InstanceClass string `json:"instanceClass"`
InstanceSize string `json:"instanceSize"`
Parameters map[string]string `json:"parameters"`
RestoreSnapshotArn string `json:"restoreSnapshotArn"`
RestoreSnapshotArn string `json:"restoreFromSnapshotArn"`
SkipSnapShotOnDelete bool `json:"skipSnapshotOnDelete"`
Tags map[string]string `json:"tags"`
VpcID string
Expand All @@ -48,6 +48,22 @@ type RDSStackProps struct {
AuroraCapacityUnitsV2Max float64 `json:"auroraCapacityUnitsV2Max"`
}

type SnapshotAspect struct {
SnapshotIdentifier string
}

func (sa *SnapshotAspect) Visit(node constructs.IConstruct) {
if n, ok := node.(awsrds.CfnDBCluster); ok {
n.AddPropertyOverride(jsii.String("SnapshotIdentifier"), jsii.String(sa.SnapshotIdentifier))
}
}

func NewSnapshotAspect(snapshotIdentifier string) *SnapshotAspect {
return &SnapshotAspect{
SnapshotIdentifier: snapshotIdentifier,
}
}

func NewParameterGroup(scope constructs.Construct, name *string, props *RDSStackProps, engine awsrds.IClusterEngine) awsrds.ParameterGroup {
parameterGroup := awsrds.NewParameterGroup(scope, name, &awsrds.ParameterGroupProps{
Engine: engine,
Expand Down
41 changes: 41 additions & 0 deletions rds/hooks/pre-change-set-apply
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# On delete, do not get involved, the user might be trying to disable delete protection.
if [ "${ACORN_EVENT}" = "delete" ]; then
echo "Skipping pre-apply hook on delete event."
exit 0
fi

write_error() {
echo "Error: $1" >&2
exit 1
}

help() {
echo "Usage: $0 <current_cfn_template> <proposed_cfn_template> <change_set>"
write_error "Usage: $0 <current_cfn_template> <proposed_cfn_template> <change_set>" >&2
}

snapshot_identifier_present() {
grep "SnapshotIdentifier" "${1}" > /dev/null
return $?
}

if [ "$#" -ne 3 ]; then
help
fi

current_cfn_template="${1}"
proposed_cfn_template="${2}"
change_set="${3}"


snapshot_identifier_present "${current_cfn_template}"
current_snapshot=$?
snapshot_identifier_present "${proposed_cfn_template}"
proposed_snapshot=$?

if [ "${current_snapshot}" -eq 0 ] && [ "${proposed_snapshot}" -eq 1 ]; then
value=$(grep "SnapshotIdentifier" "${current_cfn_template}" | awk '{print $2}')
write_error "Cannot change from snapshot ${value} to no snapshot. You must delete Acorn ${ACORN_NAME} to reset."
fi
5 changes: 3 additions & 2 deletions rds/mysql.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ COPY --from=common . ../libs/
COPY . .
RUN --mount=type=cache,target=/root/go/pkg \
--mount=type=cache,target=/root/.cache/go-build \
go build -o rds ./aurora/mysql/${MAIN}
go build -o rds ./aurora/mysql/${MAIN}

FROM cgr.dev/chainguard/mariadb as user
WORKDIR /app
COPY ./scripts ./scripts
ENTRYPOINT ["/app/scripts/create_and_grant_users.sh"]

FROM ghcr.io/acorn-io/aws/utils/cdk-runner:v0.6.0 as cdk-runner
FROM ghcr.io/acorn-io/aws/utils/cdk-runner:v0.7.1 as cdk-runner
FROM cgr.dev/chainguard/wolfi-base
RUN apk add -U --no-cache nodejs bash busybox jq curl zip && \
apk del --no-cache wolfi-base apk-tools
Expand All @@ -23,6 +23,7 @@ RUN npm install -g aws-cdk
WORKDIR /app
COPY ./cdk.json ./
COPY ./scripts ./scripts
COPY ./hooks ./hooks
COPY --from=cdk-runner /cdk-runner .
COPY --from=build /src/rds/rds .

Expand Down
7 changes: 4 additions & 3 deletions rds/postgres.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ WORKDIR /app
COPY ./scripts ./scripts
ENTRYPOINT ["/app/scripts/create_and_grant_users_psql.sh"]

FROM ghcr.io/acorn-io/aws/utils/cdk-runner:v0.6.0 as cdk-runner
FROM ghcr.io/acorn-io/aws/utils/cdk-runner:v0.7.1 as cdk-runner
FROM cgr.dev/chainguard/wolfi-base
RUN apk add -U --no-cache nodejs bash busybox jq curl zip && \
apk del --no-cache wolfi-base apk-tools
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install
unzip awscliv2.zip && \
./aws/install
RUN npm install -g aws-cdk
WORKDIR /app
COPY ./cdk.json ./
COPY ./scripts ./scripts
COPY ./hooks ./hooks
COPY --from=cdk-runner /cdk-runner .
COPY --from=build /src/rds/rds .

Expand Down
3 changes: 3 additions & 0 deletions rds/scripts/list-snapshots.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
set -x
aws rds describe-db-cluster-snapshots --db-cluster-identifier "${DB_CLUSTER_ID}" --query "DBClusterSnapshots[*].DBClusterSnapshotArn" | jq -r '.[]' > /run/secrets/output
2 changes: 2 additions & 0 deletions rds/scripts/service.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PORT="$( jq -r '.[] | select(.OutputKey=="port") |.OutputVal
ADDRESS="$( jq -r '.[] | select(.OutputKey=="host") |.OutputValue' outputs.json )"
ADMIN_USERNAME="$(jq -r '.[] | select(.OutputKey=="adminusername") |.OutputValue' outputs.json )"
PASSWORD_ARN="$( jq -r '.[] | select(.OutputKey=="adminpasswordarn")|.OutputValue' outputs.json )"
CLUSTER_ID="$( jq -r '.[] | select(.OutputKey=="clusterid") |.OutputValue' outputs.json )"

ADMIN_PASSWORD="$(aws --output json secretsmanager get-secret-value --secret-id "${PASSWORD_ARN}" --query 'SecretString' | jq -r .|jq -r .password)"

Expand All @@ -15,6 +16,7 @@ services: rds: {
ports: [${PORT}]
data: {
dbName: "${DB_NAME}"
clusterId: "${CLUSTER_ID}"
}
}
Expand Down

0 comments on commit 8c4752e

Please sign in to comment.