To initialize the infrastructure we are using Cloudflare, Doppler and Pulumi.
Before running the script, ensure that Cloudflare is set to Development Mode if it is enabled. If Cloudflare is not configured yet, you can skip this step. If Cloudflare is available but not in Development Mode, the user data script may fail during the certificate creation process.
Before executing pulumi commands via bun, set Doppler access token as an environment variable:
export DOPPLER_TOKEN="" # Doppler access token to the IaaC-related environmentsexport WRITTTE_PULUMI_ORGANIZATION="" # Pulumi organization name
export WRITTTE_PULUMI_STACK="" # Pulumi stack name
export WRITTTE_DOPPLER_PROJECT="" # Doppler project nameAfter setting up the EC2 instance, SSH access will not be available. To gain access, you need to do the following:
- Manually add your IP address to the SSH inbound rules of the
ec2ServerTempAccessSecurityGroupsecurity group. - Create a private key using the generated keys.
For more information, read Wiki
The following environment variables should be defined in the Doppler project related to IaaC.
-
AWS_ACCESS_KEY_ID(string): Access key ID of the aws IAM account. -
AWS_SECRET_ACCESS_KEY(string): Secret access key of the aws IAM account. -
CLOUDFLARE_API_TOKEN(string): API access token to change zone details in cloudflare. -
CLOUDFLARE_DOMAIN_ZONE_ID(string): Zone ID of the domain name in Cloudflare. -
BACKEND_CLOUDFLARE_DOMAIN(string): Domain name of the backend application (e.g.,api.writtte.com) -
BACKEND_CLOUDFLARE_DOMAIN_RECORD_ID(string): Record ID of the backend domain field in DNS. -
FRONTEND_CLOUDFLARE_DOMAIN(string): Domain name of the frontend application (e.g.,app.writtte.com) -
FRONTEND_CLOUDFLARE_DOMAIN_RECORD_ID(string): Record ID of the frontend domain field in DNS. -
PULUMI_DATA_INSTANCE(json): This script is used to create the EC2 instance.
{
"type": "",
"ami": "",
"storage": {
"blockIOPS": 0,
"blockThroughput": 0,
"volumeSize": 0
},
"tags": {
"environment": "",
"project": "",
"code": ""
}
}
| Field | Description |
|---|---|
type |
EC2 instance type |
ami |
Amazon Machine Image ID to use for the instance |
storage.blockIOPS |
The number of I/O operations per second for the storage volume |
storage.blockThroughput |
The throughput in MiB/s for the storage volume |
storage.volumeSize |
Size of the storage volume in GB |
tags.environment |
Environment tag for the instance (e.g., production, staging, development) |
tags.project |
Project name tag for the instance |
tags.code |
Code identifier tag for the instance |
PULUMI_DATA_ENV_SCRIPT(json): This script is used when running the initial Bash script during EC2 Ubuntu server initialization.
{
"code": {
"be": "",
"fe": "",
"langtool": ""
},
"directories": {
"be": "",
"beLogs": "",
"fe": "",
"feLogs": "",
"staticPages": "",
"langtool": ""
},
"domains": {
"be": "",
"fe": ""
},
"ports": {
"be": "",
"fe": "",
"langtool": ""
},
"commands": {
"run": {
"fe": "bun ./index.html --port=%i",
"be": "server -env=local -mode=debug -address=127.0.0.1:%i -ses-enabled"
}
},
"users": {
"primary": {
"name": "",
"password": ""
},
"secondary": {
"name": "",
"password": ""
}
},
"tools": {
"bun": {
"url": "https://github.com/oven-sh/bun/releases/download/bun-v1.3.6/bun-linux-x64.zip",
"archiver": "bun-linux-x64.zip",
"binaryLocationFromArchiver": "bun-linux-x64",
"installDestination": "/usr/local/bun"
},
"go": {
"url": "https://go.dev/dl/go1.25.6.linux-amd64.tar.gz",
"archiver": "go1.25.6.linux-amd64.tar.gz",
"binaryLocationFromArchiver": "go/bin",
"installDestination": "/usr/local/go"
},
"langtool": {
"url": "https://internal1.languagetool.org/snapshots/LanguageTool-20260124-snapshot.zip",
"archiver": "LanguageTool-20260124-snapshot.zip",
"extractedDirectoryName": "LanguageTool-6.8-SNAPSHOT",
"allowOrigin": ""
}
},
"ssl": {
"certBotEmail": ""
}
}| Field | Description |
|---|---|
code.be |
Code for the backend application (e.g., backend-app) |
code.fe |
Code for the frontend application (e.g., frontend-app) |
code.langtool |
Code for the language tool (java) application (e.g., language-tool) |
directories.be |
Directory path where backend code will be deployed |
directories.beLogs |
Directory path for backend logs |
directories.fe |
Directory path where frontend code will be deployed |
directories.feLogs |
Directory path for frontend logs |
directories.staticPages |
Directory path for static web pages |
directories.langtool |
Directory path for language tool installation |
domains.be |
Domain name for the backend service |
domains.fe |
Domain name for the frontend service |
ports.be |
Port number for the backend service |
ports.fe |
Port number for the frontend service |
ports.langtool |
Port number for the language tool service |
commands.run.fe |
Command to run the frontend service (with %i as port placeholder) |
commands.run.be |
Command to run the backend service (with %i as port placeholder) |
users.primary.name |
Username for the primary system user |
users.primary.password |
Password for the primary system user |
users.secondary.name |
Username for the secondary system user |
users.secondary.password |
Password for the secondary system user |
tools.bun.url |
Download URL for the Bun runtime |
tools.bun.archiver |
Filename of the Bun archive |
tools.bun.binaryLocationFromArchiver |
Path to binary within the Bun archive |
tools.bun.installDestination |
Installation directory for Bun |
tools.go.url |
Download URL for Go language |
tools.go.archiver |
Filename of the Go archive |
tools.go.binaryLocationFromArchiver |
Path to binary within the Go archive |
tools.go.installDestination |
Installation directory for Go |
tools.langtool.url |
Download URL for LanguageTool |
tools.langtool.archiver |
Filename of the LanguageTool archive |
tools.langtool.extractedDirectoryName |
Name of directory created after extracting LanguageTool |
tools.langtool.allowOrigin |
CORS allow-origin setting for LanguageTool |
ssl.certBotEmail |
Email address for SSL certificate notifications |