Skip to content

Commit 3a675fa

Browse files
Added cdk stack & github action
1 parent 1979065 commit 3a675fa

File tree

10 files changed

+2680
-1
lines changed

10 files changed

+2680
-1
lines changed

.github/workflows/cdk-deploy.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Deploy infrastructure
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
ref:
6+
description: 'Branch, tag or commit SHA to deploy'
7+
required: false
8+
default: 'master'
9+
type: string
10+
11+
permissions:
12+
id-token: write
13+
contents: read
14+
15+
jobs:
16+
deploy:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
with:
22+
ref: ${{ github.event.inputs.ref }}
23+
24+
- name: Configure AWS Credentials
25+
uses: aws-actions/configure-aws-credentials@v4
26+
with:
27+
aws-region: eu-central-1
28+
role-to-assume: ${{ secrets.AWS_OIDC_ROLE }}
29+
30+
- name: Setup Node.js
31+
uses: actions/setup-node@v4
32+
with:
33+
node-version: '22'
34+
cache: 'npm'
35+
cache-dependency-path: 'cdk/package-lock.json'
36+
37+
- name: Install CDK dependencies
38+
working-directory: ./cdk
39+
run: npm ci
40+
41+
- name: Install AWS CDK CLI
42+
run: npm install -g aws-cdk
43+
44+
- name: CDK Deploy
45+
working-directory: ./cdk
46+
run: cdk deploy --require-approval never

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
cake-redux.iml
33
target/
44
.DS_Store
5-
.config.toml
5+
.config.toml
6+
node_modules/

cdk/bin/stacks.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
import * as cdk from 'aws-cdk-lib';
3+
import {CakeReduxStack } from '../lib/cakeredux-stack.js';
4+
5+
const app = new cdk.App();
6+
new CakeReduxStack(app, 'CakeReduxStack', {
7+
env: { account: '553637109631', region: 'eu-central-1' },
8+
});
9+
10+

cdk/cdk.context.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"acknowledged-issue-numbers": [
3+
34892
4+
],
5+
"vpc-provider:account=553637109631:filter.isDefault=true:region=eu-central-1:returnAsymmetricSubnets=true": {
6+
"vpcId": "vpc-d55e68bc",
7+
"vpcCidrBlock": "172.31.0.0/16",
8+
"ownerAccountId": "553637109631",
9+
"availabilityZones": [],
10+
"subnetGroups": [
11+
{
12+
"name": "Public",
13+
"type": "Public",
14+
"subnets": [
15+
{
16+
"subnetId": "subnet-0347ca5488bd97167",
17+
"cidr": "172.31.48.0/20",
18+
"availabilityZone": "eu-central-1a",
19+
"routeTableId": "rtb-f0626d99"
20+
},
21+
{
22+
"subnetId": "subnet-19746c70",
23+
"cidr": "172.31.0.0/20",
24+
"availabilityZone": "eu-central-1a",
25+
"routeTableId": "rtb-f0626d99"
26+
},
27+
{
28+
"subnetId": "subnet-01210e22afbd300aa",
29+
"cidr": "172.31.64.0/20",
30+
"availabilityZone": "eu-central-1b",
31+
"routeTableId": "rtb-f0626d99"
32+
},
33+
{
34+
"subnetId": "subnet-35c1f74e",
35+
"cidr": "172.31.16.0/20",
36+
"availabilityZone": "eu-central-1b",
37+
"routeTableId": "rtb-f0626d99"
38+
},
39+
{
40+
"subnetId": "subnet-2f3d0c65",
41+
"cidr": "172.31.32.0/20",
42+
"availabilityZone": "eu-central-1c",
43+
"routeTableId": "rtb-f0626d99"
44+
},
45+
{
46+
"subnetId": "subnet-0f462674c4b62bd57",
47+
"cidr": "172.31.80.0/20",
48+
"availabilityZone": "eu-central-1c",
49+
"routeTableId": "rtb-f0626d99"
50+
}
51+
]
52+
}
53+
]
54+
}
55+
}

cdk/cdk.json

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{
2+
"app": "npx tsx bin/stacks.ts",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"**/*.d.ts",
11+
"**/*.js",
12+
"tsconfig.json",
13+
"package*.json",
14+
"yarn.lock",
15+
"node_modules",
16+
"test"
17+
]
18+
},
19+
"context": {
20+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21+
"@aws-cdk/core:checkSecretUsage": true,
22+
"@aws-cdk/core:target-partitions": [
23+
"aws",
24+
"aws-cn"
25+
],
26+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29+
"@aws-cdk/aws-iam:minimizePolicies": true,
30+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
35+
"@aws-cdk/core:enablePartitionLiterals": true,
36+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
38+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
39+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
40+
"@aws-cdk/aws-route53-patters:useCertificate": true,
41+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
42+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
43+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
44+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
45+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
46+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
47+
"@aws-cdk/aws-redshift:columnId": true,
48+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
49+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
50+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
51+
"@aws-cdk/aws-kms:aliasNameRef": true,
52+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
53+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
54+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
55+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
56+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
57+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
58+
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
59+
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
60+
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
61+
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
62+
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
63+
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
64+
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
65+
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
66+
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
67+
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
68+
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
69+
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
70+
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
71+
"@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
72+
"@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
73+
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
74+
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
75+
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
76+
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
77+
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
78+
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
79+
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
80+
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
81+
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
82+
"@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
83+
"@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
84+
"@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
85+
"@aws-cdk/core:enableAdditionalMetadataCollection": true
86+
}
87+
}

