Skip to content

Commit

Permalink
Expose SingleNodeRestateDeployment proxy read timeout (#35)
Browse files Browse the repository at this point in the history
* Expose SingleNodeRestateDeployment proxy read timeout

* Apply config changes on every restart
  • Loading branch information
pcholakov authored Aug 9, 2024
1 parent a3323e8 commit 7837d62
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 101 deletions.
117 changes: 74 additions & 43 deletions lib/restate-constructs/single-node-restate-deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ export interface SingleNodeRestateProps {
* Removal policy for long-lived resources (storage, logs). Default: `cdk.RemovalPolicy.DESTROY`.
*/
removalPolicy?: cdk.RemovalPolicy;

/**
* The read timeout for proxyied ingress requests. Default: 3600 seconds.
*/
ingressProxyReadTimeout?: cdk.Duration;

/**
* Completely override the default nginx configuration for the ingress proxy. Note that other
* ingress proxy configuration options will effectively be ignored if this is set.
*/
ingressNginxConfigOverride?: string;
}

/**
Expand Down Expand Up @@ -106,9 +117,11 @@ export class SingleNodeRestateDeployment extends Construct implements IRestateEn
const restateImage = props.restateImage ?? RESTATE_IMAGE_DEFAULT;
const restateTag = props.restateTag ?? RESTATE_DOCKER_DEFAULT_TAG;
const adotTag = props.adotTag ?? ADOT_DOCKER_DEFAULT_TAG;
const restateInitCommands = ec2.UserData.forLinux();
restateInitCommands.addCommands(
"yum update -y",

const ingressNginxConfig = this.ingressNginxConfig(props);

const initScript = ec2.UserData.forLinux();
initScript.addCommands(
"yum install -y docker nginx",

"systemctl enable docker.service",
Expand All @@ -133,11 +146,19 @@ export class SingleNodeRestateDeployment extends Construct implements IRestateEn
" -subj '/C=DE/ST=Berlin/L=Berlin/O=restate.dev/OU=demo/CN=restate.example.com'",
" -newkey rsa:2048 -keyout /etc/pki/private/restate-selfsigned.key -out /etc/pki/private/restate-selfsigned.crt",
].join(""),
["cat << EOF > /etc/nginx/conf.d/restate-ingress.conf", NGINX_REVERSE_PROXY_CONFIG, "EOF"].join("\n"),

["cat << EOF > /etc/nginx/conf.d/restate-ingress.conf", ingressNginxConfig, "EOF"].join("\n"),
"systemctl enable nginx",
"systemctl start nginx",
"systemctl reload nginx", // ensure that we reload config on subsequent reboots in case nginx was already running
);

const cloudConfig = ec2.UserData.custom([`cloud_final_modules:`, `- [scripts-user, always]`].join("\n"));

const userData = new ec2.MultipartUserData();
userData.addUserDataPart(cloudConfig, "text/cloud-config");
userData.addUserDataPart(initScript, "text/x-shellscript");

const restateInstance = new ec2.Instance(this, "Host", {
vpc: this.vpc,
vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC },
Expand All @@ -146,7 +167,7 @@ export class SingleNodeRestateDeployment extends Construct implements IRestateEn
cpuType: ec2.AmazonLinuxCpuType.ARM_64,
}),
role: this.instanceRole,
userData: restateInitCommands,
userData,
});
this.instance = restateInstance;

Expand Down Expand Up @@ -179,42 +200,52 @@ export class SingleNodeRestateDeployment extends Construct implements IRestateEn
}`;
this.adminUrl = `https://${restateInstance.instancePublicDnsName}:${PUBLIC_ADMIN_PORT}`;
}
}

const NGINX_REVERSE_PROXY_CONFIG = [
"server {",
" listen 443 ssl http2;",
" listen [::]:443 ssl http2;",
" server_name _;",
" root /usr/share/nginx/html;",
"",
' ssl_certificate "/etc/pki/private/restate-selfsigned.crt";',
' ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";',
" ssl_session_cache shared:SSL:1m;",
" ssl_session_timeout 10m;",
" ssl_ciphers PROFILE=SYSTEM;",
" ssl_prefer_server_ciphers on;",
"",
" location / {",
` proxy_pass http://localhost:${RESTATE_INGRESS_PORT};`,
" }",
"}",
"",
"server {",
" listen 9073 ssl http2;",
" listen [::]:9073 ssl http2;",
" server_name _;",
" root /usr/share/nginx/html;",
"",
' ssl_certificate "/etc/pki/private/restate-selfsigned.crt";',
' ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";',
" ssl_session_cache shared:SSL:1m;",
" ssl_session_timeout 10m;",
" ssl_ciphers PROFILE=SYSTEM;",
" ssl_prefer_server_ciphers on;",
"",
" location / {",
` proxy_pass http://localhost:${RESTATE_ADMIN_PORT};`,
" }",
"}",
].join("\n");
/**
* @param props construct properties
* @returns nginx configuration to use for ingress reverse proxy, formatted as a multi-line string
*/
protected ingressNginxConfig(props: SingleNodeRestateProps) {
return (
props.ingressNginxConfigOverride ??
[
"server {",
" listen 443 ssl http2;",
" listen [::]:443 ssl http2;",
" server_name _;",
" root /usr/share/nginx/html;",
"",
' ssl_certificate "/etc/pki/private/restate-selfsigned.crt";',
' ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";',
" ssl_session_cache shared:SSL:1m;",
" ssl_session_timeout 10m;",
" ssl_ciphers PROFILE=SYSTEM;",
" ssl_prefer_server_ciphers on;",
"",
" location / {",
` proxy_pass http://localhost:${RESTATE_INGRESS_PORT};`,
` proxy_read_timeout ${props.ingressProxyReadTimeout?.toSeconds() ?? 3600};`,
" }",
"}",
"",
"server {",
" listen 9073 ssl http2;",
" listen [::]:9073 ssl http2;",
" server_name _;",
" root /usr/share/nginx/html;",
"",
' ssl_certificate "/etc/pki/private/restate-selfsigned.crt";',
' ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";',
" ssl_session_cache shared:SSL:1m;",
" ssl_session_timeout 10m;",
" ssl_ciphers PROFILE=SYSTEM;",
" ssl_prefer_server_ciphers on;",
"",
" location / {",
` proxy_pass http://localhost:${RESTATE_ADMIN_PORT};`,
" }",
"}",
].join("\n")
);
}
}
146 changes: 88 additions & 58 deletions test/__snapshots__/restate-constructs.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -113,82 +113,112 @@ exports[`Restate constructs Create a self-hosted Restate environment deployed on
'Fn::Base64':
'Fn::Join':
- ''
- - >-
#!/bin/bash
- - >+
Content-Type: multipart/mixed;
boundary="+AWS+CDK+User+Data+Separator=="
yum update -y
MIME-Version: 1.0
yum install -y docker nginx
systemctl enable docker.service
--+AWS+CDK+User+Data+Separator==
systemctl start docker.service
Content-Type: text/cloud-config
docker run --name adot --restart unless-stopped --detach -p
4317:4317 -p 55680:55680 -p 8889:8888
public.ecr.aws/aws-observability/aws-otel-collector:latest
Content-Transfer-Encoding: base64
docker run --name restate --restart unless-stopped --detach
--volume /var/restate:/target --network=host -e
RESTATE_OBSERVABILITY__LOG__FORMAT=Json -e
RUST_LOG=info,restate_worker::partition=warn -e
RESTATE_OBSERVABILITY__TRACING__ENDPOINT=http://localhost:4317
--log-driver=awslogs --log-opt awslogs-group=
- Ref: RestateLogsFD86ECAE
- >2-
docker.io/restatedev/restate:latest
mkdir -p /etc/pki/private
- 'Fn::Base64': |-
cloud_final_modules:
- [scripts-user, always]
- |+
openssl req -new -x509 -nodes -sha256 -days 365 -extensions
v3_ca -subj
'/C=DE/ST=Berlin/L=Berlin/O=restate.dev/OU=demo/CN=restate.example.com'
-newkey rsa:2048 -keyout /etc/pki/private/restate-selfsigned.key
-out /etc/pki/private/restate-selfsigned.crt
--+AWS+CDK+User+Data+Separator==
Content-Type: text/x-shellscript
Content-Transfer-Encoding: base64
cat << EOF > /etc/nginx/conf.d/restate-ingress.conf
- 'Fn::Base64':
'Fn::Join':
- ''
- - >-
#!/bin/bash
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;
root /usr/share/nginx/html;
yum install -y docker nginx
ssl_certificate "/etc/pki/private/restate-selfsigned.crt";
ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
systemctl enable docker.service
location / {
proxy_pass http://localhost:8080;
}
}
systemctl start docker.service
docker run --name adot --restart unless-stopped --detach
-p 4317:4317 -p 55680:55680 -p 8889:8888
public.ecr.aws/aws-observability/aws-otel-collector:latest
server {
listen 9073 ssl http2;
listen [::]:9073 ssl http2;
server_name _;
root /usr/share/nginx/html;
docker run --name restate --restart unless-stopped
--detach --volume /var/restate:/target --network=host -e
RESTATE_OBSERVABILITY__LOG__FORMAT=Json -e
RUST_LOG=info,restate_worker::partition=warn -e
RESTATE_OBSERVABILITY__TRACING__ENDPOINT=http://localhost:4317
--log-driver=awslogs --log-opt awslogs-group=
- Ref: RestateLogsFD86ECAE
- >2-
docker.io/restatedev/restate:latest
mkdir -p /etc/pki/private
ssl_certificate "/etc/pki/private/restate-selfsigned.crt";
ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
openssl req -new -x509 -nodes -sha256 -days 365
-extensions v3_ca -subj
'/C=DE/ST=Berlin/L=Berlin/O=restate.dev/OU=demo/CN=restate.example.com'
-newkey rsa:2048 -keyout
/etc/pki/private/restate-selfsigned.key -out
/etc/pki/private/restate-selfsigned.crt
location / {
proxy_pass http://localhost:9070;
}
}
cat << EOF > /etc/nginx/conf.d/restate-ingress.conf
EOF
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _;
root /usr/share/nginx/html;
systemctl enable nginx
ssl_certificate "/etc/pki/private/restate-selfsigned.crt";
ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
systemctl start nginx
location / {
proxy_pass http://localhost:8080;
proxy_read_timeout 3600;
}
}
server {
listen 9073 ssl http2;
listen [::]:9073 ssl http2;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/private/restate-selfsigned.crt";
ssl_certificate_key "/etc/pki/private/restate-selfsigned.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:9070;
}
}
EOF
systemctl enable nginx
systemctl start nginx
systemctl reload nginx
- |
--+AWS+CDK+User+Data+Separator==--
DependsOn:
- RestateInstanceRoleDefaultPolicyD1D39538
- RestateInstanceRoleACC59A6F
Expand Down

0 comments on commit 7837d62

Please sign in to comment.