2.2.5.2. AWS MarketPlace Cloudformation 仕様

作成日:

2022/8/1

更新日:

2025/2/5

AWS MarketPlace にて提供している、 mijin Catapult(v.2) は、オーケストラレーションツールであるCloudformationにてデプロイを行なっています。
本章では、Cloudformationを使って作成されるAWSリソースの説明をします。

Cloudformation Template(CFT)の構成は複数のファイルから構成されており、親Stackが子のStackをそれぞれ呼び出しています。 親Stackのパラメータによって、呼び出される子のStackが変わります。

../../_images/cft.jpg

2.2.5.2.1. macroNestStack

macroNestStackでは、Cloudformation Macroを作成します。 パラメータ mijinStackAlreadyExistYes の場合、Macroを作成しないスタックが(empty-macro)を呼び出します。 これは、Cloudformation Macroがユニークな名前で作成するため、複数同一名で作成することができないためです。

Cloudformation MacroはLambda(Node.js)で作成されており、この後に出てくるmijinNestStackのCFTを指定パラメータによって変換します。
この作成したLambdaからAmazon CloudWatch Logsへの読み書き権限を許可をするため、以下のIAMロール及びポリシーを割り当てます。
Resources:
  PeerUnitsExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogGroup'
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource:
                  - Fn::Join:
                    - ':'
                    -
                      - 'arn:aws:logs'
                      - Ref: 'AWS::Region'
                      - Ref: 'AWS::AccountId'
                      - 'log-group:/aws/lambda/*:*:*'

Macroでは、パラメータ PeerNumberOfUnits の数に応じて、EC2インスタンスのスタックを複製し、起動するEC2インスタンスを動的に変更することができます。

警告

同一リージョンに複数の mijin Catapult(v.2) を作成する場合は、mijinStackAlreadyExistをYESにする必要があります。

2.2.5.2.2. vpcNestStack

vpcNestStackでは、新たにVPCを作成します。 マルチAZ環境を構築し、各AZにパブリックサブネット・プライベートサブネットを配置します。 また、プライベートネットワークのルーティングのデフォルトゲートウェイは同じAZにあるパブリックネットワークに配置したNat Gatewayを使用してインターネットに出ることができます。

../../_images/vpc.jpg

注釈

既存ネットワークにmijinを展開する場合は、このスタックは使いません。

2.2.5.2.3. iamNestStack

iamNestStackでは、EC2インスタンスが使用するIAMロールおよびそれに紐づくIAMポリシーを作成します。

以下は、APIノード、PEERノードそれぞれに割り当てるロールです。

AWSApiAccessRole:
  Type: 'AWS::IAM::Role'
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - ec2.amazonaws.com
          Action:
            - 'sts:AssumeRole'
    Path: /
AWSPeerAccessRole:
  Type: 'AWS::IAM::Role'
  Properties:
    AssumeRolePolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Principal:
            Service:
              - ec2.amazonaws.com
          Action:
            - 'sts:AssumeRole'
    Path: /
AWS Systems Manager Session Managerの権限を付与します。
AWS Systems Manager Session Managerでは、EC2インスタンスにIAM権限でリモートログインできるように権限を付与し、IAMロールに紐づけます。
AWSSSMRolePolicies:
  Type: 'AWS::IAM::Policy'
  Properties:
    PolicyName: AWSSSMAccessPolicy
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - 'ssm:DescribeAssociation'
            - 'ssm:GetDeployablePatchSnapshotForInstance'
            - 'ssm:GetDocument'
            - 'ssm:GetManifest'
            - 'ssm:GetParameters'
            - 'ssm:ListAssociations'
            - 'ssm:ListInstanceAssociations'
            - 'ssm:PutInventory'
            - 'ssm:PutComplianceItems'
            - 'ssm:PutConfigurePackageResult'
            - 'ssm:UpdateAssociationStatus'
            - 'ssm:UpdateInstanceAssociationStatus'
            - 'ssm:UpdateInstanceInformation'
          Resource: '*'
        - Effect: Allow
          Action:
            - 'ssmmessages:CreateControlChannel'
            - 'ssmmessages:CreateDataChannel'
            - 'ssmmessages:OpenControlChannel'
            - 'ssmmessages:OpenDataChannel'
          Resource: '*'
