Skip to content
Closed
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
cfbbde8
chore: add DNS to shared resources
jeastham1993 Jan 29, 2026
130a8d8
feat: add domain name to shared resources
jeastham1993 Jan 29, 2026
81304bd
feat: update user service to use Cloudfront endpoint
jeastham1993 Jan 29, 2026
3257a29
feat: update OAuthissuer
jeastham1993 Jan 29, 2026
f3ce933
feat: add Cloudfront endpoint to services
jeastham1993 Jan 29, 2026
91babc1
chore: update deployment workflows
jeastham1993 Jan 29, 2026
6e49337
chore: update endpoint for web backend
jeastham1993 Jan 29, 2026
3110bf6
feat: add deployable DNS
jeastham1993 Jan 29, 2026
c1206b4
feat: reference cert and zone in shared resources
jeastham1993 Jan 29, 2026
9fa4af3
chore: add hosted zone configuration to shared resources
jeastham1993 Jan 29, 2026
f0a181a
chore: update shared resources variables
jeastham1993 Jan 29, 2026
29a41a7
chore: remove shared deps from AWS deploy
jeastham1993 Jan 29, 2026
6b750fb
fix: resolve DNS mapping issues on deploy
jeastham1993 Jan 30, 2026
f56f2e6
feat: add protected environment guard for AWS deployments
jeastham1993 Feb 2, 2026
3843e82
fix: remove DNS from user environment deploy
jeastham1993 Feb 2, 2026
8d94e97
chore: add AWS guard to sub mise files
jeastham1993 Feb 2, 2026
97d9f26
chore: add env to autoset to username
jeastham1993 Feb 2, 2026
30d217d
chore: fix connection string parsing for .NET
jeastham1993 Feb 2, 2026
dbb081b
chore: remove unused env vars
jeastham1993 Feb 2, 2026
da049b6
chore: update comments on database parameter parser
jeastham1993 Feb 2, 2026
979a005
chore: add README to shared DNS
jeastham1993 Feb 2, 2026
77988ce
fix: allow cert ARN to not be set in shared resources.
jeastham1993 Feb 2, 2026
5045a31
chore: shorten bucket name
jeastham1993 Feb 2, 2026
6c1cc4d
chore: add workflow to deploy shared infra
jeastham1993 Feb 2, 2026
d2465c6
chore: remove setup go
jeastham1993 Feb 2, 2026
f52fa70
chore: update domain name parsing
jeastham1993 Feb 2, 2026
15cd55b
fix: resolve variable name issue in other stacks
jeastham1993 Feb 2, 2026
06503c5
fix: qualify aws:guard tasks with root path for mise
scottgerring Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions .github/workflows/shared-infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2025-Present Datadog, Inc.

name: Shared AWS Infra

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
paths:
- "shared/infra/aws/**"
- ".github/**"
workflow_dispatch:
inputs:
deploy:
description: "Deploy to AWS dev environment after build"
required: false
default: false
type: boolean

jobs:
deploy-aws-dev:
runs-on: ubuntu-latest
if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'workflow_dispatch' && inputs.deploy == true)
permissions:
contents: read
packages: write
attestations: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: "20"
- name: Install CDK
run: |
npm install -g aws-cdk
- name: Install dependencies
shell: bash
run: |
cd shared/lib/shared-constructs
npm i
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
role-session-name: GitHub_to_AWS_via_FederatedOIDC
aws-region: "eu-west-1"
- name: Set Commit Hash Environment Variables
shell: bash
run: |
echo "sha_short=$(git rev-parse --short "$GITHUB_SHA")" >> "$GITHUB_ENV"
echo "sha_full=$(git rev-parse "$GITHUB_SHA")" >> "$GITHUB_ENV"
- name: Deploy to dev AWS
shell: bash
env:
COMMIT_SHA: ${{ env.sha_short }}
COMMIT_SHA_FULL: ${{ env.sha_full }}
ENV: "dev"
DD_API_KEY: ${{secrets.DD_API_KEY}}
HOSTED_ZONE_ID: ${{secrets.HOSTED_ZONE_ID}}
CERTIFICATE_ARN: ${{secrets.CERTIFICATE_ARN}}
DD_SITE: "datadoghq.com"
run: |
cd shared/infra/aws
npm i
cdk deploy --require-approval never
74 changes: 70 additions & 4 deletions mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ _.file = { path = ".env", optional = true }
[tasks."env:setup"]
description = "Create .env file with required configuration"
hide = true
raw = true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this doing?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scottgerring without the raw tag my terminal crapped out because it couldn't accept user input. Adding the raw flag was the fix.

