#!/bin/bash # create-queue.sh (v2 β€” mit SNS Fan-Out + Standby Queue) # Usage: DOMAIN=andreasknuth.de ./create-queue.sh # # Erstellt pro Domain: # - Primary Queue + DLQ (wie bisher, fΓΌr Contabo) # - Standby Queue + DLQ (NEU, fΓΌr Office-VM) # - SNS Topic (NEU, Fan-Out) # - 2 SNS Subscriptions (NEU, Topic β†’ Primary + Standby) set -e AWS_REGION="us-east-2" if [ -z "$DOMAIN" ]; then echo "Error: DOMAIN environment variable not set" echo "Usage: DOMAIN=andreasknuth.de $0" exit 1 fi DOMAIN_SLUG="${DOMAIN//./-}" QUEUE_NAME="${DOMAIN_SLUG}-queue" DLQ_NAME="${QUEUE_NAME}-dlq" STANDBY_QUEUE_NAME="${DOMAIN_SLUG}-standby-queue" STANDBY_DLQ_NAME="${STANDBY_QUEUE_NAME}-dlq" TOPIC_NAME="${DOMAIN_SLUG}-topic" ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) echo "========================================" echo "Creating SQS + SNS for Email Delivery" echo "========================================" echo "" echo "πŸ“§ Domain: $DOMAIN" echo " Region: $AWS_REGION" echo " Account: $ACCOUNT_ID" echo "" # ============================================================ # 1. Primary DLQ + Queue (wie bisher) # ============================================================ echo "━━━ Primary Queue (Contabo) ━━━" echo "Creating DLQ: $DLQ_NAME" DLQ_URL=$(aws sqs create-queue \ --queue-name "${DLQ_NAME}" \ --region "${AWS_REGION}" \ --attributes '{"MessageRetentionPeriod": "1209600"}' \ --query 'QueueUrl' --output text 2>/dev/null \ || aws sqs get-queue-url --queue-name "${DLQ_NAME}" --region "${AWS_REGION}" --query 'QueueUrl' --output text) DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "${DLQ_URL}" --region "${AWS_REGION}" \ --attribute-names QueueArn --query 'Attributes.QueueArn' --output text) echo " βœ“ DLQ: ${DLQ_ARN}" echo "Creating Queue: $QUEUE_NAME" QUEUE_URL=$(aws sqs create-queue \ --queue-name "${QUEUE_NAME}" \ --region "${AWS_REGION}" \ --attributes "{ \"VisibilityTimeout\": \"300\", \"MessageRetentionPeriod\": \"86400\", \"ReceiveMessageWaitTimeSeconds\": \"20\", \"RedrivePolicy\": \"{\\\"deadLetterTargetArn\\\":\\\"${DLQ_ARN}\\\",\\\"maxReceiveCount\\\":\\\"3\\\"}\" }" \ --query 'QueueUrl' --output text 2>/dev/null \ || aws sqs get-queue-url --queue-name "${QUEUE_NAME}" --region "${AWS_REGION}" --query 'QueueUrl' --output text) QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "${QUEUE_URL}" --region "${AWS_REGION}" \ --attribute-names QueueArn --query 'Attributes.QueueArn' --output text) echo " βœ“ Queue: ${QUEUE_ARN}" echo "" # ============================================================ # 2. Standby DLQ + Queue (NEU) # ============================================================ echo "━━━ Standby Queue (Office-VM) ━━━" echo "Creating Standby DLQ: $STANDBY_DLQ_NAME" STANDBY_DLQ_URL=$(aws sqs create-queue \ --queue-name "${STANDBY_DLQ_NAME}" \ --region "${AWS_REGION}" \ --attributes '{"MessageRetentionPeriod": "1209600"}' \ --query 'QueueUrl' --output text 2>/dev/null \ || aws sqs get-queue-url --queue-name "${STANDBY_DLQ_NAME}" --region "${AWS_REGION}" --query 'QueueUrl' --output text) STANDBY_DLQ_ARN=$(aws sqs get-queue-attributes --queue-url "${STANDBY_DLQ_URL}" --region "${AWS_REGION}" \ --attribute-names QueueArn --query 'Attributes.QueueArn' --output text) echo " βœ“ Standby DLQ: ${STANDBY_DLQ_ARN}" echo "Creating Standby Queue: $STANDBY_QUEUE_NAME" STANDBY_QUEUE_URL=$(aws sqs create-queue \ --queue-name "${STANDBY_QUEUE_NAME}" \ --region "${AWS_REGION}" \ --attributes "{ \"VisibilityTimeout\": \"300\", \"MessageRetentionPeriod\": \"86400\", \"ReceiveMessageWaitTimeSeconds\": \"20\", \"RedrivePolicy\": \"{\\\"deadLetterTargetArn\\\":\\\"${STANDBY_DLQ_ARN}\\\",\\\"maxReceiveCount\\\":\\\"3\\\"}\" }" \ --query 'QueueUrl' --output text 2>/dev/null \ || aws sqs get-queue-url --queue-name "${STANDBY_QUEUE_NAME}" --region "${AWS_REGION}" --query 'QueueUrl' --output text) STANDBY_QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "${STANDBY_QUEUE_URL}" --region "${AWS_REGION}" \ --attribute-names QueueArn --query 'Attributes.QueueArn' --output text) echo " βœ“ Standby Queue: ${STANDBY_QUEUE_ARN}" echo "" # ============================================================ # 3. SNS Topic (NEU) # ============================================================ echo "━━━ SNS Topic (Fan-Out) ━━━" echo "Creating Topic: $TOPIC_NAME" TOPIC_ARN=$(aws sns create-topic \ --name "${TOPIC_NAME}" \ --region "${AWS_REGION}" \ --query 'TopicArn' --output text) echo " βœ“ Topic: ${TOPIC_ARN}" echo "" # ============================================================ # 4. SNS β†’ SQS Subscriptions (NEU) # ============================================================ echo "━━━ Subscriptions ━━━" # SNS braucht Berechtigung, in die SQS Queues zu schreiben # Policy fΓΌr Primary Queue POLICY_PRIMARY="{ \"Version\": \"2012-10-17\", \"Statement\": [{ \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"sns.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"${QUEUE_ARN}\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"${TOPIC_ARN}\"}} }] }" aws sqs set-queue-attributes \ --queue-url "${QUEUE_URL}" \ --region "${AWS_REGION}" \ --attributes "{\"Policy\": $(echo "$POLICY_PRIMARY" | jq -c '.' | jq -Rs '.')}" \ > /dev/null echo " βœ“ Primary Queue Policy gesetzt" # Policy fΓΌr Standby Queue POLICY_STANDBY="{ \"Version\": \"2012-10-17\", \"Statement\": [{ \"Effect\": \"Allow\", \"Principal\": {\"Service\": \"sns.amazonaws.com\"}, \"Action\": \"sqs:SendMessage\", \"Resource\": \"${STANDBY_QUEUE_ARN}\", \"Condition\": {\"ArnEquals\": {\"aws:SourceArn\": \"${TOPIC_ARN}\"}} }] }" aws sqs set-queue-attributes \ --queue-url "${STANDBY_QUEUE_URL}" \ --region "${AWS_REGION}" \ --attributes "{\"Policy\": $(echo "$POLICY_STANDBY" | jq -c '.' | jq -Rs '.')}" \ > /dev/null echo " βœ“ Standby Queue Policy gesetzt" # Subscription: Topic β†’ Primary Queue SUB_PRIMARY=$(aws sns subscribe \ --topic-arn "${TOPIC_ARN}" \ --protocol sqs \ --notification-endpoint "${QUEUE_ARN}" \ --region "${AWS_REGION}" \ --attributes '{"RawMessageDelivery": "true"}' \ --query 'SubscriptionArn' --output text) echo " βœ“ Subscription Primary: ${SUB_PRIMARY}" # Subscription: Topic β†’ Standby Queue SUB_STANDBY=$(aws sns subscribe \ --topic-arn "${TOPIC_ARN}" \ --protocol sqs \ --notification-endpoint "${STANDBY_QUEUE_ARN}" \ --region "${AWS_REGION}" \ --attributes '{"RawMessageDelivery": "true"}' \ --query 'SubscriptionArn' --output text) echo " βœ“ Subscription Standby: ${SUB_STANDBY}" echo "" # ============================================================ # Zusammenfassung # ============================================================ echo "========================================" echo "βœ… Setup complete for $DOMAIN" echo "========================================" echo "" echo "Primary (Contabo):" echo " Queue: $QUEUE_URL" echo " DLQ: $DLQ_URL" echo "" echo "Standby (Office-VM):" echo " Queue: $STANDBY_QUEUE_URL" echo " DLQ: $STANDBY_DLQ_URL" echo "" echo "SNS Fan-Out:" echo " Topic: $TOPIC_ARN" echo " β†’ Primary: $SUB_PRIMARY" echo " β†’ Standby: $SUB_STANDBY" echo "" echo "⚠️ NΓ€chste Schritte:" echo " 1. Lambda-Funktion updaten: sns.publish() statt sqs.send_message()" echo " 2. Lambda IAM Role: sns:Publish Berechtigung hinzufΓΌgen" echo " 3. Worker auf Office-VM: QUEUE_SUFFIX=-standby-queue konfigurieren" echo " 4. Worker auf Office-VM: STANDBY_MODE=true setzen"