AWS Systems Manager パラメータストアへの読み書き権限を付与します。
AWS Systems Manager パラメータストアでは、 mijin Catapult(v.2) の最初のノードの動的生成されたデータを保存し、その他の各ノードから参照できる権限を付与し、IAMロールに紐づけます。
AWSPSAccessRolePolicies:
  Type: 'AWS::IAM::Policy'
  Properties:
    PolicyName: AWSPSAccessRole
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - 'ssm:PutParameter'
            - 'ssm:GetParameter'
            - 'ssm:GetParametersByPath'
同一アカウント同一サービス名のIAMロールのリソースからのSecurity Token Service(STS)の付与し、IAMロールを紐づけます。
STSが付与されていることで、 AWSApiAccessRole 及び AWSPeerAccessRole のIAMロールはポリシー指定したAWSサービスを操作できるようになります。
AWSAssumeAccessRolePolicies:
  Type: 'AWS::IAM::Policy'
  Properties:
    PolicyName: AWSAssumeAccessRole
    PolicyDocument:
      Version: 2012-10-17
      Statement:
        - Effect: Allow
          Action:
            - 'sts:AssumeRole'
          Resource:
            - Fn::Join:
                    - ':'
                    -
                      - 'arn:aws:iam:'
                      - Ref: 'AWS::AccountId'
                      - !Sub "role/${ServiceName}*"
    Roles:
      - !Ref AWSApiAccessRole
      - !Ref AWSPeerAccessRole

2.2.5.2.4. s3NestStack

警告

この機能は現在無効化されており、パラメーターストアのみしか保存することができません。

s3NestStackでは、mijinのデータをAWS Systems Manager パラメータストアに配置するか、S3バケットに保存するかを選択し、S3を選択した場合、S3バケットを作成します。

2.2.5.2.5. mijinNestStack

mijinNestStackでは、Route53によるプライベートDNS、セキュリティグループ、EBS、EC2インスタンスを作成します。

mijinは各EC2インスタンス間をDNS名で通信を行います。 ドメインは mijin.internal で固定になり、各インスタンス名はそれぞれ以下のように、Aレコード設定されます。

  1. api1.mijin.internal

  2. api2.mijin.internal

  3. peer1.mijin.internal

  4. peer2.mijin.internal

  5. peer3.mijin.internal

  6. peer4.mijin.internal

  7. peer5.mijin.internal

  8. peer6.mijin.internal

  9. peer7.mijin.internal

  10. peer8.mijin.internal

  11. peer9.mijin.internal

セキュリティグループは以下、画像のように最低限の通信に使用するセキュリティグループが適用されます。

セキュリティグループ名

説明

attach-ssm_ssh-client

このセキュリティグループは踏み台など設定することで、SSHログインが可能になります。新規VPCでは使用しません。(既存VPC用で作成した場合、既存の踏み台に割り当てるなど)

attach-node-client

ノード間通信用です。

sv-api

APIノード用です。
3000ポート / RESTアクセス用です
7900 / mijinノード通信用です。

sv-peer

PEERノード用です。
7900ポート / mijinノード通信用です。
../../_images/sg_network.jpg
EBSはmijinのデータ領域を保存するため、APIノードでは、rootパーティション以外に2つのEBS、PEERノードでは、一つのEBSをアタッチしています。
VolumeTypeは`GP3`固定であり、ディスクの暗号化はしていません。
EC2インスタンス初回構築時のみ、cloud-initを使って、EBSをXFSフォーマットし、ディスクマウントするように設計されています。
mijinデータは`block`に保存されます。APIノードでは、block`とrestで使用する `mongo`のデータを保存しますが、 `block にあるデータがあれば、mongo データを復元することができます。
../../_images/ebs.jpg

EC2インスタンスは、mijinパッケージがインストールされたカスタムAMIを使用し起動します。 UserDataにて、cloud-initを動作し、初期パッケージの設定を実行します。 UserDataの実行結果を受け取り、設定に失敗するとロールバックするように動作します。

  1. パラメータで指定したUnixユーザーの設定

  2. ホスト名の設定

  3. OSパッケージの更新

  4. pipのインストール

  5. cloudformation helper scriptのインストール

  6. mijinのセットアップ
    1. EBSフォーマット

    2. mijinセットアップ(api1はパラメータストアにデータをアップ)

