Skip to content

Commit f14c39b

Browse files
committed
Add cdk deployment
1 parent d6e17ba commit f14c39b

14 files changed

+279
-0
lines changed

my-webapp-cdk/.gitignore

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*.swp
2+
package-lock.json
3+
__pycache__
4+
.pytest_cache
5+
.venv
6+
*.egg-info
7+
build
8+
9+
# CDK asset staging directory
10+
.cdk.staging
11+
cdk.out

my-webapp-cdk/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
2+
# Welcome to your CDK Python project!
3+
4+
This is a blank project for CDK development with Python.
5+
6+
The `cdk.json` file tells the CDK Toolkit how to execute your app.
7+
8+
This project is set up like a standard Python project. The initialization
9+
process also creates a virtualenv within this project, stored under the `.venv`
10+
directory. To create the virtualenv it assumes that there is a `python3`
11+
(or `python` for Windows) executable in your path with access to the `venv`
12+
package. If for any reason the automatic creation of the virtualenv fails,
13+
you can create the virtualenv manually.
14+
15+
To manually create a virtualenv on MacOS and Linux:
16+
17+
```
18+
$ python3 -m venv .venv
19+
```
20+
21+
After the init process completes and the virtualenv is created, you can use the following
22+
step to activate your virtualenv.
23+
24+
```
25+
$ source .venv/bin/activate
26+
```
27+
28+
If you are a Windows platform, you would activate the virtualenv like this:
29+
30+
```
31+
% .venv\Scripts\activate.bat
32+
```
33+
34+
Once the virtualenv is activated, you can install the required dependencies.
35+
36+
```
37+
$ pip install -r requirements.txt
38+
```
39+
40+
At this point you can now synthesize the CloudFormation template for this code.
41+
42+
```
43+
$ cdk synth
44+
```
45+
46+
To add additional dependencies, for example other CDK libraries, just add
47+
them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48+
command.
49+
50+
## Useful commands
51+
52+
* `cdk ls` list all stacks in the app
53+
* `cdk synth` emits the synthesized CloudFormation template
54+
* `cdk deploy` deploy this stack to your default AWS account/region
55+
* `cdk diff` compare deployed stack with current state
56+
* `cdk docs` open CDK documentation
57+
58+
Enjoy!

my-webapp-cdk/app.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import aws_cdk as cdk
4+
from my_webapp_cdk.my_webapp_cdk_stack import MyWebappCdkStack
5+
6+
app = cdk.App()
7+
MyWebappCdkStack(app, "MyWebappCdkStack")
8+
app.synth()

my-webapp-cdk/cdk.json

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

my-webapp-cdk/my_webapp_cdk/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from aws_cdk import (
2+
Stack,
3+
aws_s3 as s3,
4+
aws_iam as iam,
5+
aws_s3_deployment as s3deploy,
6+
aws_cloudfront as cloudfront,
7+
aws_cloudfront_origins as origins,
8+
RemovalPolicy,
9+
10+
CfnOutput
11+
)
12+
from constructs import Construct
13+
14+
class MyWebappCdkStack(Stack):
15+
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
16+
super().__init__(scope, construct_id, **kwargs)
17+
18+
# Create an S3 bucket
19+
website_bucket = s3.Bucket(
20+
self, "WebsiteBucket",
21+
website_index_document="index.html",
22+
website_error_document="index.html",
23+
public_read_access=True,
24+
block_public_access=s3.BlockPublicAccess(
25+
block_public_acls=False,
26+
block_public_policy=False,
27+
ignore_public_acls=False,
28+
restrict_public_buckets=False
29+
),
30+
removal_policy=RemovalPolicy.DESTROY,
31+
auto_delete_objects=True
32+
)
33+
34+
# Then grant public read access to the bucket
35+
website_bucket.grant_public_access('GET')
36+
37+
# Allow public access through bucket policy
38+
website_bucket.add_to_resource_policy(
39+
iam.PolicyStatement(
40+
actions=['s3:GetObject'],
41+
resources=[website_bucket.arn_for_objects('*')],
42+
principals=[iam.AnyPrincipal()]
43+
)
44+
)
45+
46+
# Deploy site contents to S3 bucket
47+
deployment = s3deploy.BucketDeployment(
48+
self, "DeployWebsite",
49+
sources=[s3deploy.Source.asset("./build")],
50+
destination_bucket=website_bucket,
51+
retain_on_delete=False,
52+
)
53+
54+
# Create CloudFront distribution
55+
distribution = cloudfront.Distribution(
56+
self, "Distribution",
57+
default_behavior=cloudfront.BehaviorOptions(
58+
origin=origins.S3Origin(website_bucket),
59+
viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
60+
),
61+
default_root_object="index.html",
62+
error_responses=[
63+
cloudfront.ErrorResponse(
64+
http_status=403,
65+
response_http_status=200,
66+
response_page_path="/index.html",
67+
),
68+
cloudfront.ErrorResponse(
69+
http_status=404,
70+
response_http_status=200,
71+
response_page_path="/index.html",
72+
),
73+
]
74+
)
75+
76+
# Output the website URL
77+
CfnOutput(
78+
self, "WebsiteURL",
79+
value=distribution.distribution_domain_name,
80+
description="Website URL"
81+
)

my-webapp-cdk/requirements-dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==6.2.5

my-webapp-cdk/requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
aws-cdk-lib==2.178.1
2+
constructs>=10.0.0,<11.0.0

my-webapp-cdk/source.bat

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@echo off
2+
3+
rem The sole purpose of this script is to make the command
4+
rem
5+
rem source .venv/bin/activate
6+
rem
7+
rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows.
8+
rem On Windows, this command just runs this batch file (the argument is ignored).
9+
rem
10+
rem Now we don't need to document a Windows command for activating a virtualenv.
11+
12+
echo Executing .venv\Scripts\activate.bat for you
13+
.venv\Scripts\activate.bat

my-webapp-cdk/tests/__init__.py

Whitespace-only changes.

my-webapp-cdk/tests/unit/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import aws_cdk as core
2+
import aws_cdk.assertions as assertions
3+
4+
from my_webapp_cdk.my_webapp_cdk_stack import MyWebappCdkStack
5+
6+
# example tests. To run these tests, uncomment this file along with the example
7+
# resource in my_webapp_cdk/my_webapp_cdk_stack.py
8+
def test_sqs_queue_created():
9+
app = core.App()
10+
stack = MyWebappCdkStack(app, "my-webapp-cdk")
11+
template = assertions.Template.from_stack(stack)
12+
13+
# template.has_resource_properties("AWS::SQS::Queue", {
14+
# "VisibilityTimeout": 300
15+
# })

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"start": "vite",
77
"build": "tsc && vite build",
88
"preview": "npm run build && vite preview",
9+
"deploy": "npm run build",
910
"test": "vitest",
1011
"test:ui": "vitest --ui",
1112
"test:coverage": "vitest run --coverage",

vite.config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export default defineConfig({
1313
},
1414
},
1515
plugins: [react()],
16+
build: {
17+
outDir: 'my-webapp-cdk/build',
18+
emptyOutDir: true,
19+
},
1620
test: {
1721
globals: true,
1822
environment: "jsdom",

0 commit comments

Comments
 (0)