Skip to content

Commit 7607306

Browse files
committed
add simple wordpress stack
1 parent 8262701 commit 7607306

File tree

13 files changed

+370
-0
lines changed

13 files changed

+370
-0
lines changed

Makefile

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
VENV_BIN = python3 -m venv
2+
VENV_DIR ?= .venv
3+
VENV_ACTIVATE = $(VENV_DIR)/bin/activate
4+
VENV_RUN = . $(VENV_ACTIVATE)
5+
6+
venv: $(VENV_ACTIVATE)
7+
8+
$(VENV_ACTIVATE): setup.py setup.cfg pyproject.toml
9+
test -d .venv || $(VENV_BIN) .venv
10+
$(VENV_RUN); pip install --upgrade pip setuptools wheel
11+
$(VENV_RUN); pip install -e .[dev,deploy]
12+
touch $(VENV_DIR)/bin/activate
13+
14+
clean:
15+
rm -rf .venv
16+
rm -rf build/
17+
rm -rf .eggs/
18+
rm -rf *.egg-info/
19+
rm -rf node_modules
20+
rm -rf deployments/cdk/cdk.out
21+
22+
install: venv
23+
npm install; \
24+
ln -sfn `pwd`/node_modules/aws-cdk/bin/cdk $(VENV_DIR)/bin/; \
25+
ln -sfn `pwd`/node_modules/aws-cdk-local/bin/cdklocal $(VENV_DIR)/bin/
26+
27+
deploy-local:
28+
$(VENV_RUN); \
29+
cd deployments/cdk; \
30+
cdklocal bootstrap || true; \
31+
cdklocal deploy --all --require-approval never
32+
33+
destroy-local:
34+
$(VENV_RUN); \
35+
cd deployments/cdk; \
36+
cdklocal destroy --all
37+
38+
format:
39+
$(VENV_ACTIVATE); python -m isort .; python -m black .
40+
41+
.PHONY: clean format install deploy

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
wordpress-ecs-rds-cdk
2+
===============================
3+
4+
Wordpress deployed using ECS and RDS
5+
6+
7+
## Quickstart
8+
9+
to install python requirements and developer tools (ckdlocal, awslocal) into a venv run:
10+
11+
make install
12+
13+
then, to deploy the cdk app, first start localstack and run
14+
15+
make deploy-local
16+
17+
## Tinker
18+
19+
After running `make install`, when you activate the virtual environment with
20+
21+
source .venv/bin/activate
22+
23+
you get the *local commands:
24+
25+
cdklocal
26+
awslocal
27+
28+
You can for example get the name of the bucket that was created and whose name was added as an SSM parameter:
29+
30+
awslocal ssm get-parameter --name /artifacts/bucket
31+
32+
Or list the created lambdas:
33+
34+
awslocal lambda list-functions

deployments/cdk/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cdk.out/

deployments/cdk/app.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import aws_cdk as cdk
2+
import env
3+
from wordpress import WordpressStack
4+
5+
6+
def main():
7+
app = cdk.App()
8+
9+
WordpressStack(app, "WordpressStack", env=env.ENV_LOCAL)
10+
11+
app.synth()
12+
13+
14+
if __name__ == "__main__":
15+
main()

deployments/cdk/cdk.context.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"availability-zones:account=000000000000:region=us-east-1": [
3+
"us-east-1a",
4+
"us-east-1b",
5+
"us-east-1c",
6+
"us-east-1d",
7+
"us-east-1e",
8+
"us-east-1f"
9+
]
10+
}

deployments/cdk/cdk.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"**/__init__.py",
12+
"python/__pycache__",
13+
"tests"
14+
]
15+
},
16+
"context": {
17+
"@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true,
18+
"@aws-cdk/core:stackRelativeExports": true,
19+
"@aws-cdk/aws-rds:lowercaseDbIdentifier": true,
20+
"@aws-cdk/aws-lambda:recognizeVersionProps": true,
21+
"@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": true,
22+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
23+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
24+
"@aws-cdk/core:target-partitions": [
25+
"aws",
26+
"aws-cn"
27+
]
28+
}
29+
}

