AWS SDK for Python(boto3)でAmazon Managed Blockchainのブロックチェーンネットワークを作成してみた

Amazon Managed Blockchainでブロックチェーンネットワークを構築するのにAWS CloudFormationを利用したいなぁとドキュメントを読んでみたらリソースがありませんでした。oh...

AWS CloudFormationのカスタムリソースを利用すれば管理できるので、まずはAWS SDKでAmazon Managed Blockchainが取り扱えるのか確認してみました。

AWS CloudFormationのカスタムリソースについては下記が参考になります。

カスタムリソース - AWS CloudFormation

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources.html

CloudFormationで提供されていない処理をカスタムリソースで作ってみた。 | DevelopersIO

https://dev.classmethod.jp/cloud/aws/cfn-api-custom/

AWS CloudFormationでCognitoユーザープールをMFAのTOTPを有効にして作成する - Qiita

https://qiita.com/kai_kou/items/f56bb13a5d47ee05d766


Amazon Managed Blockchainってなんぞ?

Amazon Managed Blockchainってなんぞ?という方は下記をご参考ください。

Amazon Managed BlockchainがリリースされたのでHyperledger Fabricも合わせて情報をまとめてみた - Qiita

https://qiita.com/kai_kou/items/5a968f42c5f96296f6fe


前提

今回はAmazon Managed Blockchainのネットワーク、メンバー、ノードがAWS SDKで作成できるかの確認のみとなります。セキュリティグループ、インタフェースVPCエンドポイントやHyperledger Fabricの設定などは行いません。


  • AWSアカウントがある

  • AWSアカウントに以下の作成権限がある


    • Managed Blockchainネットワーク



  • AWS CLIのaws configure コマンドでアカウント設定済み

ネットワーク構築して動作確認するまでの手順は下記が参考になります。

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita

https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e


AWS SDK for Python(boto3)でAmazon Managed BlockchainのAPIが提供されてる

ドキュメントを確認してみたらAWS SDKでAmazon Managed BlockchainのAPIが提供されていました。

boto/boto3: AWS SDK for Python

https://github.com/boto/boto3

ManagedBlockchain — Boto 3 Docs 1.9.152 documentation

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/managedblockchain.html


Python環境の用意

Pipenvを利用したことがなかったので、ついでに初利用します(趣味)。

仮想環境じゃなくてもOKです。

Pipenvを使ったPython開発まとめ - Qiita

https://qiita.com/y-tsutsu/items/54c10e0b2c6b565c887a

# pipenvがインストールされてなかったら

> pip install pipenv

(略)
Installing collected packages: virtualenv, virtualenv-clone, pipenv
Successfully installed pipenv-2018.11.26 virtualenv-16.6.0 virtualenv-clone-0.5.3

# 仮想環境の作成
> pipenv --python 3.7

Creating a virtualenv for this project…
Pipfile: /Users/xxx/dev/aws/managed-blockchain-use-sdk/Pipfile
Using /Users/xxx/.anyenv/envs/pyenv/versions/3.7.0/bin/python3 (3.7.0) to create virtualenv…
⠴ Creating virtual environment...
(略)
✔ Successfully created virtual environment!
Virtualenv location: /Users/xxx/.local/share/virtualenvs/managed-blockchain-use-sdk-ijMKrYxz
Creating a Pipfile for this project…

# boto3のインストール
> pipenv install boto3

Installing boto3…
⠴ Installing...
(略)

# 仮想環境へ入る
> pipenv shell

Launching subshell in virtual environment…
Welcome to fish, the friendly interactive shell


AWS SDK for Python(boto3)を利用して実装

ドキュメントを参考にネットワークなどを作成、取得できるか確認します。

ManagedBlockchain — Boto 3 Docs 1.9.152 documentation

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/managedblockchain.html


ネットワークとメンバーの作成

create_network でネットワーク作成できます。パラメータはAWS CLIとほぼ同じなので下記が参考になります。

AWS CLIと同じく最初のメンバーも合わせて作成する必要があります。

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita

https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B


create_network.py

import boto3

client = boto3.client("managedblockchain")

def create_network():
new_network = client.create_network(
# ClientRequestToken="string",
Name="TestNetwork",
Description="TestNetworkDescription",
Framework="HYPERLEDGER_FABRIC",
FrameworkVersion="1.2",
FrameworkConfiguration={
"Fabric": {
"Edition": "STARTER"
}
},
VotingPolicy={
"ApprovalThresholdPolicy": {
"ThresholdPercentage": 50,
"ProposalDurationInHours": 24,
"ThresholdComparator": "GREATER_THAN"
}
},
MemberConfiguration={
"Name": "org1",
"Description": "Org1 first member of network",
"FrameworkConfiguration": {
"Fabric": {
"AdminUsername": "AdminUser",
"AdminPassword": "Password123"
}
}
}
)

print(new_network)


実行するとネットワークとメンバーの作成が開始されてNetworkIdMemberId が得られます。

> python create_network.py


{'ResponseMetadata': {'RequestId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Tue, 21 May 2019 03:24:32 GMT', 'content-type': 'application/json', 'content-length': '86', 'connection': 'keep-alive', 'x-amzn-requestid': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'x-amz-apigw-id': 'xxxxxxxxxxxxxxx=', 'x-amzn-trace-id': 'Root=1-xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;
Sampled=0'}, 'RetryAttempts': 0}, 'NetworkId': 'n-XXXXXXXXXXXXXXXXXXXXXXXXXX', 'MemberId': 'm-XXXXXXXXXXXXXXXXXXXXXXXXXX'}


ネットワーク情報の取得

list_networks でネットワーク情報が取得できます。

パラメータ指定することで検索もできるみたいです。


list_network.py

import boto3

client = boto3.client("managedblockchain")

def list_network():
networks = client.list_networks(
# Name="Test"
# Name="string",
# Framework="HYPERLEDGER_FABRIC",
# Status="CREATING"|"AVAILABLE"|"CREATE_FAILED"|"DELETING"|"DELETED",
# MaxResults=123,
# NextToken="string"
)

print(networks)

list_networks()


> python list_network.py


[{'Id': 'n-XXXXXXXXXXXXXXXXXXXXXXXXXX', 'Name': 'TestNetwork', 'Description': 'TestNetworkDescription', 'Framework': 'HYPERLEDGER_FABRIC', 'FrameworkVersion': '1.2', 'Status': 'CREATING', 'CreationDate': datetime.datetime(2019, 5, 21, 3, 24, 31, 929000, tzinfo=tzutc())}]


ノードの作成

create_node でノード作成ができます。ClientRequestToken に関しては指定しない場合自動生成してくれるとのことでした。手動での生成方法は未調査です。


create_node.py

import boto3

client = boto3.client("managedblockchain")

def create_node():
new_node = client.create_node(
# ClientRequestToken='string',
NetworkId='n-5QBOS5ULTVEZZG6EMIPLPRSSQA',
MemberId='m-OMLBOQIAMJDDPJV3FVGIAVUGBE',
NodeConfiguration={
'InstanceType': 'bc.t3.small',
'AvailabilityZone': 'us-east-1a'
}
)

print(new_node)

create_node()


> python create_node.py


{'ResponseMetadata': {'RequestId': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Tue, 21 May 2019 04:04:44 GMT', 'content-type': 'application/json', 'content-length': '42', 'connection': 'keep-alive', 'x-amzn-requestid': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', 'x-amz-apigw-id': 'xxxxxxxxxxxxxxx=', 'x-amzn-trace-id': 'Root=1-xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx;Sampled=0'}, 'RetryAttempts': 0}, 'NodeId': 'nd-XXXXXXXXXXXXXXXXXXXXXXXXXX'}

ネットワーク、メンバーが作成中(StatusCREATING )の場合は作成できませんでした。


ネットワーク、メンバー作成中に実行

> python create_node.py


Traceback (most recent call last):
File "main.py", line 43, in <module>
'AvailabilityZone': 'us-east-1a'
File "/Users/xxx/.local/share/virtualenvs/managed-blockchain-use-sdk-ijMKrYxz/lib/python3.7/site-packages/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/Users/xxx/.local/share/virtualenvs/managed-blockchain-use-sdk-ijMKrYxz/lib/python3.7/site-packages/botocore/client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.errorfactory.ResourceNotReadyException: An error occurred (ResourceNotReadyException) when calling the CreateNode operation: Member m-XXXXXXXXXXXXXXXXXXXXXXXXXX is in CREATING. you cannot create nodes at this time..


メンバー情報の取得

list_members でメンバーが取得できます。NetworkId が必須となります。


list_members.py

import boto3

client = boto3.client("managedblockchain")

def list_members():
members = client.list_members(
NetworkId="n-XXXXXXXXXXXXXXXXXXXXXXXXXX"
# Name="string",
# Status="CREATING"|"AVAILABLE"|"CREATE_FAILED"|"DELETING"|"DELETED",
# IsOwned=True|False,
# MaxResults=123,
# NextToken="string"
)

print(members["Members"])

list_members()


> python list_members.py


[{'Id': 'm-XXXXXXXXXXXXXXXXXXXXXXXXXX', 'Name': 'demo', 'Description': 'demo member', 'Status': 'AVAILABLE', 'CreationDate': datetime.datetime(2019, 5, 21, 3, 24, 32, 271000, tzinfo=tzutc()), 'IsOwned': True}]


ノード情報の取得

list_nodes でノードが取得できます。NetworkIdMemberId が必須となります。


list_nodes.py

import boto3

client = boto3.client("managedblockchain")

def list_nodes():
nodes = client.list_nodes(
NetworkId="n-XXXXXXXXXXXXXXXXXXXXXXXXXX",
MemberId="m-XXXXXXXXXXXXXXXXXXXXXXXXXX"
# Status="CREATING"|"AVAILABLE"|"CREATE_FAILED"|"DELETING"|"DELETED"|"FAILED",
# MaxResults=123,
# NextToken="string"
)

print(nodes["Nodes"])

list_nodes()


> python list_nodes.py


[{'Id': 'nd-XXXXXXXXXXXXXXXXXXXXXXXXXX', 'Status': 'AVAILABLE', 'CreationDate': datetime.datetime(2019, 5, 21, 4, 4, 44, 468000, tzinfo=tzutc()), 'AvailabilityZone': 'us-east-1a', 'InstanceType': 'bc.t3.small'}]

特にハマることもなくboto3を利用してネットワーク、メンバー、ノードを作成することができました。

これで、AWS CloudFormationのカスタムリソースを利用してリソース管理することができそうです。

ただ、ネットワークとメンバー作成に20分程度かかるので、その待受処理などがAWS CloudFormationで実現できるのか、ちょっと心配です。(未調査)


参考

カスタムリソース - AWS CloudFormation

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources.html

CloudFormationで提供されていない処理をカスタムリソースで作ってみた。 | DevelopersIO

https://dev.classmethod.jp/cloud/aws/cfn-api-custom/

AWS CloudFormationでCognitoユーザープールをMFAのTOTPを有効にして作成する - Qiita

https://qiita.com/kai_kou/items/f56bb13a5d47ee05d766

boto/boto3: AWS SDK for Python

https://github.com/boto/boto3

ManagedBlockchain — Boto 3 Docs 1.9.152 documentation

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/managedblockchain.html

Amazon Managed BlockchainがリリースされたのでHyperledger Fabricも合わせて情報をまとめてみた - Qiita

https://qiita.com/kai_kou/items/5a968f42c5f96296f6fe

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita

https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e

Pipenvを使ったPython開発まとめ - Qiita

https://qiita.com/y-tsutsu/items/54c10e0b2c6b565c887a

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた - Qiita

https://qiita.com/kai_kou/items/e02e34dd9abb26219a7e#%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%A8%E3%83%A1%E3%83%B3%E3%83%90%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B