また、インスタンスを作成する順序としては、以下のようになります。
  1. ApiInstance1

  2. ApiInstance2 PeerInstanceX 並行実行

ApiInstance1にて、すべてのノードに使用する設定を作成し、AWS Systems Manager パラメータストアにデータを保存します。その他インスタンスはこのパラメータストアからデータを取得し、mijinを作成します。
パラメーターストアに保存される内容は、以下となります。

パラメータ名

説明

/デプロイ時に指定した冠名/shares/api_node.json

APIノードが使用する公開鍵

/デプロイ時に指定した冠名/shares/generation_hash.json

mijin Catapult(v.2) のブロックチェーンのジェネシスハッシュ(GenerationHash)

/デプロイ時に指定した冠名/shares/harvest_fee_sink_public_key.json

Harvestを受け取るアドレス(mijinでは不要)

/デプロイ時に指定した冠名/shares/init_host_count.json

デプロイ時に作成したノード数

/デプロイ時に指定した冠名/shares/mosaic_rental_fee_sink_public_key.json

Mosaicレンタル費用を受け取るアドレス

/デプロイ時に指定した冠名/shares/namespace_rental_fee_sink_public_key.json

Namespaceレンタル費用を受け取るアドレス

/デプロイ時に指定した冠名/shares/nemesis_addresses.json

とくに使用されてない空のアドレス(使用可能)

/デプロイ時に指定した冠名/shares/nemesis_addresses_harvesting.json

harvestなどを受け取るアドレス

/デプロイ時に指定した冠名/shares/nemesis_addresses_harvesting_voting.json

ファイナライズの権限に使用するアドレス

/デプロイ時に指定した冠名/shares/nemesis_addresses_harvesting_vrf.json

セキュリティ強化用のアドレス(ブロック生成できる状態をわからなくする)

/デプロイ時に指定した冠名/shares/peer_node.json

PEERノードが使用する公開鍵

/デプロイ時に指定した冠名/shares/rest_gateway_private_key.json

APIノードが使用するREST用のアドレス

/デプロイ時に指定した冠名/shares/signer_private_key.json

Nemesis(Genesis)ブロックを署名するアドレス

/デプロイ時に指定した冠名/shares/new-cert/各ノード/CA/[*].pem

ノード間の通信を暗号化するSSL証明書

注釈

このパラメータストアの値はブロックチェーンの1ブロック目に作成する値として保存され、デプロイ以降、パラメータストアから呼び出すことはありません。
そのため、セキュリティとしてデータを削除しておきたいなどがある場合、このデータを削除しても問題ありません。
また、障害や新規に増設したいなどがある場合などは、このデータから復旧することができます。

2.2.5.2.6. loadbalanceNestStack

loadbalanceNestStackでは、ELB(ロードバランサー)を作成します。
パラメータ UseLoadBalancerNo の場合はELBを作成しないスタック(empty-elb)を呼び出します。
ELBは、APIノードのRESTアクセスポート`3000`ポートへ分散します。
ELBのTypeはNLB(ネットワークロードバランサー)を使用し、APIノードへの接続はスティッキーセッションにより同一セッションは一定期間、同じノードを使用する設定となっています。

注釈

ELBはNetwork Load Balancer(NLB)のみで作成します。
NLBについて理解したい場合は、以下を参照してください。
TargetGroupAttributes:
  - Key: stickiness.enabled
    Value: 'true'

NLBは、プライベートのみで使用する内向き用の配置、インターネット経由で接続する外向き用の配置をパラメータで指定することができます。

../../_images/elb.jpg
APIノードのRESTアクセスポート`3000`ポートへは以下のような条件でヘルスチェックをおこなっています。
ヘルスチェックは http://APIノード:3000/chain/info を死活監視しています。
Properties:
  HealthCheckIntervalSeconds: 10 # 10秒間隔でチェックする Check at 10-second intervals.
  UnhealthyThresholdCount: 3 # 異常とみなす回数 Number of times considered abnormal
  HealthyThresholdCount: 3 # 正常とみなす回数 Number of times considered normal
  HealthCheckPath: /chain/info # ヘルスチェックをするURL URL for health check
  HealthCheckProtocol: HTTP
  Port: 3000 # ヘルスチェックポート health check port