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://cloudpack.media/44573

Amazon Managed Blockchainってなんぞ?

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

Amazon Managed BlockchainがリリースされたのでHyperledger Fabricも合わせて情報をまとめてみた – Qiita
https://cloudpack.media/46950

前提

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

  • AWSアカウントがある
  • AWSアカウントに以下の作成権限がある
    • Managed Blockchainネットワーク
  • AWS CLIのaws configure コマンドでアカウント設定済み

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

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた – Qiita
https://cloudpack.media/46963

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://cloudpack.media/46963

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()
> pyhton 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()
> pyhton 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://cloudpack.media/44573

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://cloudpack.media/46950

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた – Qiita
https://cloudpack.media/46963

Pipenvを使ったPython開発まとめ – Qiita
https://qiita.com/y-tsutsu/items/54c10e0b2c6b565c887a

Amazon Managed BlockchainでHyperledger Fabricのブロックチェーンネットワークを構築してみた – Qiita
https://cloudpack.media/46963

元記事はこちら

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