diff --git a/basic_setup/create-queue.sh b/basic_setup/create-queue.sh index 643a521..aa00828 100755 --- a/basic_setup/create-queue.sh +++ b/basic_setup/create-queue.sh @@ -1,55 +1,58 @@ #!/bin/bash -# create-queue.sh +# 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" -# Domain aus Environment Variable if [ -z "$DOMAIN" ]; then echo "Error: DOMAIN environment variable not set" echo "Usage: DOMAIN=andreasknuth.de $0" exit 1 fi -QUEUE_NAME="${DOMAIN//./-}-queue" +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 Queue for Email Delivery" +echo "Creating SQS + SNS for Email Delivery" echo "========================================" echo "" -echo "πŸ“§ Domain: $DOMAIN" -echo " Region: $AWS_REGION" +echo "πŸ“§ Domain: $DOMAIN" +echo " Region: $AWS_REGION" +echo " Account: $ACCOUNT_ID" echo "" -# Dead Letter Queue erstellen +# ============================================================ +# 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) + --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 " βœ“ DLQ URL: ${DLQ_URL}" - -# DLQ ARN ermitteln -DLQ_ARN=$(aws sqs get-queue-attributes \ - --queue-url "${DLQ_URL}" \ - --region "${AWS_REGION}" \ - --attribute-names QueueArn \ - --query 'Attributes.QueueArn' \ - --output text) - -echo " βœ“ DLQ ARN: ${DLQ_ARN}" -echo "" - -# Haupt-Queue erstellen mit Redrive Policy -echo "Creating Main Queue: $QUEUE_NAME" +echo "Creating Queue: $QUEUE_NAME" QUEUE_URL=$(aws sqs create-queue \ --queue-name "${QUEUE_NAME}" \ --region "${AWS_REGION}" \ @@ -59,18 +62,146 @@ QUEUE_URL=$(aws sqs create-queue \ \"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) + --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 "" -echo " βœ“ Queue URL: ${QUEUE_URL}" +# ============================================================ +# 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 "βœ… Queue created successfully!" +echo "βœ… Setup complete for $DOMAIN" echo "========================================" echo "" -echo "Configuration:" -echo " Domain: $DOMAIN" -echo " Queue: $QUEUE_NAME" -echo " Queue URL: $QUEUE_URL" -echo " DLQ: $DLQ_NAME" -echo " Region: $AWS_REGION" \ No newline at end of file +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" \ No newline at end of file