LoginSignup
2
2

More than 3 years have passed since last update.

AWSのSNSとDynamoDBをDockerComposeとPython(boto3)を使ってローカルで動かしたことについての備忘録

Last updated at Posted at 2019-10-17

はじめに

  • こんにちはRIN1208です。今回はAWSのSNSとDynamoDBを触れることになり、先ずはローカルでやってみようとのことでDockerComposeで動かしたのですがいろいろあったので(主にSNS)忘れないため、またこれから触る人の参考になればと思いこの記事を書きました。
  • また間違っている箇所がありましたら指摘して頂けると幸いです。

実行環境

  • macos catalia .ver10.15
    • Docker for Mac

使用したコンテナ等

DynamoDB local

Fake SNS

  • 今回はPublishするだけだったのでFake SNSというのを使用しました

boto3

DynamoDBにデータを書き込むコード等

  • docker-compose.yml
docker-compose.yml
version: "3"
services:
  dynamodb:
    image: amazon/dynamodb-local
    ports:
      - 8000:8000
  app:
    build:
      context: .
    tty: true
    links:
      - dynamodb
  • Dockerfile
    • 今回は使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
FROM python:3.6
WORKDIR /
RUN pip install boto3
COPY . /
  • pythonのコード
    • ここではテーブルの作成、データの書き込み、テーブル一覧の取得をしています
    • aws_access_key_idとaws_secret_access_keyはdynamodb local だと適当な文字列で大丈夫です。
main.py
import boto3

resource = boto3.resource(
    'dynamodb',
    region_name='us-east-1',
    endpoint_url="http://dynamodb:8000/",
    aws_access_key_id='ACCESS_ID',
    aws_secret_access_key='ACCESS_KEY'
)

client = boto3.client(
    'dynamodb',
    region_name='us-east-1',
    endpoint_url="http://dynamodb:8000/",
    aws_access_key_id='ACCESS_ID',
    aws_secret_access_key='ACCESS_KEY'
)

# 以下の処理はテーブルの作成

tab = resource.create_table(
    TableName='atelier',
    KeySchema=[
        {
            'AttributeName': 'id',
            'KeyType': 'HASH'
        }
    ],
    AttributeDefinitions=[
        {
            'AttributeName': 'id',
            'AttributeType': 'N'
        }
    ],
    ProvisionedThroughput={
        'ReadCapacityUnits': 1,
        'WriteCapacityUnits': 1
    }
)


print('Table status:', tab.table_status)

# 以下の処理はデータの書き込み及び、書き込んだデータの取得

table = resource.Table('atelier')

table.put_item(
    Item={
        "id": 1,
        "name": "Ryza",
        "job": "Alchemist"
    }

)

res = table.get_item(Key={'id': 1})

print(res['Item'])

# 以下の処理はテーブル一覧の取得

tables = client.list_tables()

print('Tables List:', tables['TableNames'])

実行結果

  • 実行して以下のように出力されていれば無事処理は成功

実行コマンド

docker-compose up -d --build && docker-compose exec app  bash -c "python main.py"

以下のような感じで出力されていれば大丈夫です

Table status: ACTIVE
{'name': 'Ryza', 'job': 'Alchemist', 'id': Decimal('1')}
Tables List: ['test']

詳細はこちらを参照してください。

SNSにPublish

  • これが一番苦戦しました

  • docker-compose.yml

docker-compose.yml
version: "3"
services:
  sns:
    image: s12v/sns
    ports:
      - 9911:9911
  app:
    build:
      context: .
    tty: true
    links:
      - sns
  • Dockerfile
    • 今回も使うパッケージがboto3だけなのでrequirements.txtは使わずにそのままpip installしています
FROM python:3.6
WORKDIR /
RUN pip install boto3
COPY . /
  • pythonのコード
    • 今回もaws_access_key_idとaws_secret_access_keyは適当で大丈夫です
main.py
import boto3

sns = boto3.client('sns', region_name='us-east-1',
                   endpoint_url="http://sns:9911",
                   aws_access_key_id='foo',
                   aws_secret_access_key='bar')
res = sns.create_topic(
    Name='atelier',
)
print(res['TopicArn'])

listTopic = sns.list_topics(
    NextToken=res['TopicArn']
)

print(listTopic)

##-------------------
sns.subscribe(
    TopicArn=res['TopicArn'],
    Protocol='http',
    Endpoint='http',
    ReturnSubscriptionArn=True
)
##-------------------

subscriptions = sns.list_subscriptions_by_topic(
    TopicArn=res['TopicArn']
)

print(subscriptions)

response = sns.publish(
    TopicArn=res['TopicArn'],
    Message='hutomomo yabai'
)

print(response)

実行結果

実行コマンド

docker-compose up -d --build && docker-compose exec app  bash -c "python main.py"

以下のような感じで出力されていれば大丈夫です

{'Topics': [{'TopicArn': 'arn:aws:sns:us-east-1:123456789012:atelier'}], 'ResponseMetadata': {'RequestId': '3206fffa-b256-4100-b005-7d064c305f35', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '317'}, 'RetryAttempts': 0}}

{'Subscriptions': [{'SubscriptionArn': 'arn:aws:sns:us-east-1:123456789012:atelier:c2e93c42-e7b6-465b-bc71-01ac3b538e2c', 'Owner': '', 'Protocol': 'http', 'Endpoint': 'http', 'TopicArn': 'arn:aws:sns:us-east-1:123456789012:atelier'}], 'ResponseMetadata': {'RequestId': 'e872c714-7152-4233-9ba9-d930ed461ca6', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '563'}, 'RetryAttempts': 0}}

{'MessageId': 'd523ef9c-dca6-4164-8a75-6bf85b0d9c7a', 'ResponseMetadata': {'RequestId': '057296d4-b0b0-4f96-8153-b55224ca6d17', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'akka-http/10.0.10', 'date': 'Thu, 17 Oct 2019 15:25:50 GMT', 'content-type': 'text/xml; charset=UTF-8', 'content-length': '270'}, 'RetryAttempts': 0}}

躓いたポイント

上のコードの囲ってある部分で躓いていました

# この部分
sns.subscribe(
    TopicArn=res['TopicArn'],
    Protocol='http',
    Endpoint='http',
    ReturnSubscriptionArn=True
)

この部分で何をしているかというとsubscriptionを作成してるだけです。

ちなみに作成していないと以下のエラーがでます

botocore.errorfactory.NotFoundException: An error occurred (NotFound) when calling the Publish operation: Topic not found: arn:aws:sns:us-east-1:123456789012:atelier

Topic上で作ってるのになんでないの!?ってなりました。
このエラーについてはgithubのissueにも上がっていてこれを見るまで気が付きませんでした.
fakesnsはguiもなく記事も全然なくて...
READMEにサンプルコードかsubscriptionの作成が必要と書いて欲しかった...

最後に

  • こんにちはRIN1208です。この記事でFakeSNSに触れる人の助けになれば幸いです。
  • また、この記事を読んでくださりありがとうございます
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2