@scottgerring scottgerring Feb 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crapped out when - on the prompting for .env population? I've never seen this and suspect you've got something munted in your TERM or so but regardless .... what else does raw do? is this going to affect any other behaviour?

run = """
if [ -f .env ]; then
exit 0
Expand All @@ -41,9 +42,14 @@ fi
echo "Creating .env file..."
echo "Press Enter to use default values shown in brackets"
echo ""
echo "NOTE: 'dev' and 'prod' are protected environments (CI/CD only)."
echo " Use your initials or a personal name for local development."
echo ""

read -p "Environment name (e.g., your initials) [dev]: " ENV
ENV=${ENV:-dev}
DEFAULT_ENV=$(whoami | tr -cd '[:alnum:]')
Comment thread
jeastham1993 marked this conversation as resolved.
read -p "Environment name [$DEFAULT_ENV]: " ENV
ENV=${ENV:-$DEFAULT_ENV}
ENV=$(echo "$ENV" | tr -cd '[:alnum:]')
read -p "Datadog API Key: " DD_API_KEY
read -p "Datadog Site [datadoghq.eu]: " DD_SITE
DD_SITE=${DD_SITE:-datadoghq.eu}
Expand Down Expand Up @@ -160,11 +166,71 @@ run = "./scripts/test-services.sh --max-retries 5 --retry-delay 10"
# image), set COMMIT_SHA to the desired tag and run aws:deploy directly
# without setting DEPLOY_MODE. For example:
# COMMIT_SHA=abc123 npx cdk deploy (from infra/aws directory)
#
# PROTECTED ENVIRONMENTS:
# The 'dev' and 'prod' environments are protected and can ONLY be deployed
# to from CI/CD pipelines. Local deployments to these environments will be
# blocked by the aws:guard task. This ensures:
# - Production stability (no accidental local deployments)
# - Consistent deployment process through CI/CD
# - Audit trail for all production changes
#
# For local development, use a personal environment name (e.g., your initials).
# CI/CD pipelines are detected via standard environment variables:
# - CI=true (generic, set by most CI systems)
# - GITHUB_ACTIONS=true (GitHub Actions)
# - GITLAB_CI=true (GitLab CI)
# - CIRCLECI=true (CircleCI)
# - JENKINS_URL (Jenkins)
# =============================================================================

# Guard task to prevent local deployments to protected environments (dev/prod)
# This task is automatically run as a dependency of aws:deploy:* tasks
[tasks."aws:guard"]
description = "Guard against deploying to protected environments locally"
hide = true
run = """
# Protected environment names - only CI/CD can deploy to these
PROTECTED_ENVS="dev prod"

for protected in $PROTECTED_ENVS; do
if [ "$ENV" = "$protected" ]; then
# Check for common CI environment variables
# Most CI systems set at least one of these
if [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ] || [ -n "$GITLAB_CI" ] || [ -n "$CIRCLECI" ] || [ -n "$JENKINS_URL" ]; then
echo "CI environment detected - allowing deployment to '$ENV'"
exit 0
fi

echo ""
echo "=========================================="
echo " DEPLOYMENT BLOCKED"
echo "=========================================="
echo ""
echo " Cannot deploy to '$ENV' from a local machine."
echo ""
echo " The '$ENV' environment is protected and can only"
echo " be deployed to through CI/CD pipelines."
echo ""
echo " For local development, please use a personal"
echo " environment name (e.g., your initials):"
echo ""
echo " 1. Delete or edit your .env file"
echo " 2. Run: mise run env:setup"
echo " 3. Enter a personal environment name"
echo ""
echo "=========================================="
echo ""
exit 1
fi
done

echo "Environment '$ENV' is not protected - proceeding with deployment"
"""

[tasks."aws:deploy:local"]
description = "Deploy to AWS (build containers locally)"
depends = ["env:setup"]
depends = ["env:setup", "aws:guard"]
env = { DEPLOY_MODE = "local" }
run = """
echo "=== Deploying Stickerlandia to AWS: $ENV (DEPLOY_MODE=$DEPLOY_MODE) ==="
Expand All @@ -179,7 +245,7 @@ echo "=== Deployment complete! ==="