deployments/cdk/env.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import aws_cdk as cdk
2+
3+
ENV_PRODUCTION = cdk.Environment(account="886468871268", region="eu-central-1")
4+
ENV_STAGING = cdk.Environment(account="583952393159", region="eu-central-1")
5+
ENV_SHARED = cdk.Environment(account="385386232812", region="eu-central-1")
6+
ENV_SANDBOX = cdk.Environment(account="000000000000", region="us-east-1")
7+
ENV_LOCAL = cdk.Environment(account="000000000000", region="us-east-1")

deployments/cdk/wordpress.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import aws_cdk as cdk
2+
import constructs
3+
from aws_cdk import aws_ec2 as ec2
4+
from aws_cdk import aws_ecs as ecs
5+
from aws_cdk import aws_ecs_patterns as ecs_patterns
6+
from aws_cdk import aws_elasticloadbalancingv2 as elbv2
7+
from aws_cdk import aws_rds as rds
8+
9+
# FIXME
10+
db_user = "wordpress"
11+
db_password = "wordpress-password"
12+
db_name = "wordpress"
13+
14+
15+
class WordpressStack(cdk.Stack):
16+
def __init__(self, scope: constructs.Construct, construct_id: str, **kwargs) -> None:
17+
super().__init__(scope, construct_id, **kwargs)
18+
19+
# VPC
20+
self.vpc = ec2.Vpc(
21+
self,
22+
"VPC",
23+
nat_gateways=1,
24+
cidr="10.0.0.0/16",
25+
subnet_configuration=[
26+
ec2.SubnetConfiguration(
27+
name="public", subnet_type=ec2.SubnetType.PUBLIC, cidr_mask=24
28+
),
29+
ec2.SubnetConfiguration(
30+
name="private", subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT, cidr_mask=24
31+
),
32+
],
33+
)
34+
self.cluster_sec_group = ec2.SecurityGroup(
35+
self,
36+
"cluster-sec-group",
37+
security_group_name="cluster-sec-group",
38+
vpc=self.vpc,
39+
allow_all_outbound=True,
40+
)
41+
42+
database = rds.DatabaseInstance(
43+
self,
44+
"WordpressDatabase",
45+
credentials=rds.Credentials.from_password(
46+
username=db_user, password=cdk.SecretValue.plain_text(db_password)
47+
),
48+
database_name=db_name,
49+
engine=rds.DatabaseInstanceEngine.MARIADB,
50+
vpc=self.vpc,
51+
)
52+
53+
# ECS cluster
54+
cluster = ecs.Cluster(self, "ServiceCluster", vpc=self.vpc)
55+
56+
docker_image = ecs.ContainerImage.from_registry("wordpress")
57+
web_service = ecs_patterns.ApplicationLoadBalancedFargateService(
58+
self,
59+
"Wordpress",
60+
cluster=cluster,
61+
target_protocol=elbv2.ApplicationProtocol.HTTP,
62+
protocol=elbv2.ApplicationProtocol.HTTP,
63+
desired_count=1,
64+
# container size
65+
cpu=512,
66+
memory_limit_mib=2048,
67+
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
68+
image=docker_image,
69+
container_port=80,
70+
container_name="webapp",
71+
enable_logging=True,
72+
environment={
73+
"WORDPRESS_DB_HOST": f"{database.db_instance_endpoint_address}:{database.db_instance_endpoint_port}",
74+
"WORDPRESS_DB_USER": db_user,
75+
"WORDPRESS_DB_PASSWORD": db_password,
76+
"WORDPRESS_DB_NAME": db_name,
77+
},
78+
),
79+
)
80+
81+
# TODO: add APIGW and dns + cert

package-lock.json

Lines changed: 88 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"dependencies": {
3+
"aws-cdk": "^2.20.0",
4+
"aws-cdk-local": "^2.15.0"
5+
}
6+
}

0 commit comments

Comments
 (0)