187 lines
7.8 KiB
Bash
Executable File
187 lines
7.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# awsses_lambda_global.sh - SES Setup mit S3 + Global Lambda Shim -> SQS
|
|
# Dieses Skript ist idempotent: Es kann sicher mehrfach ausgeführt werden.
|
|
# Globale Lambda für alle Domains.
|
|
|
|
set -e
|
|
|
|
# --- CHECKS ---
|
|
if ! command -v jq &> /dev/null; then echo "Fehler: 'jq' fehlt."; exit 1; fi
|
|
if [ -z "$DOMAIN_NAME" ]; then echo "Fehler: DOMAIN_NAME ist nicht gesetzt."; exit 1; fi
|
|
|
|
# Prüfen ob Python Code da ist
|
|
PYTHON_FILE="ses_sns_shim_global.py"
|
|
if [ ! -f "$PYTHON_FILE" ]; then
|
|
echo "Fehler: $PYTHON_FILE nicht gefunden!"
|
|
exit 1
|
|
fi
|
|
|
|
# --- VARIABLEN ---
|
|
AWS_REGION=${AWS_REGION:-"us-east-2"}
|
|
EMAIL_PREFIX=${EMAIL_PREFIX:-""}
|
|
CONFIGURATION_SET_NAME="relay-outbound"
|
|
|
|
# Bucket Name generieren falls leer
|
|
if [ -z "$S3_BUCKET_NAME" ]; then
|
|
S3_BUCKET_NAME=$(echo "$DOMAIN_NAME" | tr '.' '-' | awk '{print $0 "-emails"}')
|
|
fi
|
|
|
|
# Namen (Global Lambda!)
|
|
RULE_SET_NAME="bizmatch-ruleset"
|
|
RULE_NAME="store-${DOMAIN_NAME//./-}-to-s3"
|
|
QUEUE_NAME="${DOMAIN_NAME//./-}-queue"
|
|
LAMBDA_NAME="ses-shim-global"
|
|
LAMBDA_ROLE_NAME="SesShimGlobalRole"
|
|
|
|
echo "=========================================================="
|
|
echo " SES Setup (S3 -> Global Lambda Shim -> SQS) für $DOMAIN_NAME"
|
|
echo "=========================================================="
|
|
|
|
# ---------------------------------------------------------
|
|
# 1. SES Identity & Config Set
|
|
# ---------------------------------------------------------
|
|
echo "[1/6] SES Identity Setup..."
|
|
if ! aws sesv2 get-email-identity --email-identity ${DOMAIN_NAME} --region ${AWS_REGION} >/dev/null 2>&1; then
|
|
aws sesv2 create-email-identity --email-identity ${DOMAIN_NAME} --region ${AWS_REGION} >/dev/null
|
|
fi
|
|
# Update Attributes (Idempotent)
|
|
aws sesv2 put-email-identity-dkim-attributes --email-identity ${DOMAIN_NAME} --signing-enabled --region ${AWS_REGION}
|
|
aws sesv2 put-email-identity-mail-from-attributes --email-identity ${DOMAIN_NAME} --mail-from-domain "mail.${DOMAIN_NAME}" --behavior-on-mx-failure USE_DEFAULT_VALUE --region ${AWS_REGION}
|
|
aws sesv2 put-email-identity-configuration-set-attributes --email-identity ${DOMAIN_NAME} --configuration-set-name "$CONFIGURATION_SET_NAME" --region ${AWS_REGION}
|
|
|
|
# ---------------------------------------------------------
|
|
# 2. SQS Queue holen (nur zur Validierung, Lambda holt dynamisch)
|
|
# ---------------------------------------------------------
|
|
echo "[2/6] Queue URL ermitteln (zur Validierung)..."
|
|
QUEUE_URL=$(aws sqs get-queue-url --queue-name "$QUEUE_NAME" --region "$AWS_REGION" --output text --query 'QueueUrl' 2>/dev/null)
|
|
if [ -z "$QUEUE_URL" ]; then echo "FEHLER: Queue $QUEUE_NAME nicht gefunden! ./create-queue.sh zuerst ausführen."; exit 1; fi
|
|
QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "$QUEUE_URL" --attribute-names QueueArn --region "$AWS_REGION" --output text --query 'Attributes.QueueArn')
|
|
|
|
# ---------------------------------------------------------
|
|
# 3. IAM Role für Global Lambda erstellen
|
|
# ---------------------------------------------------------
|
|
echo "[3/6] IAM Role für Lambda prüfen/erstellen..."
|
|
TRUST_POLICY='{"Version": "2012-10-17","Statement": [{"Effect": "Allow","Principal": {"Service": "lambda.amazonaws.com"},"Action": "sts:AssumeRole"}]}'
|
|
if ! aws iam get-role --role-name "$LAMBDA_ROLE_NAME" >/dev/null 2>&1; then
|
|
aws iam create-role --role-name "$LAMBDA_ROLE_NAME" --assume-role-policy-document "$TRUST_POLICY" >/dev/null
|
|
echo " -> Rolle erstellt."
|
|
else
|
|
echo " -> Rolle existiert bereits."
|
|
fi
|
|
|
|
# Permissions Policy (Lambda darf Logs schreiben und in ALLE Queues mit *-queue senden)
|
|
LAMBDA_POLICY=$(jq -n '{
|
|
Version: "2012-10-17",
|
|
Statement: [
|
|
{
|
|
Effect: "Allow",
|
|
Action: ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"],
|
|
Resource: "arn:aws:logs:*:*:*"
|
|
},
|
|
{
|
|
Effect: "Allow",
|
|
Action: "sqs:SendMessage",
|
|
Resource: "arn:aws:sqs:*:*:*-queue"
|
|
},
|
|
{
|
|
Effect: "Allow",
|
|
Action: "sqs:GetQueueUrl",
|
|
Resource: "*"
|
|
}
|
|
]
|
|
}' | jq -c .)
|
|
aws iam put-role-policy --role-name "$LAMBDA_ROLE_NAME" --policy-name "SesShimGlobalPermissions" --policy-document "$LAMBDA_POLICY"
|
|
echo " -> Permissions aktualisiert."
|
|
|
|
# Kurze Pause für IAM Propagation, falls Rolle neu war
|
|
sleep 5
|
|
|
|
# ---------------------------------------------------------
|
|
# 4. Lambda Funktion erstellen/updaten (Global!)
|
|
# ---------------------------------------------------------
|
|
echo "[4/6] Global Lambda Shim deployen..."
|
|
# Zip erstellen
|
|
cp "$PYTHON_FILE" lambda_function.py
|
|
zip -q lambda.zip lambda_function.py
|
|
# Keine Env-Vars nötig, da dynamisch
|
|
ROLE_ARN=$(aws iam get-role --role-name "$LAMBDA_ROLE_NAME" --query 'Role.Arn' --output text)
|
|
if ! aws lambda get-function --function-name "$LAMBDA_NAME" --region "$AWS_REGION" >/dev/null 2>&1; then
|
|
echo " -> Erstelle neue Lambda-Funktion..."
|
|
aws lambda create-function --function-name "$LAMBDA_NAME" \
|
|
--runtime python3.11 --handler lambda_function.lambda_handler \
|
|
--role "$ROLE_ARN" --zip-file fileb://lambda.zip \
|
|
--region "$AWS_REGION" >/dev/null
|
|
else
|
|
echo " -> Aktualisiere existierende Lambda-Funktion..."
|
|
aws lambda update-function-code --function-name "$LAMBDA_NAME" --zip-file fileb://lambda.zip --region "$AWS_REGION" >/dev/null
|
|
|
|
# Warte kurz
|
|
sleep 2
|
|
|
|
aws lambda update-function-configuration --function-name "$LAMBDA_NAME" --region "$AWS_REGION" >/dev/null
|
|
fi
|
|
# Aufräumen
|
|
rm lambda.zip lambda_function.py
|
|
|
|
# ---------------------------------------------------------
|
|
# 5. Permission: SES darf Lambda aufrufen (Global, einmalig)
|
|
# ---------------------------------------------------------
|
|
echo "[5/6] SES Permission für Lambda..."
|
|
aws lambda add-permission --function-name "$LAMBDA_NAME" \
|
|
--statement-id "AllowSESInvoke-Global" \
|
|
--action "lambda:InvokeFunction" \
|
|
--principal "ses.amazonaws.com" \
|
|
--region "$AWS_REGION" 2>/dev/null || true
|
|
|
|
# ---------------------------------------------------------
|
|
# 6. SES Rule (S3 + Global Lambda)
|
|
# ---------------------------------------------------------
|
|
echo "[6/6] SES Receipt Rule (S3 + Lambda) konfigurieren..."
|
|
LAMBDA_ARN=$(aws lambda get-function --function-name "$LAMBDA_NAME" --region "$AWS_REGION" --query 'Configuration.FunctionArn' --output text)
|
|
# Rule Set prüfen
|
|
if ! aws ses list-receipt-rule-sets --region ${AWS_REGION} | grep -q "bizmatch-ruleset"; then
|
|
aws ses create-receipt-rule-set --rule-set-name "bizmatch-ruleset" --region ${AWS_REGION}
|
|
fi
|
|
# Regel-Definition
|
|
RULE_JSON=$(jq -n \
|
|
--arg bucket "$S3_BUCKET_NAME" \
|
|
--arg prefix "$EMAIL_PREFIX" \
|
|
--arg larn "$LAMBDA_ARN" \
|
|
--arg rule "$RULE_NAME" \
|
|
--arg domain "$DOMAIN_NAME" \
|
|
--arg subdomain "mail.$DOMAIN_NAME" \
|
|
'{
|
|
Name: $rule,
|
|
Enabled: true,
|
|
ScanEnabled: true,
|
|
TlsPolicy: "Require",
|
|
Recipients: [$domain, $subdomain],
|
|
Actions: [
|
|
{
|
|
S3Action: {
|
|
BucketName: $bucket,
|
|
ObjectKeyPrefix: $prefix
|
|
}
|
|
},
|
|
{
|
|
LambdaAction: {
|
|
FunctionArn: $larn,
|
|
InvocationType: "Event"
|
|
}
|
|
}
|
|
]
|
|
}')
|
|
# Check ob Regel existiert -> Update, sonst Create
|
|
if aws ses describe-receipt-rule --rule-set-name "bizmatch-ruleset" --rule-name "$RULE_NAME" --region "$AWS_REGION" >/dev/null 2>&1; then
|
|
echo " -> Aktualisiere existierende Regel..."
|
|
aws ses update-receipt-rule --rule-set-name "bizmatch-ruleset" --rule "$RULE_JSON" --region "$AWS_REGION"
|
|
else
|
|
echo " -> Erstelle neue Regel..."
|
|
aws ses create-receipt-rule --rule-set-name "bizmatch-ruleset" --rule "$RULE_JSON" --region "$AWS_REGION"
|
|
fi
|
|
# Aktivieren
|
|
aws ses set-active-receipt-rule-set --rule-set-name "bizmatch-ruleset" --region ${AWS_REGION}
|
|
echo "========================================================"
|
|
echo "✅ Setup erfolgreich. Globale Lambda ($LAMBDA_NAME) für alle Domains."
|
|
echo " S3 -> Lambda -> Domain-spezifische SQS"
|
|
echo "========================================================" |