Deploy app, demo, fider and listmonk on OCI
This commit is contained in:
parent
b45e29c278
commit
b3a1eba792
@ -1,4 +1,28 @@
|
|||||||
config:
|
config:
|
||||||
|
infra-happyDomain:fider_github_clientid:
|
||||||
|
secure: AAABABgXd86uOrZsOJejnjqCeNrrI/AVHEALi/VVhoaQdkJrHA9lxu2b/ctKvaWV+XZ+7A==
|
||||||
|
infra-happyDomain:fider_github_secret:
|
||||||
|
secure: AAABALPjvMXkBjZLx4okTac8YdhBllcdnZTyNVLZHjuGAE3pcR5LjRvB8gN4XHMo+vlVXbkE5n5NBFGTz7Ka2abwliDRl2DW
|
||||||
|
infra-happyDomain:fider_jwt_secret:
|
||||||
|
secure: AAABAEGORkViwn3kMhOt2vnbrQKk8d7xcJC2xhUdc1gPang80HQBLpkB64kzvcppt04n0YziIlxfnnmeroFE3bplyja/3KrxCNxfvNuzcgEayZNQAjBte7YzGpM6iHMY
|
||||||
|
infra-happyDomain:happydomain_jwt_secret_key:
|
||||||
|
secure: AAABAO/gNZhqN+mybhh8VsATf3F0Dklc/h88qPMuieQStQQa9rv3R1qMf8lBvjnLCJKEnJnEZQpE7RP0YrX5dx5U2WMG7eKVeE4eNzaIHkxbM2NgGFEVl96dp7/A75dY
|
||||||
|
infra-happyDomain:happydomain_ovh_application_key:
|
||||||
|
secure: AAABAPc3FRKWbvBGbmBb5YtU/CJd7EUsn+++Xi49RFk59Idi1W+l8EqhvqpyUGK2
|
||||||
|
infra-happyDomain:happydomain_ovh_application_secret:
|
||||||
|
secure: AAABAP0O4tvPQzRy0fgcOiElgZzL3ON5Oos/rzr6tFubGblCF7tC8MSp06iAUgpX2J2hN0/047gAZGdW90d0sg==
|
||||||
|
infra-happyDomain:listmonk_api_password:
|
||||||
|
secure: AAABAJc7vc/Rt8azTrsPtk88omCW5koGOkD1/CL45I3lmArb2reA7JkHJb1C4uLvy0VYrDnCXNwNfNy7ompC
|
||||||
|
infra-happyDomain:listmonk_api_username:
|
||||||
|
secure: AAABAAJaF5qECuXAJQEuSQxOfKPb2vTolugGaukVmdkAdQNswPpZnVk=
|
||||||
|
infra-happyDomain:postgres_password:
|
||||||
|
secure: AAABAB/ISsauXbqLKv4BkjAI/9RdUZkIAuTxlDIepxH9qYQD00KvOTbCLVHbPEq17P6P5mZS/75XIvk6UHgb
|
||||||
|
infra-happyDomain:restic_aws_access_key_id:
|
||||||
|
secure: AAABAI89qmSeNjBH6OpF/Ym9eEDEG4Y1JbLC6uRwHMk+IllpgTVxOuBO/NG9JA3RgHgFsw==
|
||||||
|
infra-happyDomain:restic_aws_secret_access_key:
|
||||||
|
secure: AAABAM39hDfydSv0IZVLZf1fSwIJJAD94ve2wsELAJYxdtn2Pe7C5TXplaAAR8qH/56wS23n24BJGQcLgjv+Hy+vwUoIu+zs
|
||||||
|
infra-happyDomain:restic_password:
|
||||||
|
secure: AAABADIJzvbIRfqwrfVyNgjJKVW1uBH8Bhld1dKYJyMXVRPXTcenUPJ/oA9dPDqGlur0J1UdnKpaUPjIU8xf
|
||||||
oci:fingerprint:
|
oci:fingerprint:
|
||||||
secure: AAABAIF01WUHBaDO1ebReUpxMGKFtnuhenKdjdxqMmniQv091K1rG/EPfDwy2RJ2Btm6yl9U/usIM4QHpcl46sZFO9QtV4Pv7rZzdNrK/Q==
|
secure: AAABAIF01WUHBaDO1ebReUpxMGKFtnuhenKdjdxqMmniQv091K1rG/EPfDwy2RJ2Btm6yl9U/usIM4QHpcl46sZFO9QtV4Pv7rZzdNrK/Q==
|
||||||
oci:privateKeyPath: terraform@p0m.fr_2024-07-30T09_19_34.293Z.pem
|
oci:privateKeyPath: terraform@p0m.fr_2024-07-30T09_19_34.293Z.pem
|
||||||
|
382
cloud-init.yaml
Normal file
382
cloud-init.yaml
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
#cloud-config
|
||||||
|
users:
|
||||||
|
- default
|
||||||
|
package_update: true
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- ca-certificates
|
||||||
|
- cron
|
||||||
|
- docker.io
|
||||||
|
- jq
|
||||||
|
- restic
|
||||||
|
- syslog-ng
|
||||||
|
|
||||||
|
write_files:
|
||||||
|
- content: |
|
||||||
|
{
|
||||||
|
#acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
}
|
||||||
|
|
||||||
|
app.happydomain.org {
|
||||||
|
reverse_proxy app-happydomain:8081 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try.happydomain.org {
|
||||||
|
reverse_proxy demo-happydomain:8081 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lists.happydomain.org {
|
||||||
|
tls {
|
||||||
|
issuer acme {
|
||||||
|
disable_http_challenge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@adminroute path /admin /admin/* /api/* /webhooks/*
|
||||||
|
basic_auth @adminroute {
|
||||||
|
nemunaire "$2a$14$F937dQbs6iizd/.p8UZdKuY0O5BjKfkmshKFDH0uA4HJEIrSq2hZa"
|
||||||
|
happyuser "$2a$14$QvpmUl8MBxuqB14mP393yuuQ24/lxibj3zBRzvCdovJQOPeKTzAQC"
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_proxy listmonk:9000 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
feedback.happydomain.org {
|
||||||
|
reverse_proxy feedback:3000 {
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
path: /etc/caddy/Caddyfile
|
||||||
|
- content: |
|
||||||
|
@version:3.30
|
||||||
|
@include "scl.conf"
|
||||||
|
|
||||||
|
# syslog-ng configuration file.
|
||||||
|
#
|
||||||
|
# See syslog-ng(8) and syslog-ng.conf(5) for more information.
|
||||||
|
#
|
||||||
|
# Note: It also sources additional configuration files (*.conf)
|
||||||
|
# located in /etc/syslog-ng/conf.d/.
|
||||||
|
|
||||||
|
#
|
||||||
|
# Options
|
||||||
|
#
|
||||||
|
options {
|
||||||
|
# Create destination directories if missing.
|
||||||
|
create_dirs(yes);
|
||||||
|
|
||||||
|
# The default action of syslog-ng is to log a MARK line to the file every
|
||||||
|
# 20 minutes. That's seems high for most people so turn it down to once an
|
||||||
|
# hour. Set it to zero if you don't want the functionality at all.
|
||||||
|
mark_freq(3600);
|
||||||
|
|
||||||
|
# The default action of syslog-ng is to log a STATS line to the file every
|
||||||
|
# 10 minutes. That's pretty ugly after a while. Change it to every 12 hours
|
||||||
|
# so you get a nice daily update of how many messages syslog-ng missed (0).
|
||||||
|
stats_freq(43200);
|
||||||
|
|
||||||
|
# Time to wait before a died connection is re-established (default is 60).
|
||||||
|
time_reopen(5);
|
||||||
|
|
||||||
|
# Disable DNS usage.
|
||||||
|
# syslog-ng blocks on DNS queries, so enabling DNS may lead to a DoS attack.
|
||||||
|
use_dns(no);
|
||||||
|
dns-cache(no);
|
||||||
|
|
||||||
|
# Default owner, group, and permissions for log files.
|
||||||
|
owner(root);
|
||||||
|
group(adm);
|
||||||
|
perm(0640);
|
||||||
|
|
||||||
|
# Default permissions for created directories.
|
||||||
|
dir_perm(0755);
|
||||||
|
};
|
||||||
|
|
||||||
|
source src { system(); internal(); };
|
||||||
|
|
||||||
|
filter f_auth { facility(auth, authpriv); };
|
||||||
|
filter f_syslog { not facility(authpriv, mail) and not message("^grsec:( From [^:]+:)? exec of.*") and not (program("named") and message("^client ")); };
|
||||||
|
filter f_cron { facility(cron); };
|
||||||
|
filter f_daemon { facility(daemon); };
|
||||||
|
filter f_kern { facility(kern); };
|
||||||
|
filter f_mail { facility(mail, news); };
|
||||||
|
filter f_user { facility(user); };
|
||||||
|
filter f_debug { not facility(auth, authpriv, news, mail); };
|
||||||
|
filter f_messages { level(info..warn) and not facility(auth, authpriv, mail, news) and not message("^grsec:( From [^:]+:)? exec of.*"); };
|
||||||
|
filter f_emergency { level(emerg); };
|
||||||
|
|
||||||
|
filter f_info { level(info); };
|
||||||
|
|
||||||
|
filter f_notice { level(notice); };
|
||||||
|
filter f_warn { level(warn); };
|
||||||
|
filter f_crit { level(crit); };
|
||||||
|
filter f_err { level(err); };
|
||||||
|
|
||||||
|
filter f_audit { message("^audit.*"); };
|
||||||
|
filter f_history { message(".*HISTORY*"); };
|
||||||
|
|
||||||
|
destination authlog { file("/var/log/auth.log"); };
|
||||||
|
destination syslog { file("/var/log/syslog"); };
|
||||||
|
destination kern { file("/var/log/kern.log"); };
|
||||||
|
destination user { file("/var/log/user.log"); };
|
||||||
|
|
||||||
|
destination mailinfo { file("/var/log/mail/mail.info"); };
|
||||||
|
destination mailwarn { file("/var/log/mail/mail.warn"); };
|
||||||
|
destination mailerr { file("/var/log/mail/mail.err"); };
|
||||||
|
|
||||||
|
destination audit { file("/var/log/audit.log"); };
|
||||||
|
destination messages { file("/var/log/messages"); };
|
||||||
|
destination emergency { file("/var/log/emergency"); };
|
||||||
|
|
||||||
|
log { source(src); filter(f_auth); destination(authlog); };
|
||||||
|
|
||||||
|
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };
|
||||||
|
|
||||||
|
#log { source(src); filter(f_messages); destination(messages); };
|
||||||
|
log { source(src); filter(f_emergency); destination(emergency); };
|
||||||
|
|
||||||
|
# Remote loghost
|
||||||
|
destination loghost1 { tcp6("geb.ra.nemunai.re"); };
|
||||||
|
log { source(src); destination(loghost1); };
|
||||||
|
destination loghost2 { tcp6("jizah.masr.nemunai.re"); };
|
||||||
|
log { source(src); destination(loghost2); };
|
||||||
|
|
||||||
|
# Source additional configuration files (.conf extension only)
|
||||||
|
@include "/etc/syslog-ng/conf.d/*.conf"
|
||||||
|
path: /etc/syslog-ng/syslog-ng.conf
|
||||||
|
- content: |
|
||||||
|
# /etc/crontab: configuration file for cron
|
||||||
|
|
||||||
|
# See cron(8) and crontab(5) for details.
|
||||||
|
|
||||||
|
# m h dom mon dow user command
|
||||||
|
23 12 * * * root /root/launch_container_demo.sh && sleep 1 && /root/demo_initialize_data.sh
|
||||||
|
23 0 * * * root /root/launch_container_demo.sh && sleep 1 && /root/demo_initialize_data.sh
|
||||||
|
path: /etc/crontab
|
||||||
|
- content: |
|
||||||
|
#!/bin/sh
|
||||||
|
export AWS_ACCESS_KEY_ID=$(cloud-init query ds.metadata.RESTIC_AWS_ACCESS_KEY_ID)
|
||||||
|
export AWS_SECRET_ACCESS_KEY=$(cloud-init query ds.metadata.RESTIC_AWS_SECRET_ACCESS_KEY)
|
||||||
|
|
||||||
|
export RESTIC_REPOSITORY=$(cloud-init query ds.metadata.RESTIC_REPOSITORY)
|
||||||
|
export RESTIC_PASSWORD=$(cloud-init query ds.metadata.RESTIC_PASSWORD)
|
||||||
|
export RESTIC_COMPRESSION=max
|
||||||
|
|
||||||
|
mkdir -p /var/backups/happydomain
|
||||||
|
|
||||||
|
docker exec -i app-happydomain hadmin /api/backup.json -X POST > /var/backups/happydomain/db.json
|
||||||
|
|
||||||
|
restic backup /var/backups/happydomain
|
||||||
|
path: /etc/cron.daily/backup_happydomain
|
||||||
|
permissions: 0o755
|
||||||
|
- content: |
|
||||||
|
#!/bin/sh
|
||||||
|
export AWS_ACCESS_KEY_ID=$(cloud-init query ds.metadata.RESTIC_AWS_ACCESS_KEY_ID)
|
||||||
|
export AWS_SECRET_ACCESS_KEY=$(cloud-init query ds.metadata.RESTIC_AWS_SECRET_ACCESS_KEY)
|
||||||
|
|
||||||
|
export RESTIC_REPOSITORY=$(cloud-init query ds.metadata.RESTIC_REPOSITORY_POSTGRES)
|
||||||
|
export RESTIC_PASSWORD=$(cloud-init query ds.metadata.RESTIC_PASSWORD)
|
||||||
|
export RESTIC_COMPRESSION=max
|
||||||
|
|
||||||
|
mkdir -p /var/backups/postgres
|
||||||
|
|
||||||
|
DBLIST=$(docker exec -i postgres psql -U postgres -d postgres -q -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('postgres', 'template0', 'template1')")
|
||||||
|
for dbname in $DBLIST; do
|
||||||
|
echo "Dumping database '$dbname'"
|
||||||
|
docker exec -i postgres pg_dump -U postgres --no-owner --no-privileges --dbname="$dbname" > /var/backups/postgres/$dbname.sql || true # Ignore failures
|
||||||
|
done
|
||||||
|
|
||||||
|
restic backup /var/backups/postgres
|
||||||
|
path: /etc/cron.daily/backup_postgres
|
||||||
|
permissions: 0o755
|
||||||
|
- content: |
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
function create_user_and_database() {
|
||||||
|
local database=$1
|
||||||
|
echo " Creating user and database '$database'"
|
||||||
|
PWD_VAR="POSTGRES_PASSWORD_$database"
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||||
|
CREATE USER $database WITH PASSWORD '${!PWD_VAR}';
|
||||||
|
CREATE DATABASE $database;
|
||||||
|
ALTER DATABASE $database OWNER TO $database;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE $database TO $database;
|
||||||
|
EOSQL
|
||||||
|
[ -f "/var/backups/postgres/${database}.sql" ] && \
|
||||||
|
psql -v ON_ERROR_STOP=1 -U "${database}" -d "${database}" < "/var/backups/postgres/${database}.sql"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
|
||||||
|
echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
|
||||||
|
for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do
|
||||||
|
create_user_and_database $db
|
||||||
|
done
|
||||||
|
echo "Multiple databases created"
|
||||||
|
fi
|
||||||
|
path: /etc/pgsql-init/00-create-databases.sh
|
||||||
|
permissions: 0o755
|
||||||
|
- content: |
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
export HAPPYDOMAIN_BIND="0.0.0.0:8081"
|
||||||
|
export HAPPYDOMAIN_CUSTOM_HEAD_HTML="<script async defer data-website-id=\"$(cloud-init query ds.metadata.UMAMI_ID)\" src=\"https://pythagore.p0m.fr/pythagore.js\"></script>"
|
||||||
|
export HAPPYDOMAIN_DEFAULT_NS="9.9.9.9:53"
|
||||||
|
export HAPPYDOMAIN_EXTERNALURL="https://$(cloud-init query ds.metadata.MY_DOMAIN)"
|
||||||
|
export HAPPYDOMAIN_JWT_SECRET_KEY="$(cloud-init query ds.metadata.HAPPYDOMAIN_JWT_SECRET_KEY)"
|
||||||
|
export HAPPYDOMAIN_NEWSLETTER_SERVER_URL="https://$(cloud-init query ds.metadata.LISTMONK_API_USERNAME):$(cloud-init query ds.metadata.LISTMONK_API_PASSWORD)@lists.happydomain.org/"
|
||||||
|
export HAPPYDOMAIN_NEWSLETTER_ID="$(cloud-init query ds.metadata.LISTMONK_NEWSLETTER_ID)"
|
||||||
|
export HAPPYDOMAIN_MAIL_FROM="Fred from happyDomain <contact@happydomain.org>"
|
||||||
|
export HAPPYDOMAIN_MAIL_SMTP_HOST="$(cloud-init query ds.metadata.EMAIL_SMTP_HOST)"
|
||||||
|
export HAPPYDOMAIN_MAIL_SMTP_PORT=$(cloud-init query ds.metadata.EMAIL_SMTP_PORT)
|
||||||
|
export HAPPYDOMAIN_MAIL_SMTP_USERNAME="$(cloud-init query ds.metadata.EMAIL_SMTP_USERNAME)"
|
||||||
|
export HAPPYDOMAIN_MAIL_SMTP_PASSWORD="$(cloud-init query ds.metadata.EMAIL_SMTP_PASSWORD)"
|
||||||
|
export HAPPYDOMAIN_OVH_APPLICATION_KEY="$(cloud-init query ds.metadata.HAPPYDOMAIN_OVH_APPLICATION_KEY)"
|
||||||
|
export HAPPYDOMAIN_OVH_APPLICATION_SECRET="$(cloud-init query ds.metadata.HAPPYDOMAIN_OVH_APPLICATION_SECRET)"
|
||||||
|
export HAPPYDOMAIN_STORAGE_ENGINE="leveldb"
|
||||||
|
|
||||||
|
[ -z "${HAPPYDOMAIN_VERSION}" ] && export HAPPYDOMAIN_VERSION=$(cloud-init query ds.metadata.HAPPYDOMAIN_VERSION)
|
||||||
|
|
||||||
|
docker inspect app-happydomain > /dev/null && {
|
||||||
|
docker pull happydomain/happydomain:${HAPPYDOMAIN_VERSION}
|
||||||
|
docker stop app-happydomain
|
||||||
|
docker rm app-happydomain
|
||||||
|
}
|
||||||
|
|
||||||
|
docker run -d --restart unless-stopped --network local -e HAPPYDOMAIN_BIND -e HAPPYDOMAIN_CUSTOM_HEAD_HTML -e HAPPYDOMAIN_DEFAULT_NS -e HAPPYDOMAIN_EXTERNALURL -e HAPPYDOMAIN_JWT_SECRET_KEY -e HAPPYDOMAIN_NEWSLETTER_SERVER_URL -e HAPPYDOMAIN_NEWSLETTER_ID -e HAPPYDOMAIN_MAIL_FROM -e HAPPYDOMAIN_MAIL_SMTP_HOST -e HAPPYDOMAIN_MAIL_SMTP_PORT -e HAPPYDOMAIN_MAIL_SMTP_USERNAME -e HAPPYDOMAIN_MAIL_SMTP_PASSWORD -e HAPPYDOMAIN_OVH_APPLICATION_KEY -e HAPPYDOMAIN_OVH_APPLICATION_SECRET -e HAPPYDOMAIN_STORAGE_ENGINE -p "8081:8081" --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=app-happydomain --name app-happydomain --pull always happydomain/happydomain:${HAPPYDOMAIN_VERSION}
|
||||||
|
path: /root/launch_container_app.sh
|
||||||
|
permissions: 0o755
|
||||||
|
- content: |
|
||||||
|
#!/bin/sh
|
||||||
|
# pdns
|
||||||
|
docker inspect pdns-demo-happydomain > /dev/null && {
|
||||||
|
docker pull nemunaire/pdns
|
||||||
|
docker stop pdns-demo-happydomain
|
||||||
|
docker rm pdns-demo-happydomain
|
||||||
|
}
|
||||||
|
|
||||||
|
docker run -d --restart unless-stopped --network local -e PDNS_AUTH_API_KEY=changeme --entrypoint /bin/sh --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=pdns-demo-happydomain --name pdns-demo-happydomain --pull always nemunaire/pdns -c "rm /var/lib/powerdns/pdns.sqlite3; sqlite3 /var/lib/powerdns/pdns.sqlite3 < /usr/share/doc/pdns/schema.sqlite3.sql && exec tini -- /usr/sbin/pdns_server-startup"
|
||||||
|
|
||||||
|
# happyDomain demo
|
||||||
|
export HAPPYDOMAIN_BIND="0.0.0.0:8081"
|
||||||
|
export HAPPYDOMAIN_CUSTOM_HEAD_HTML="<script async defer data-website-id=\"$(cloud-init query ds.metadata.TRY_UMAMI_ID)\" src=\"https://pythagore.p0m.fr/pythagore.js\"></script>"
|
||||||
|
export HAPPYDOMAIN_DEFAULT_NS="9.9.9.9:53"
|
||||||
|
export HAPPYDOMAIN_EXTERNALURL="https://$(cloud-init query ds.metadata.TRY_DOMAIN)"
|
||||||
|
export HAPPYDOMAIN_STORAGE_ENGINE="leveldb"
|
||||||
|
|
||||||
|
[ -z "${HAPPYDOMAIN_VERSION}" ] && export HAPPYDOMAIN_VERSION=$(cloud-init query ds.metadata.HAPPYDOMAIN_VERSION)
|
||||||
|
|
||||||
|
docker inspect demo-happydomain > /dev/null && {
|
||||||
|
docker pull happydomain/happydomain:${HAPPYDOMAIN_VERSION}
|
||||||
|
docker stop demo-happydomain
|
||||||
|
docker rm demo-happydomain
|
||||||
|
}
|
||||||
|
|
||||||
|
docker run -d --restart unless-stopped --network local -e HAPPYDOMAIN_BIND -e HAPPYDOMAIN_CUSTOM_HEAD_HTML -e HAPPYDOMAIN_DEFAULT_NS -e HAPPYDOMAIN_EXTERNALURL -e HAPPYDOMAIN_DISABLE_PROVIDERS_EDIT=true -e HAPPYDOMAIN_NO_AUTH=1 -e HAPPYDOMAIN_MSG_HEADER_TEXT="Shared demo instance; data reset at 00:34 and 12:34 UTC" -e HAPPYDOMAIN_MSG_HEADER_COLOR="warning" -e HAPPYDOMAIN_STORAGE_ENGINE --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=demo-happydomain --name demo-happydomain --pull always happydomain/happydomain:${HAPPYDOMAIN_VERSION}
|
||||||
|
path: /root/launch_container_demo.sh
|
||||||
|
permissions: 0o755
|
||||||
|
- content: |
|
||||||
|
#!/bin/sh
|
||||||
|
[ -z "$POSTGRES_PASSWORD_fider" ] && export $(docker inspect postgres -f 'json' | jq -r '.[0].Config.Env[]' | grep ^POSTGRES_PASSWORD_fider)
|
||||||
|
|
||||||
|
docker run -d --restart unless-stopped --network local -e BASE_URL="https://$(cloud-init query ds.metadata.FIDER_DOMAIN)" -e DATABASE_URL="postgres://fider:${POSTGRES_PASSWORD_fider}@postgres:5432/fider?sslmode=disable" -e JWT_SECRET="$(cloud-init query ds.metadata.FIDER_JWT_SECRET)" -e EMAIL_NOREPLY="feedback@happydomain.org" -e EMAIL_SMTP_HOST="$(cloud-init query ds.metadata.EMAIL_SMTP_HOST)" -e EMAIL_SMTP_PORT=$(cloud-init query ds.metadata.EMAIL_SMTP_PORT) -e EMAIL_SMTP_USERNAME="$(cloud-init query ds.metadata.EMAIL_SMTP_USERNAME)" -e EMAIL_SMTP_PASSWORD="$(cloud-init query ds.metadata.EMAIL_SMTP_PASSWORD)" -e EMAIL_SMTP_ENABLE_STARTTLS=true -e OAUTH_GITHUB_CLIENTID="$(cloud-init query ds.metadata.FIDER_GITHUB_CLIENTID)" -e OAUTH_GITHUB_SECRET="$(cloud-init query ds.metadata.FIDER_GITHUB_SECRET)" -p 3000:3000 --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=feedback --name feedback --pull always getfider/fider:stable
|
||||||
|
|
||||||
|
docker run -d --restart unless-stopped --network local -v /etc/listmonk.toml:/listmonk/config.toml:ro -e GENERIC_TIMEZONE="Europe/Paris" -e TZ="Europe/Paris" -p "9000:9000" --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=listmonk --name listmonk --pull always ghcr.io/knadh/listmonk:latest
|
||||||
|
path: /root/launch_container_other.sh
|
||||||
|
permissions: 0o755
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
# Allow traffic in IPv4
|
||||||
|
- sed -i '/-A INPUT -j REJECT/i-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT\n-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT' /etc/iptables/rules.v4
|
||||||
|
- iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
|
||||||
|
- iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
|
||||||
|
|
||||||
|
# Retrieve last backups
|
||||||
|
- export AWS_ACCESS_KEY_ID=$(cloud-init query ds.metadata.RESTIC_AWS_ACCESS_KEY_ID)
|
||||||
|
- export AWS_SECRET_ACCESS_KEY=$(cloud-init query ds.metadata.RESTIC_AWS_SECRET_ACCESS_KEY)
|
||||||
|
- export RESTIC_PASSWORD=$(cloud-init query ds.metadata.RESTIC_PASSWORD)
|
||||||
|
|
||||||
|
- export RESTIC_REPOSITORY=$(cloud-init query ds.metadata.RESTIC_REPOSITORY)
|
||||||
|
- mkdir -p /var/backups/happydomain
|
||||||
|
- restic restore latest --target / --include /var/backups/happydomain
|
||||||
|
|
||||||
|
- export RESTIC_REPOSITORY=$(cloud-init query ds.metadata.RESTIC_REPOSITORY_POSTGRES)
|
||||||
|
- mkdir -p /var/backups/postgres
|
||||||
|
- restic restore latest --target / --include /var/backups/postgres
|
||||||
|
- touch /var/backups/postgres/fider.sql
|
||||||
|
- touch /var/backups/postgres/listmonk.sql
|
||||||
|
|
||||||
|
# Create docker network
|
||||||
|
- docker network create local
|
||||||
|
|
||||||
|
# Generate database password
|
||||||
|
- export POSTGRES_PASSWORD_fider=$(openssl rand -base64 30 | sed 's@/@.@g')
|
||||||
|
- export POSTGRES_PASSWORD_listmonk=$(openssl rand -base64 30)
|
||||||
|
|
||||||
|
# Launch database
|
||||||
|
- |
|
||||||
|
cat > /etc/pgsql-init/70-update-listmonk-settings.sh <<EOF
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "\$POSTGRES_USER" -d listmonk <<-EOSQL
|
||||||
|
UPDATE settings SET value = '"https://$(cloud-init query ds.metadata.LISTMONK_DOMAIN)"' WHERE key = 'app.root_url';
|
||||||
|
UPDATE settings SET value = '"$(cloud-init query ds.metadata.LISTMONK_S3_CLIENT_ID)"' WHERE key = 'upload.s3.aws_access_key_id';
|
||||||
|
UPDATE settings SET value = '"$(cloud-init query ds.metadata.LISTMONK_S3_CLIENT_SECRET)"' WHERE key = 'upload.s3.aws_secret_access_key';
|
||||||
|
UPDATE settings SET value = '"https://$(cloud-init query ds.metadata.LISTMONK_S3_HOST)/"' WHERE key = 'upload.s3.url';
|
||||||
|
UPDATE settings SET value = '"$(cloud-init query ds.metadata.LISTMONK_S3_REGION)"' WHERE key = 'upload.s3.aws_default_region';
|
||||||
|
UPDATE settings SET value = '"$(cloud-init query ds.metadata.LISTMONK_S3_BUCKET)"' WHERE key = 'upload.s3.bucket';
|
||||||
|
UPDATE settings SET value = '[{"host": "$(cloud-init query ds.metadata.EMAIL_SMTP_HOST)", "port": $(cloud-init query ds.metadata.EMAIL_SMTP_PORT), "uuid": "16aee4cf-4e54-401d-a02d-70097e44315e", "enabled": true, "password": $(cloud-init query ds.metadata.EMAIL_SMTP_PASSWORD | jq -R . | sed 's/\$/\\$/'), "tls_type": "STARTTLS", "username": "$(cloud-init query ds.metadata.EMAIL_SMTP_USERNAME)", "max_conns": 10, "idle_timeout": "1m", "wait_timeout": "5s", "auth_protocol": "plain", "email_headers": [], "hello_hostname": "", "max_msg_retries": 4, "tls_skip_verify": false}]' WHERE key = 'smtp';
|
||||||
|
EOSQL
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- chmod +x /etc/pgsql-init/70-update-listmonk-settings.sh
|
||||||
|
- docker run -d --restart unless-stopped --network local --shm-size=512MB -v /var/backups/postgres/:/var/backups/postgres/ -v /etc/pgsql-init/:/docker-entrypoint-initdb.d/ -v /var/lib/postgres/data:/var/lib/postgresql/data -e POSTGRES_PASSWORD=$(cloud-init query ds.metadata.POSTGRES_PASSWORD) -e POSTGRES_MULTIPLE_DATABASES="fider,listmonk" -e POSTGRES_PASSWORD_fider -e POSTGRES_PASSWORD_listmonk --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=postgres --name postgres --pull always --name postgres postgres:alpine
|
||||||
|
|
||||||
|
# Launch web server
|
||||||
|
- docker run -d --restart unless-stopped --network local -v /etc/caddy:/etc/caddy -v /srv/:/srv/ -p 80:80 -p 443:443 --log-driver syslog --log-opt "syslog-address=unixgram:///dev/log" --log-opt syslog-facility=daemon --log-opt tag=caddy --name caddy caddy:latest
|
||||||
|
|
||||||
|
# Launch container
|
||||||
|
- /root/launch_container_app.sh
|
||||||
|
|
||||||
|
# Generate listmonk config
|
||||||
|
- |
|
||||||
|
cat <<EOF > /etc/listmonk.toml
|
||||||
|
[app]
|
||||||
|
address = "0.0.0.0:9000"
|
||||||
|
|
||||||
|
[db]
|
||||||
|
host = "postgres"
|
||||||
|
port = 5432
|
||||||
|
user = "listmonk"
|
||||||
|
password = "${POSTGRES_PASSWORD_listmonk}"
|
||||||
|
database = "listmonk"
|
||||||
|
ssl_mode = "disable"
|
||||||
|
max_open = 25
|
||||||
|
max_idle = 25
|
||||||
|
max_lifetime = "300s"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Launch others containers
|
||||||
|
- /root/launch_container_other.sh
|
||||||
|
|
||||||
|
# Launch demo containers
|
||||||
|
- /root/launch_container_demo.sh
|
||||||
|
|
||||||
|
# Restore happydomain backups
|
||||||
|
- |
|
||||||
|
[ -f /var/backups/happydomain/db.json ] && docker exec -i app-happydomain hadmin /api/backup.json -X PUT -d @- < /var/backups/happydomain/db.json
|
||||||
|
|
||||||
|
# Apply demo data
|
||||||
|
- |
|
||||||
|
[ -x /root/demo_initialize_data.sh ] && /root/demo_initialize_data.sh
|
4
consts.go
Normal file
4
consts.go
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const SHAPE_AMD64 = "VM.Standard.E2.1.Micro"
|
||||||
|
const SSH_AUTHORIZED_KEYS = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILO2HHqD/MDYpPjYVMdvYI9Jn1FoyFp43IkPRzjZGvdL nemunaire@oupaout.ra.nemunai.re"
|
130
demo_initialize_data.sh
Normal file
130
demo_initialize_data.sh
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Configure pdns
|
||||||
|
[ -z "${PDNS_CONTAINER}" ] && PDNS_CONTAINER=pdns-demo-happydomain
|
||||||
|
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil create-zone happydomain.test ns1.happydomain.org
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test @ A 198.51.100.1
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test @ AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:1234
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test @ MX "10 mx1"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test @ MX "10 mx2"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test @ TXT '"v=spf1 +mx -all"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test mail._domainkey TXT '"v=DKIM1;k=rsa;p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2s==;s=email"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test _dmarc TXT '"v=DMARC1;p=none;sp=reject;rua=mailto:postmaster@happydomain.test;ruf=mailto:postmaster@happydomain.test;adkim=s;aspf=s"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test _mta-sts TXT '"v=STSv1; id=20181231172300Z"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test _smtp._tls TXT '"v=TLSRPTv1; rua=mailto:postmaster@happydomain.test"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test _matrix._tcp SRV "10 0 8448 matrix.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus A 203.0.113.35
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:7891
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus SSHFP "1 1 3A92EA036ECFAAFB7262651970E7A8A9C17AADFB"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus SSHFP "1 2 FAF1B7B2BE4AFF034C8DA465ED90B317ADDFA3EBA97914D16BF2D3B75283F3FA"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus SSHFP "4 1 CC1E38492A753DA93FCB8605393B0C6F058E829D"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test augustus SSHFP "4 2 B03BD08AFE6DA44E879E7C15EE4D121DD64F27514866314E79E07C76DDF4A65C"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test mx1 A 198.51.100.12
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test mx1 AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:4567
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test mx2 A 203.0.113.34
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test mx2 AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:7890
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test matrix CNAME augustus.happydomain.test.
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.test www CNAME augustus.happydomain.test.
|
||||||
|
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil create-zone happydomain.invalid ns1.happydomain.org
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid @ A 198.51.100.1
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid @ AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:1234
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid @ MX "10 mx1.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid @ MX "10 mx2.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid @ TXT '"v=spf1 +mx -all"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record happydomain.invalid www CNAME augustus.happydomain.test.
|
||||||
|
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil create-zone example.com ns1.happydomain.org
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com @ A 198.51.100.1
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com @ AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:1234
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com @ MX "10 mx1.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com @ MX "10 mx2.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com @ TXT '"v=spf1 +mx -all"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com www CNAME augustus.happydomain.test.
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com _443._tcp.www TLSA "3 1 2 dc3ada2a3cf089c87f4b1fa147d77b4ee5f2c764e53dc57618f07d86c4204032f34e32746b0ff4881313d4ca0ced656863caea539f62fba427c7a677a32c5831"
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com _xmpp-client._tcp SRV "10 0 5222 augustus.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.com _xmpp-server._tcp SRV "10 0 5269 augustus.happydomain.test."
|
||||||
|
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil create-zone example.net ns1.happydomain.org
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net @ A 198.51.100.1
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net @ AAAA 2001:db8:a3f9:22dc:8301:c4b6:783e:1234
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net @ MX "10 mx1.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net @ MX "10 mx2.happydomain.test."
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net @ TXT '"v=spf1 +mx -all"'
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net www CNAME augustus.happydomain.test.
|
||||||
|
docker exec ${PDNS_CONTAINER} pdnsutil add-record example.net _443._tcp.www CNAME _443._tcp.augustus.happydomain.test.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Configure happyDomain
|
||||||
|
|
||||||
|
[ -z "${HAPPYDOMAIN_CONTAINER}" ] && HAPPYDOMAIN_CONTAINER=demo-happydomain
|
||||||
|
|
||||||
|
USERID="AA"
|
||||||
|
USEREMAIL="_no_auth"
|
||||||
|
|
||||||
|
# Create real user
|
||||||
|
docker exec -i ${HAPPYDOMAIN_CONTAINER} hadmin /api/users -X POST -d @- <<EOF
|
||||||
|
{
|
||||||
|
"id": "${USERID}",
|
||||||
|
"email": "${USEREMAIL}",
|
||||||
|
"created_at": "2024-01-01T12:21:42Z",
|
||||||
|
"last_seen": "2024-01-01T12:21:42Z",
|
||||||
|
"settings": {
|
||||||
|
"language": "en",
|
||||||
|
"fieldhint": 2,
|
||||||
|
"zoneview": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Register user's providers
|
||||||
|
PRVNYC=$(docker exec -i ${HAPPYDOMAIN_CONTAINER} hadmin /api/users/${USEREMAIL}/providers -X POST -d @- <<EOF | jq -r ._id
|
||||||
|
{
|
||||||
|
"Provider": {
|
||||||
|
"apiurl": "http://pdns-demo-happydomain:8081",
|
||||||
|
"apikey": "changeme",
|
||||||
|
"server_id": "localhost"
|
||||||
|
},
|
||||||
|
"_srctype": "PowerdnsAPI",
|
||||||
|
"_comment": "PowerDNS Paris"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Register user's domains
|
||||||
|
|
||||||
|
## happydomain.test
|
||||||
|
docker exec -i ${HAPPYDOMAIN_CONTAINER} hadmin /api/users/${USEREMAIL}/domains -X POST -d @- <<EOF
|
||||||
|
{
|
||||||
|
"id": "hV0iXIDNUyHAMPgEXF_gFg",
|
||||||
|
"id_owner": "${USERID}",
|
||||||
|
"id_provider": "${PRVNYC}",
|
||||||
|
"domain": "happydomain.test.",
|
||||||
|
"group": "other customer",
|
||||||
|
"zone_history": []
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
## example.com
|
||||||
|
docker exec -i ${HAPPYDOMAIN_CONTAINER} hadmin /api/users/${USEREMAIL}/domains -X POST -d @- <<EOF
|
||||||
|
{
|
||||||
|
"id": "hV0iXIDNUyHAMPgEXF_gFh",
|
||||||
|
"id_owner": "${USERID}",
|
||||||
|
"id_provider": "${PRVNYC}",
|
||||||
|
"domain": "example.com.",
|
||||||
|
"group": "customer 1",
|
||||||
|
"zone_history": []
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
docker exec -i ${HAPPYDOMAIN_CONTAINER} hadmin /api/users/${USEREMAIL}/domains -X POST -d @- <<EOF
|
||||||
|
{
|
||||||
|
"id": "hV0iXIDNUyHAMPgEXF_gFi",
|
||||||
|
"id_owner": "${USERID}",
|
||||||
|
"id_provider": "${PRVNYC}",
|
||||||
|
"domain": "example.net.",
|
||||||
|
"group": "customer 1",
|
||||||
|
"zone_history": []
|
||||||
|
}
|
||||||
|
EOF
|
167
host.go
Normal file
167
host.go
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/core"
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/identity"
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/networkloadbalancer"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupHostMain(ctx *pulumi.Context, ocicfg *config.Config, compartment *identity.Compartment, ns pulumi.StringOutput, subnet *core.Subnet, listmonkAuthToken *identity.CustomerSecretKey, smtpcreds *identity.SmtpCredential, pemprvkey io.Reader) error {
|
||||||
|
cfg := config.New(ctx, "")
|
||||||
|
|
||||||
|
// Setup load-balancer
|
||||||
|
nlb, err := networkloadbalancer.NewNetworkLoadBalancer(ctx, "happy-nlb", &networkloadbalancer.NetworkLoadBalancerArgs{
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happy-nlb", ctx.Stack()),
|
||||||
|
SubnetId: subnet.ID(),
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
IsPreserveSourceDestination: pulumi.Bool(false),
|
||||||
|
IsPrivate: pulumi.Bool(false),
|
||||||
|
NlbIpVersion: pulumi.String("IPV4"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Export("nlb-ip", nlb.IpAddresses)
|
||||||
|
|
||||||
|
nlbset4, err := networkloadbalancer.NewBackendSet(ctx, "happydomain-nlbset4", &networkloadbalancer.BackendSetArgs{
|
||||||
|
HealthChecker: &networkloadbalancer.BackendSetHealthCheckerArgs{
|
||||||
|
Protocol: pulumi.String("HTTPS"),
|
||||||
|
Port: pulumi.Int(443),
|
||||||
|
UrlPath: pulumi.String("/api/version"),
|
||||||
|
ReturnCode: pulumi.Int(200),
|
||||||
|
},
|
||||||
|
Name: pulumi.Sprintf("%s-happydomain-nlbset4", ctx.Stack()),
|
||||||
|
NetworkLoadBalancerId: nlb.ID(),
|
||||||
|
Policy: pulumi.String("FIVE_TUPLE"),
|
||||||
|
IpVersion: pulumi.String("IPV4"),
|
||||||
|
IsPreserveSource: pulumi.Bool(true),
|
||||||
|
IsFailOpen: pulumi.Bool(true),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = networkloadbalancer.NewListener(ctx, "happydomain-listener4", &networkloadbalancer.ListenerArgs{
|
||||||
|
DefaultBackendSetName: nlbset4.Name,
|
||||||
|
Name: pulumi.Sprintf("%s-happydomain-nlb-listen4", ctx.Stack()),
|
||||||
|
NetworkLoadBalancerId: nlb.ID(),
|
||||||
|
Port: pulumi.Int(0),
|
||||||
|
Protocol: pulumi.String("TCP"),
|
||||||
|
IpVersion: pulumi.String("IPV4"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get boot image
|
||||||
|
imageId := compartment.CompartmentId.ApplyT(func(id string) string {
|
||||||
|
images, _ := core.GetImages(ctx, &core.GetImagesArgs{
|
||||||
|
CompartmentId: id,
|
||||||
|
OperatingSystem: pulumi.StringRef("Canonical Ubuntu"),
|
||||||
|
OperatingSystemVersion: pulumi.StringRef("22.04 Minimal"),
|
||||||
|
SortBy: pulumi.StringRef("TIMECREATED"),
|
||||||
|
SortOrder: pulumi.StringRef("DESC"),
|
||||||
|
Shape: pulumi.StringRef(SHAPE_AMD64),
|
||||||
|
})
|
||||||
|
return images.Images[0].Id
|
||||||
|
}).(pulumi.StringOutput)
|
||||||
|
|
||||||
|
// Get availability domains
|
||||||
|
availabilityDomainName := compartment.CompartmentId.ApplyT(func(id string) string {
|
||||||
|
availabilityDomains, _ := identity.GetAvailabilityDomains(ctx, &identity.GetAvailabilityDomainsArgs{
|
||||||
|
CompartmentId: id,
|
||||||
|
})
|
||||||
|
return availabilityDomains.AvailabilityDomains[0].Name
|
||||||
|
}).(pulumi.StringOutput)
|
||||||
|
|
||||||
|
// Load cloudinit
|
||||||
|
userData, err := ioutil.ReadFile("cloud-init.yaml")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
storens := ns.ApplyT(func(storageNamespace string) string {
|
||||||
|
return storageNamespace + ".compat.objectstorage." + ocicfg.Require("region") + ".oraclecloud.com"
|
||||||
|
}).(pulumi.StringOutput)
|
||||||
|
|
||||||
|
// Create an OCI instance
|
||||||
|
instance, err := core.NewInstance(ctx, "happydomain-main-1", &core.InstanceArgs{
|
||||||
|
AvailabilityDomain: availabilityDomainName,
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-main", ctx.Stack()),
|
||||||
|
Shape: pulumi.String(SHAPE_AMD64),
|
||||||
|
SourceDetails: &core.InstanceSourceDetailsArgs{
|
||||||
|
SourceId: imageId,
|
||||||
|
SourceType: pulumi.String("image"),
|
||||||
|
},
|
||||||
|
CreateVnicDetails: &core.InstanceCreateVnicDetailsArgs{
|
||||||
|
AssignIpv6ip: pulumi.Bool(true),
|
||||||
|
SubnetId: subnet.ID(),
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-main", ctx.Stack()),
|
||||||
|
},
|
||||||
|
ExtendedMetadata: pulumi.Map{
|
||||||
|
"EMAIL_SMTP_HOST": pulumi.String("smtp.email." + ocicfg.Require("region") + ".oci.oraclecloud.com"),
|
||||||
|
"EMAIL_SMTP_PORT": pulumi.String("587"),
|
||||||
|
"EMAIL_SMTP_USERNAME": smtpcreds.Username,
|
||||||
|
"EMAIL_SMTP_PASSWORD": smtpcreds.Password,
|
||||||
|
"FIDER_DOMAIN": pulumi.String("feedback.happydomain.org"),
|
||||||
|
"FIDER_JWT_SECRET": cfg.RequireSecret("fider_jwt_secret"),
|
||||||
|
"FIDER_GITHUB_CLIENTID": cfg.RequireSecret("fider_github_clientid"),
|
||||||
|
"FIDER_GITHUB_SECRET": cfg.RequireSecret("fider_github_secret"),
|
||||||
|
"UMAMI_ID": pulumi.String("3a9d70d8-c2d4-44e0-9fa1-46d4b2e3fca0"),
|
||||||
|
"HAPPYDOMAIN_JWT_SECRET_KEY": cfg.RequireSecret("happydomain_jwt_secret_key"),
|
||||||
|
"HAPPYDOMAIN_OVH_APPLICATION_KEY": cfg.RequireSecret("happydomain_ovh_application_key"),
|
||||||
|
"HAPPYDOMAIN_OVH_APPLICATION_SECRET": cfg.RequireSecret("happydomain_ovh_application_secret"),
|
||||||
|
"HAPPYDOMAIN_VERSION": pulumi.String("latest"),
|
||||||
|
"MY_DOMAIN": pulumi.String("app.happydomain.org"),
|
||||||
|
"LISTMONK_NEWSLETTER_ID": pulumi.String("4"),
|
||||||
|
"LISTMONK_API_USERNAME": cfg.RequireSecret("listmonk_api_username"),
|
||||||
|
"LISTMONK_API_PASSWORD": cfg.RequireSecret("listmonk_api_password"),
|
||||||
|
"LISTMONK_DOMAIN": pulumi.String("lists.happydomain.org"),
|
||||||
|
"LISTMONK_S3_BUCKET": pulumi.String(HappyListmonkBucketName),
|
||||||
|
"LISTMONK_S3_CLIENT_ID": listmonkAuthToken.ID(),
|
||||||
|
"LISTMONK_S3_CLIENT_SECRET": listmonkAuthToken.Key,
|
||||||
|
"LISTMONK_S3_HOST": storens,
|
||||||
|
"LISTMONK_S3_REGION": pulumi.String(ocicfg.Require("region")),
|
||||||
|
"POSTGRES_PASSWORD": cfg.RequireSecret("postgres_password"),
|
||||||
|
"RESTIC_REPOSITORY": pulumi.String("s3:storage.nemunai.re/zbackup-happydomain"),
|
||||||
|
"RESTIC_REPOSITORY_POSTGRES": pulumi.String("s3:storage.nemunai.re/zbackup-postgres-happydomain"),
|
||||||
|
"RESTIC_PASSWORD": cfg.RequireSecret("restic_password"),
|
||||||
|
"RESTIC_AWS_ACCESS_KEY_ID": cfg.RequireSecret("restic_aws_access_key_id"),
|
||||||
|
"RESTIC_AWS_SECRET_ACCESS_KEY": cfg.RequireSecret("restic_aws_secret_access_key"),
|
||||||
|
"TRY_DOMAIN": pulumi.String("try.happydomain.org"),
|
||||||
|
"TRY_UMAMI_ID": pulumi.String("0af0b29f-bf8a-4801-918a-01a8fb4b4312"),
|
||||||
|
},
|
||||||
|
Metadata: pulumi.Map{
|
||||||
|
"user_data": pulumi.String(base64.StdEncoding.EncodeToString(userData)),
|
||||||
|
"ssh_authorized_keys": pulumi.String(SSH_AUTHORIZED_KEYS),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the public-ip
|
||||||
|
ctx.Export("instance-ip", instance.PublicIp)
|
||||||
|
|
||||||
|
// Add host to backend
|
||||||
|
_, err = networkloadbalancer.NewBackend(ctx, "happydomain-lb4", &networkloadbalancer.BackendArgs{
|
||||||
|
BackendSetName: nlbset4.Name,
|
||||||
|
NetworkLoadBalancerId: nlb.ID(),
|
||||||
|
Port: pulumi.Int(0),
|
||||||
|
IpAddress: instance.PrivateIp,
|
||||||
|
TargetId: instance.ID(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
17
main.go
17
main.go
@ -19,7 +19,22 @@ func main() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = setupEmails(ctx, ocicfg, compartment)
|
ns, listmonkAuthToken, err := setupListmonkStorage(ctx, ocicfg, compartment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pemprvkey, smtpcreds, err := setupEmails(ctx, ocicfg, compartment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
subnet, err := setupNetwork(ctx, compartment)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = setupHostMain(ctx, ocicfg, compartment, ns, subnet, listmonkAuthToken, smtpcreds, pemprvkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
146
network.go
Normal file
146
network.go
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/core"
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/identity"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupNetwork(ctx *pulumi.Context, compartment *identity.Compartment) (*core.Subnet, error) {
|
||||||
|
// Create Virtual Network
|
||||||
|
vcn, err := core.NewVcn(ctx, "happydomain-vnc", &core.VcnArgs{
|
||||||
|
/*Byoipv6cidrDetails: core.VcnByoipv6cidrDetailArray{
|
||||||
|
&core.VcnByoipv6cidrDetailArgs{
|
||||||
|
Byoipv6rangeId: pulumi.String("test"),
|
||||||
|
Ipv6cidrBlock: pulumi.String("2603:c022:2:7a00::/56"),
|
||||||
|
},
|
||||||
|
},*/
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
CidrBlocks: pulumi.StringArray{
|
||||||
|
pulumi.String("10.0.0.0/24"),
|
||||||
|
},
|
||||||
|
DisplayName: pulumi.String("happydomain-net"),
|
||||||
|
DnsLabel: pulumi.String("thobis"),
|
||||||
|
IsIpv6enabled: pulumi.Bool(true),
|
||||||
|
IsOracleGuaAllocationEnabled: pulumi.Bool(true),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
securityList, err := core.NewSecurityList(ctx, "happydomain-security-list", &core.SecurityListArgs{
|
||||||
|
VcnId: vcn.ID(),
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-sl", ctx.Stack()),
|
||||||
|
EgressSecurityRules: core.SecurityListEgressSecurityRuleArray{
|
||||||
|
core.SecurityListEgressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("all"),
|
||||||
|
Destination: pulumi.String("0.0.0.0/0"),
|
||||||
|
},
|
||||||
|
core.SecurityListEgressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("all"),
|
||||||
|
Destination: pulumi.String("::/0"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IngressSecurityRules: core.SecurityListIngressSecurityRuleArray{
|
||||||
|
core.SecurityListIngressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("6"),
|
||||||
|
Source: pulumi.String("0.0.0.0/0"),
|
||||||
|
Description: pulumi.String("IPv4 SSH Port"),
|
||||||
|
TcpOptions: core.SecurityListIngressSecurityRuleTcpOptionsArgs{
|
||||||
|
Max: pulumi.Int(22),
|
||||||
|
Min: pulumi.Int(22),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
core.SecurityListIngressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("6"),
|
||||||
|
Source: pulumi.String("0.0.0.0/0"),
|
||||||
|
Description: pulumi.String("IPv4 HTTP Port"),
|
||||||
|
TcpOptions: core.SecurityListIngressSecurityRuleTcpOptionsArgs{
|
||||||
|
Max: pulumi.Int(80),
|
||||||
|
Min: pulumi.Int(80),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
core.SecurityListIngressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("6"),
|
||||||
|
Source: pulumi.String("0.0.0.0/0"),
|
||||||
|
Description: pulumi.String("IPv4 HTTPS Port"),
|
||||||
|
TcpOptions: core.SecurityListIngressSecurityRuleTcpOptionsArgs{
|
||||||
|
Max: pulumi.Int(443),
|
||||||
|
Min: pulumi.Int(443),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
core.SecurityListIngressSecurityRuleArgs{
|
||||||
|
Protocol: pulumi.String("6"),
|
||||||
|
Source: pulumi.String("::/0"),
|
||||||
|
Description: pulumi.String("IPv6 SSH Port"),
|
||||||
|
TcpOptions: core.SecurityListIngressSecurityRuleTcpOptionsArgs{
|
||||||
|
Max: pulumi.Int(22),
|
||||||
|
Min: pulumi.Int(22),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
subnet, err := core.NewSubnet(ctx, "happydomain-subnet", &core.SubnetArgs{
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
VcnId: vcn.ID(),
|
||||||
|
CidrBlock: pulumi.String("10.0.0.0/24"),
|
||||||
|
Ipv6cidrBlocks: vcn.Ipv6cidrBlocks.ApplyT(func(blocks []string) []string {
|
||||||
|
for i := range blocks {
|
||||||
|
blocks[i] = strings.Replace(blocks[i], "/56", "/64", -1)
|
||||||
|
}
|
||||||
|
return blocks
|
||||||
|
}).(pulumi.StringArrayOutput),
|
||||||
|
SecurityListIds: pulumi.StringArray{
|
||||||
|
vcn.DefaultSecurityListId,
|
||||||
|
securityList.ID(),
|
||||||
|
},
|
||||||
|
ProhibitPublicIpOnVnic: pulumi.Bool(false),
|
||||||
|
RouteTableId: vcn.DefaultRouteTableId,
|
||||||
|
DhcpOptionsId: vcn.DefaultDhcpOptionsId,
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-subnet", ctx.Stack()),
|
||||||
|
DnsLabel: pulumi.String("happysubnet"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
internetGateway, err := core.NewInternetGateway(ctx, "happydomain-internet-gateway", &core.InternetGatewayArgs{
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
VcnId: vcn.ID(),
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-rg", ctx.Stack()),
|
||||||
|
Enabled: pulumi.Bool(true),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = core.NewDefaultRouteTable(ctx, "happydomain-route-table", &core.DefaultRouteTableArgs{
|
||||||
|
ManageDefaultResourceId: vcn.DefaultRouteTableId,
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
DisplayName: pulumi.Sprintf("%s-happydomain-rt", ctx.Stack()),
|
||||||
|
RouteRules: core.DefaultRouteTableRouteRuleArray{
|
||||||
|
core.DefaultRouteTableRouteRuleArgs{
|
||||||
|
NetworkEntityId: internetGateway.ID(),
|
||||||
|
Destination: pulumi.String("0.0.0.0/0"),
|
||||||
|
DestinationType: pulumi.String("CIDR_BLOCK"),
|
||||||
|
},
|
||||||
|
core.DefaultRouteTableRouteRuleArgs{
|
||||||
|
NetworkEntityId: internetGateway.ID(),
|
||||||
|
Destination: pulumi.String("::/0"),
|
||||||
|
DestinationType: pulumi.String("CIDR_BLOCK"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return subnet, nil
|
||||||
|
}
|
135
storage.go
Normal file
135
storage.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/identity"
|
||||||
|
"github.com/pulumi/pulumi-oci/sdk/go/oci/objectstorage"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||||
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const HappyListmonkBucketName = "listmonk-files"
|
||||||
|
|
||||||
|
func setupListmonkStorage(ctx *pulumi.Context, ocicfg *config.Config, compartment *identity.Compartment) (pulumi.StringOutput, *identity.CustomerSecretKey, error) {
|
||||||
|
// Retrieve current namespace
|
||||||
|
ns := compartment.CompartmentId.ApplyT(func(compartmentId string) (string, error) {
|
||||||
|
ns, err := objectstorage.GetNamespace(ctx, &objectstorage.GetNamespaceArgs{
|
||||||
|
CompartmentId: &compartmentId,
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return ns.Namespace, nil
|
||||||
|
}).(pulumi.StringOutput)
|
||||||
|
|
||||||
|
// Create bucket
|
||||||
|
_, err := objectstorage.NewBucket(ctx, HappyListmonkBucketName, &objectstorage.BucketArgs{
|
||||||
|
CompartmentId: compartment.ID(),
|
||||||
|
Namespace: ns,
|
||||||
|
Name: pulumi.String(HappyListmonkBucketName),
|
||||||
|
AccessType: pulumi.String("NoPublicAccess"),
|
||||||
|
StorageTier: pulumi.String("Standard"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create service account
|
||||||
|
listmonkUser, err := identity.NewUser(ctx, "listmonk-user", &identity.UserArgs{
|
||||||
|
Name: pulumi.String("listmonk"),
|
||||||
|
Description: pulumi.String("User for Listmonk"),
|
||||||
|
Email: pulumi.String("postmaster+listmonk@happydomain.fr"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set user capabilities
|
||||||
|
_, err = identity.NewUserCapabilitiesManagement(ctx, "listmonk-user-caps", &identity.UserCapabilitiesManagementArgs{
|
||||||
|
UserId: listmonkUser.ID(),
|
||||||
|
CanUseApiKeys: pulumi.Bool(false),
|
||||||
|
CanUseAuthTokens: pulumi.Bool(false),
|
||||||
|
CanUseConsolePassword: pulumi.Bool(false),
|
||||||
|
CanUseCustomerSecretKeys: pulumi.Bool(true),
|
||||||
|
CanUseSmtpCredentials: pulumi.Bool(false),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create groups
|
||||||
|
readWriteGroup, err := identity.NewGroup(ctx, "S3ListmonkReadWriteGroup", &identity.GroupArgs{
|
||||||
|
Name: pulumi.String("s3_read_write_listmonk"),
|
||||||
|
Description: pulumi.String("Users with read and write access to Object Storage " + HappyListmonkBucketName),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add users to groups
|
||||||
|
_, err = identity.NewUserGroupMembership(ctx, "listmonkReadWriteGroupMembership", &identity.UserGroupMembershipArgs{
|
||||||
|
GroupId: readWriteGroup.ID(),
|
||||||
|
UserId: listmonkUser.ID(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define policies for the groups
|
||||||
|
policies := []struct {
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
group pulumi.StringOutput
|
||||||
|
policy []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "readWritePolicy-listmonk",
|
||||||
|
description: "readWritePolicy to " + HappyListmonkBucketName + " bucket object storage",
|
||||||
|
group: readWriteGroup.Name,
|
||||||
|
policy: []string{
|
||||||
|
"Allow group 'Default'/'s3_read_write_listmonk' to read buckets in compartment %s",
|
||||||
|
fmt.Sprintf("Allow group 'Default'/'s3_read_write_listmonk' to manage objects in compartment %%s where all {target.bucket.name= '%s', any {request.permission= 'OBJECT_CREATE', request.permission='OBJECT_INSPECT', request.permission='OBJECT_OVERWRITE', request.permission='PAR_MANAGE'}}", HappyListmonkBucketName),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
compartment.Name.ApplyT(func(compartmentName string) string {
|
||||||
|
compartment.CompartmentId.ApplyT(func(compartmentId string) (string, error) {
|
||||||
|
for _, p := range policies {
|
||||||
|
var statements pulumi.StringArray
|
||||||
|
for _, policy := range p.policy {
|
||||||
|
statements = append(statements, pulumi.String(fmt.Sprintf(policy, compartmentName)))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := identity.NewPolicy(ctx, p.name, &identity.PolicyArgs{
|
||||||
|
CompartmentId: pulumi.String(compartmentId),
|
||||||
|
Name: pulumi.String(p.name),
|
||||||
|
Description: pulumi.String(p.description),
|
||||||
|
Statements: statements,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
})
|
||||||
|
return ""
|
||||||
|
})
|
||||||
|
|
||||||
|
listmonkAuthToken, err := identity.NewCustomerSecretKey(ctx, "listmonk-user-secret-key", &identity.CustomerSecretKeyArgs{
|
||||||
|
UserId: listmonkUser.ID(),
|
||||||
|
DisplayName: pulumi.String("Listmonk to S3"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ns, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the infos
|
||||||
|
ctx.Export("listmonk-access-key", listmonkAuthToken.ID())
|
||||||
|
ctx.Export("listmonk-secret-key", listmonkAuthToken.Key)
|
||||||
|
|
||||||
|
return ns, listmonkAuthToken, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user