cdk/lib/cakeredux-stack.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import * as cdk from 'aws-cdk-lib';
2+
import * as ecs from 'aws-cdk-lib/aws-ecs';
3+
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
4+
import * as iam from 'aws-cdk-lib/aws-iam';
5+
import { type Construct } from 'constructs';
6+
import { importExistingResources } from './existing-resources';
7+
8+
const port = 8081;
9+
const healthCheckPath = '/';
10+
const priority = 15;
11+
const desiredCount = 2;
12+
const clusterName = 'cakeredux';
13+
14+
export class CakeReduxStack extends cdk.Stack {
15+
constructor(scope: Construct, id: string, properties?: cdk.StackProps) {
16+
super(scope, id, properties);
17+
18+
// Import existing resources
19+
const { vpc, existingListener } = importExistingResources(this);
20+
21+
22+
// Create ECS Cluster
23+
const cluster = new ecs.Cluster(this, 'Cluster', {
24+
vpc,
25+
clusterName
26+
});
27+
// Create the Fargate service first
28+
const taskDefinition = new ecs.FargateTaskDefinition(this, 'TaskDef', {
29+
memoryLimitMiB: 512,
30+
cpu: 256,
31+
});
32+
33+
// Attach the SOPS KMS policy to the task role usin arn
34+
35+
taskDefinition.taskRole.addManagedPolicy(
36+
iam.ManagedPolicy.fromManagedPolicyArn(
37+
this,
38+
'SopsKmsPolicy',
39+
'arn:aws:iam::553637109631:policy/sops-kms-policy'
40+
)
41+
);
42+
43+
taskDefinition.addContainer('app', {
44+
image: ecs.ContainerImage.fromAsset('../', { file: 'Dockerfile' }),
45+
portMappings: [{ containerPort: port }],
46+
logging: new ecs.AwsLogDriver({ streamPrefix: 'app' }),
47+
});
48+
49+
const service = new ecs.FargateService(this, 'Service', {
50+
cluster,
51+
taskDefinition,
52+
desiredCount,
53+
assignPublicIp: true,
54+
circuitBreaker: { rollback: true },
55+
});
56+
57+
// Create a target group and add it to the existing listener
58+
const targetGroup = new elbv2.ApplicationTargetGroup(this, 'TargetGroup', {
59+
vpc,
60+
port,
61+
protocol: elbv2.ApplicationProtocol.HTTP,
62+
targets: [service],
63+
healthCheck: {
64+
path: healthCheckPath,
65+
},
66+
});
67+
68+
existingListener.addTargetGroups('AddTargetGroup', {
69+
targetGroups: [targetGroup],
70+
priority,
71+
conditions: [elbv2.ListenerCondition.hostHeaders(['cakeredux.javazone.no'])],
72+
});
73+
}
74+
}

cdk/lib/existing-resources.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import * as ec2 from 'aws-cdk-lib/aws-ec2';
2+
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
3+
import { Construct } from 'constructs';
4+
export interface ExistingResources {
5+
vpc: ec2.IVpc;
6+
existingListener: elbv2.IApplicationListener;
7+
}
8+
9+
export function importExistingResources(scope: Construct): ExistingResources {
10+
// Import existing VPC
11+
const vpc = ec2.Vpc.fromLookup(scope, 'ImportedVPC', {
12+
isDefault: true, // Assuming you're using the default VPC
13+
});
14+
15+
// Import the existing ALB
16+
const existingAlb =
17+
elbv2.ApplicationLoadBalancer.fromApplicationLoadBalancerAttributes(
18+
scope,
19+
'ExistingALB',
20+
{
21+
loadBalancerArn:
22+
'arn:aws:elasticloadbalancing:eu-central-1:553637109631:loadbalancer/app/Default-ALB/1c9b1a5fd7bded5e',
23+
loadBalancerCanonicalHostedZoneId: 'Z215JYRZR1TBD5',
24+
loadBalancerDnsName:
25+
'Default-ALB-1235825687.eu-central-1.elb.amazonaws.com',
26+
securityGroupId: 'sg-06d60bddabf369fb2',
27+
vpc,
28+
}
29+
);
30+
31+
// Import existing listener
32+
const existingListener =
33+
elbv2.ApplicationListener.fromApplicationListenerAttributes(
34+
scope,
35+
'ExistingListener',
36+
{
37+
listenerArn:
38+
'arn:aws:elasticloadbalancing:eu-central-1:553637109631:listener/app/Default-ALB/1c9b1a5fd7bded5e/b211e068a4b86a7b', // Replace with your listener ARN
39+
securityGroup: existingAlb.connections.securityGroups[0],
40+
}
41+
);
42+
43+
44+
return {
45+
vpc,
46+
existingListener,
47+
};
48+
}

0 commit comments

Comments
 (0)