Jenkins 側(Bash / AWS SQS Cli)
~/.aws/credentials ファイルが設定されていることが前提となる。
#!/bin/bash
export TARGET_HOST='{"hostname":"https://example1.com","username":"user1","password":"pass1"} \
{"hostname":"https://example2.com","username":"user2","password":"pass2"}'
export SQS_QUEUE_NAME='eaxmple_queue'
for TARGET_HOST in ${TARGET_HOSTS}; do
export SQS_QUEUE_URL=$(aws sqs get-queue-url --queue-name ${SQS_QUEUE_NAME} --output text)
export SQS_MSG_BODY=${TARGET_HOST}
aws sqs send-message --queue-url ${SQS_QUEUE_URL} --message-body ${SQS_MSG_BODY}
done
上のコードにおいて、Jenkins 側(Bash / AWS SQS Cli)で大事なのは以下の 2行のみ。
export SQS_QUEUE_URL=$(aws sqs get-queue-url --queue-name ${SQS_QUEUE_NAME} --output text)
aws sqs send-message --queue-url ${SQS_QUEUE_URL} --message-body ${SQS_MSG_BODY}
Python 側
キューを処理するロジックがWhile True:で始まっているのはなぜか?これは、receive_messages(MaxNumberOfMessages=10)とオプションを指定し、たとえキューに 2つ以上アイテムがあったとしても 1つしかアイテムが返ってこないときもあるし、ひどいときにはキューにアイテムが溜まっているのになにも返ってこないケースがあるからだ。これは AWS SQS の仕様らしいので、```While True:***で始めて、キューを監視して適宜刈り取っていくしかない。
White True:すると無限ループに陥る可能性が大きくなるが、取得したキューは削除候補のリスト messages_to_deleteに入れて削除する。そして刈り取るキューアイテムがなくなったらWhile True:のループを抜けるようになっている。
# -*- coding: utf-8 -*-
import json
import boto3
sqs = boto3.resource('sqs',
<pre><code> aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID,
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY,
region_name = 'us-west-2')
</code></pre>
sqs_queue_name = YOUR_SQS_QUEUE_NAME
q = sqs.get_queue_by_name(QueueName = sqs_queue_name)
while True:
messages_to_delete = []
for message in q.receive_messages(MaxNumberOfMessages = 10, WaitTimeSeconds = 20):
<pre><code>body = json.loads(message.body)
hostname = body['hostname']
username = body['username']
password = body['password']
messages_to_delete.append({
'Id': message.message_id,
'ReceiptHandle': message.receipt_handle
})
do_something(hostname, username, password)
</code></pre>
# if you don't receive any notifications the messages_to_delete list will be empty
if len(messages_to_delete) == 0:
<pre><code>break
</code></pre> # delete messages to remove them from SQS queue handle any errors
else:
<pre><code>q.delete_messages(
Entries = messages_to_delete
)
</code></pre>