[tasks."aws:deploy:release"]
description = "Deploy to AWS using prebuilt GHCR images"
depends = ["env:setup"]
depends = ["env:setup", "aws:guard"]
env = { DEPLOY_MODE = "release" }
run = """
echo "=== Deploying Stickerlandia to AWS: $ENV (DEPLOY_MODE=$DEPLOY_MODE) ==="
Expand Down
8 changes: 8 additions & 0 deletions shared/dns/aws/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.js
!jest.config.js
*.d.ts
node_modules

# CDK asset staging directory
.cdk.staging
cdk.out
6 changes: 6 additions & 0 deletions shared/dns/aws/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.ts
!*.d.ts

# CDK asset staging directory
.cdk.staging
cdk.out
5 changes: 5 additions & 0 deletions shared/dns/aws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Shared DNS

This shared infrastructure code contains the required IaC for provisioning DNS resources inside AWS (Route53, certificates etc).

If you are deploying resources to test in your own environment, this is not required. The DNS details are only loaded in CI environments (`dev`, `prod`).
40 changes: 40 additions & 0 deletions shared/dns/aws/bin/shared-dns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2025-Present Datadog, Inc.
*/

import * as cdk from "aws-cdk-lib";
import { execSync } from "child_process";
import { StickerlandiaSharedDnsStack } from "../lib/shared-dns-stack";

// Get AWS account from STS if CDK_DEFAULT_ACCOUNT is not set (e.g., with SSO credentials)
function getAwsAccount(): string | undefined {
if (process.env.CDK_DEFAULT_ACCOUNT) {
return process.env.CDK_DEFAULT_ACCOUNT;
}
try {
return execSync("aws sts get-caller-identity --query Account --output text", {
encoding: "utf-8",
stdio: ["pipe", "pipe", "pipe"],
}).trim();
} catch {
return undefined;
}
}

const app = new cdk.App();
new StickerlandiaSharedDnsStack(
app,
`StickerlandiaSharedDns`,
{
env: {
account: getAwsAccount(),
region: process.env.CDK_DEFAULT_REGION,
},
}
);

cdk.Tags.of(app).add("project", "stickerlandia");
cdk.Tags.of(app).add("service", "shared-dns");
cdk.Tags.of(app).add("team", "advocacy");
98 changes: 98 additions & 0 deletions shared/dns/aws/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"app": "npx ts-node --prefer-ts-exts bin/shared-dns.ts",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"**/*.d.ts",
"**/*.js",
"tsconfig.json",
"package*.json",
"yarn.lock",
"node_modules",
"test"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": [
"aws",
"aws-cn"
],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
"@aws-cdk/aws-redshift:columnId": true,
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
"@aws-cdk/aws-kms:aliasNameRef": true,
"@aws-cdk/aws-kms:applyImportedAliasPermissionsToPrincipal": true,
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
"@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
"@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
"@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
"@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
"@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
"@aws-cdk/core:enableAdditionalMetadataCollection": true,
"@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": false,
"@aws-cdk/aws-s3:setUniqueReplicationRoleName": true,
"@aws-cdk/aws-events:requireEventBusPolicySid": true,
"@aws-cdk/core:aspectPrioritiesMutating": true,
"@aws-cdk/aws-dynamodb:retainTableReplica": true,
"@aws-cdk/aws-stepfunctions:useDistributedMapResultWriterV2": true,
"@aws-cdk/s3-notifications:addS3TrustKeyPolicyForSnsSubscriptions": true,
"@aws-cdk/aws-ec2:requirePrivateSubnetsForEgressOnlyInternetGateway": true,
"@aws-cdk/aws-s3:publicAccessBlockedByDefault": true,
"@aws-cdk/aws-lambda:useCdkManagedLogGroup": true
}
}
14 changes: 14 additions & 0 deletions shared/dns/aws/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2025-Present Datadog, Inc.
*/

module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/test'],
testMatch: ['**/*.test.ts'],
transform: {
'^.+\\.tsx?$': 'ts-jest'
}
};
Loading