Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions pulumi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
**psm_opts,
)

logdest_opts = resources.get('tb:cloudwatch:LogDestination', {})
logdests = {
logdest_name: tb_pulumi.cloudwatch.LogDestination(
f'{project.name_prefix}-logdest-{logdest_name}',
app_name=logdest_name,
project=project,
**logdest_config,
)
for logdest_name, logdest_config in logdest_opts.items()
}

# Build out some private network space
vpc_opts = resources['tb:network:MultiTierVpc']['vpc']
vpc = tb_pulumi.network.MultiTierVpc(
Expand Down
4 changes: 4 additions & 0 deletions pulumi/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
BOOTSTRAP_DIR = '/opt/stalwart-bootstrap'
BOOTSTRAP_LOG = '/var/log/stalwart-bootstrap.log'
INSTANCE_TAGS = {}

# Map of template files to target files
TEMPLATE_MAP = {
'fluent-bit.yaml.j2': '/etc/fluent-bit/fluent-bit.yaml',
'stalwart.toml.j2': '/opt/stalwart/etc/config.toml',
'thundermail.service.j2': '/usr/lib/systemd/system/thundermail.service',
}
# Map of template variable to EC2 tags
TEMPLATE_VALUE_TAG_MAP = {
'env': 'environment',
'function': 'postboot.stalwart.function',
'https_paths': 'postboot.stalwart.https_paths',
'node_services': 'postboot.stalwart.node_services',
'node_id': 'postboot.stalwart.node_id',
Expand Down
31 changes: 31 additions & 0 deletions pulumi/bootstrap/templates/fluent-bit.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---

service:
flush: 1
grace: 5
daemon: no
dns.mode: UDP
hot_reload: on
log_level: info
storage.path: /fluent-bit/buffers
storage.backlog.flush_on_shutdown: on
storage.keep.rejected: on
storage.rejected.path: /fluent-bit/dlq

pipeline:
inputs:
- name: systemd
tag: cloudwatch.stalwart.{{ function }}
systemd_filter: _SYSTEMD_UNIT=thundermail.service

filters: []

outputs:
- name: forward
match: '*'
{%- if env == 'prod' %}
host: fluentbit.tb.pro
{%- else %}
host: {{ 'fluentbit-' + env + '.tb.pro' }}
{%- endif %}
port: 24224
25 changes: 18 additions & 7 deletions pulumi/config.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ resources:
- stalwart.postboot.keycloak_backend
recovery_window_in_days: 0

tb:cloudwatch:LogDestination:
stalwart:
log_group:
retention_in_days: 7
log_streams:
stalwart-api-logs: api
stalwart-mail-logs: mail
org_name: tb

tb:network:MultiTierVpc:
vpc:
cidr_block: 10.2.0.0/16
Expand Down Expand Up @@ -43,18 +52,18 @@ resources:
additional_routes:
private:
- destination_cidr_block: 10.202.0.0/22 # observability-dev
vpc_peering_connection_id: pcx-0d2027442f0e54ca4
vpc_peering_connection_id: pcx-04d7e54008cd9326c
public: []
endpoint_interfaces:
- secretsmanager

# tb:ec2:SshableInstance: {}
tb:ec2:SshableInstance: {}
# Fill out this template to build an SSH bastion
tb:ec2:SshableInstance:
bastion:
ssh_keypair_name: mailstrom-dev
source_cidrs:
- 10.2.0.0/16 # Internal access
# tb:ec2:SshableInstance:
# bastion:
# ssh_keypair_name: mailstrom-dev
# source_cidrs:
# - 10.2.0.0/16 # Internal access

tb:mailstrom:StalwartCluster:
thundermail:
Expand All @@ -81,6 +90,7 @@ resources:
nodes:
"0": # Must be a unique, stringified integer
disable_api_termination: True
function: 'mail'
ignore_ami_changes: True
ignore_user_data_changes: True
instance_type: t3.micro
Expand All @@ -99,6 +109,7 @@ resources:
storage_capacity: 20
"50":
disable_api_termination: True
function: 'api'
ignore_ami_changes: True
ignore_user_data_changes: True
instance_type: t3.micro
Expand Down
2 changes: 1 addition & 1 deletion pulumi/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Jinja2>=3.1,<4.0
pulumi_cloudflare==6.6.0
tb_pulumi @ git+https://github.com/thunderbird/pulumi.git@v0.0.16
tb_pulumi @ git+https://github.com/thunderbird/pulumi.git@main
toml>=0.10.2,<0.11
6 changes: 6 additions & 0 deletions pulumi/stalwart/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ def node(
depends_on: list = [],
disable_api_stop: bool = False,
disable_api_termination: bool = False,
function: str = 'unknown',
ignore_ami_changes: bool = True,
ignore_user_data_changes: bool = True,
instance_type: str = 't3.micro',
Expand All @@ -694,6 +695,9 @@ def node(
False.
:type disable_api_termination: bool, optional

:param function: This becomes the ``postboot.stalwart.function`` tag on the instance and the ``function``
variable inside of postboot templates.

:param ignore_ami_changes: When True, changes to the instance's AMI will not be applied. This prevents unwanted
rebuilding of cluster nodes, potentially causing downtime. Set to False if the AMI has changed and you
intend on rebuilding the node. Defaults to True.
Expand Down Expand Up @@ -749,6 +753,7 @@ def node(
postboot_tags = {
'postboot.stalwart.aws_region': self.project.aws_region,
'postboot.stalwart.env': self.project.stack,
'postboot.stalwart.function': function,
'postboot.stalwart.https_paths': ','.join(https_paths),
'postboot.stalwart.image': self.stalwart_image,
'postboot.stalwart.node_services': node_services_tag,
Expand Down Expand Up @@ -810,6 +815,7 @@ def user_data(self):
archive_file_base = './bootstrap'
archive_files = [
'bootstrap.py',
'templates/fluent-bit.yaml.j2',
'templates/ports.j2',
'templates/stalwart.toml.j2',
'templates/thundermail.service.j2',
Expand Down
29 changes: 25 additions & 4 deletions pulumi/stalwart_instance_user_data.sh.j2
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,51 @@
set -x
set -e

# Places data get stored
BOOTSTRAP_DIR=/opt/stalwart-bootstrap
BOOTSTRAP_TBZ=/root/bootstrap.tbz
STALWART_DIR=/opt/stalwart

# Install the fluent-bit repo for Amazon Linux
echo '[fluent-bit]
name = Fluent Bit
baseurl = https://packages.fluentbit.io/amazonlinux/2023/
gpgcheck=1
gpgkey=https://packages.fluentbit.io/fluentbit.key
enabled=1' > /etc/yum.repos.d/fluent-bit.repo

# Update system, install dependencies
dnf update -y
dnf install -y bzip2 docker python3.12
dnf install -y bzip2 docker fluent-bit python3.12

mkdir -p $STALWART_DIR/etc
# Delete the default fluent-bit config; we'll template a new one in Phase 2
rm -f /etc/fluent-bit/fluent-bit.conf

# Make sure fluent-bit uses the right config file
sed -i 's/fluent-bit.conf/fluent-bit.yaml/' /usr/lib/systemd/system/fluent-bit.service

# Set up Stalwart config directory and virtual environment
mkdir -p $STALWART_DIR/etc
python3.12 -m ensurepip
pip3.12 install virtualenv
/usr/local/bin/virtualenv -p python3.12 $BOOTSTRAP_DIR

# Make sure Docker always runs
systemctl start docker
systemctl enable docker

# Install Bootstrap Phase 2
echo '{{ bootstrap_tbz_base64 }}' | base64 -d > $BOOTSTRAP_TBZ
tar -xvf $BOOTSTRAP_TBZ -C $BOOTSTRAP_DIR

# Run Bootstrap Phase 2
source $BOOTSTRAP_DIR/bin/activate
pip install -r $BOOTSTRAP_DIR/requirements.txt
python $BOOTSTRAP_DIR/bootstrap.py

# Ensure all our services are online with current configs
systemctl daemon-reload
systemctl enable fluent-bit
systemctl restart fluent-bit
systemctl enable thundermail
systemctl start thundermail

systemctl restart thundermail
Loading