Skip to content

Add a new member to an existing organization

This guide explains how to add a new validator node to an existing organization in a a R3 Corda network using two methods:

  1. Using the add-new-organization.yaml playbook: This playbook involves running an Ansible playbook that automates the process of adding a new org to the network.

  2. Using helm install: This method involves using the helm install commands to directly add a new org to the network.

Method 1: Using the add-new-organization.yaml playbook

  1. Prerequisites To add a new organization, Corda Doorman/Idman and Networkmap services should already be running. The public certificates from Doorman/Idman and Networkmap should be available and specified in the configuration file.

    Note

    Addition of a new organization has been tested on an existing network which is created by Bevel. Networks created using other methods may be suitable but this has not been tested by Bevel team.

  2. Create Configuration File

    Refer this guide for details on editing the configuration file.

    The network.yaml file should contain the specific network.organization details along with the network service information about the networkmap and doorman service.

    Note

    Make sure the doorman and networkmap service certificates are in plain text and not encoded in base64 or any other encoding scheme, along with correct paths to them mentioned in network.yaml.

    For reference, sample network.yaml file here but always check the latest network.yaml file.

    ##############################################################################################
    #  Copyright Accenture. All Rights Reserved.
    #
    #  SPDX-License-Identifier: Apache-2.0
    ##############################################################################################
    ---
    # yaml-language-server: $schema=../../../../platforms/network-schema.json
    # This is a sample configuration file for SupplyChain App on Single K8s Cluster.
    # For multiple K8s clusters, there should be multiple configuration files.
    network:
      # Network level configuration specifies the attributes required for each organization
      # to join an existing network.
      type: corda
      version: 4.9
      frontend: enabled   #Flag for frontend to enabled for nodes/peers
      #Environment section for Kubernetes setup
      env:
        type: corda         # tag for the environment. Important to run multiple flux on single cluster
        proxy: ambassador   # value has to be 'ambassador' as 'haproxy' has not been implemented for Corda
        proxy_namespace: "ambassador"
        ambassadorPorts:    # Any additional Ambassador ports can be given here, this is valid only if proxy='ambassador'
          portRange:        # For a range of ports 
            from: 15010 
            to: 15020
        # ports: 15020,15021      # For specific ports
        loadBalancerSourceRanges: '0.0.0.0/0' # comma-separated list without spaces of IP adresses for proxy='ambassador' allowed access
        retry_count: 40                 # Retry count for the checks
        external_dns: enabled           # Should be enabled if using external-dns for automatic route configuration
      # Docker registry details where images are stored. This will be used to create k8s secrets
      # Please ensure all required images are built and stored in this registry. 
      # Do not check-in docker_password.
      docker:
        url: "ghcr.io/hyperledger"
        username: "docker_username"
        password: "docker_password"
      # Remote connection information for doorman and networkmap (will be blank or removed for hosting organization)
      network_services:
        - service:
          type: doorman
          uri: https://supplychain-doorman.test.corda.blockchaincloudpoc.com
        - service:
          type: networkmap
          uri: https://supplychain-nms.test.corda.blockchaincloudpoc.com
      # Allows specification of one or many organizations that will be connecting to a network.
      # If an organization is also hosting the root of the network (e.g. doorman, membership service, etc),
      # then these services should be listed in this section as well.
      organizations:
        - organization:
          name: supplychain
          country: UK
          state: London
          location: London
          subject: "CN=DLT Root CA,OU=DLT,O=DLT,L=London,C=GB"
          type: network-service
          external_url_suffix: test.corda.blockchaincloudpoc.com
          cloud_provider: aws   # Options: aws, azure, gcp
          aws:
            access_key: "aws_access_key"        # AWS Access key, only used when cloud_provider=aws
            secret_key: "aws_secret_key"        # AWS Secret key, only used when cloud_provider=aws
          # Kubernetes cluster deployment variables. The config file path and name has to be provided in case
          # the cluster has already been created.
          k8s:
            context: "cluster_context"
            config_file: "cluster_config"
          # Hashicorp Vault server address and root-token. Vault should be unsealed.
          # Do not check-in root_token
          vault:
            url: "vault_addr"
            root_token: "vault_root_token"
            secret_path: "secretsv2"
          # Git Repo details which will be used by GitOps/Flux.
          # Do not check-in git_access_token
          gitops:
            git_protocol: "https" # Option for git over https or ssh
            git_url: "https://github.com/<username>/bevel.git"         # Gitops https or ssh url for flux value files 
            branch: "develop"           # Git branch where release is being made
            release_dir: "platforms/r3-corda/releases/dev" # Relative Path in the Git repo for flux sync per environment. 
            chart_source: "platforms/r3-corda/charts"     # Relative Path where the Helm charts are stored in Git repo
            git_repo: "github.com/<username>/bevel.git"   # Gitops git repository URL for git push 
            username: "git_username"          # Git Service user who has rights to check-in in all branches
            password: "git_access_token"          # Git Server user password/token (Optional for ssh; Required for https)
            email: "git@email.com"                # Email to use in git config
            private_key: "path_to_private_key"          # Path to private key file which has write-access to the git repo (Optional for https; Required for ssh)
    
          # Cordapps Repository details (optional if cordapps jar are store in a repository)
          cordapps:
            jars: 
            - jar:
                # e.g https://maven.pkg.github.com/hyperledger/bevel/com.supplychain.bcc.cordapp-supply-chain/4.9/cordapp-supply-chain-4.9.jar
                url: https://repo/path/cordapp1.jar
            - jar:
                # e.g https://maven.pkg.github.com/hyperledger/bevel/com.supplychain.bcc.cordapp-contracts-states/4.9/cordapp-contracts-states-4.9.jar
                url: https://repo/path/cordapp2.jar
            username: "git_username"
            password: "git_access_token"
    
          # Services maps to the pods that will be deployed on the k8s cluster
          # This sample has doorman, nms and notary on one cluster but different namespaces
          services:
            doorman:
              name: doorman
              subject: "CN=Corda Doorman CA,OU=DLT,O=DLT,L=Berlin,C=DE"
              db_subject: "C=US,ST=California,L=San Francisco,O=DB,OU=DBA,CN=mongoDB"
              type: doorman
              ports:
                servicePort: 8080
                targetPort: 8080
            nms:
              name: networkmap
              subject: "CN=Network Map,OU=FRA,O=FRA,L=Berlin,C=DE"
              db_subject: "C=US,ST=California,L=San Francisco,O=DB,OU=DBA,CN=mongoDB"
              type: networkmap
              ports:
                servicePort: 8080
                targetPort: 8080
            # Currently only supporting a single notary cluster, but may want to expand in the future
            notary:
              name: notary
              subject: "O=Notary,OU=Notary,L=London,C=GB"
              serviceName: "O=Notary Service,OU=Notary,L=London,C=GB"
              validating: true            #true - if notary is validating, false  - if notary is non-validating
              type: notary            
              p2p:
                port: 10002
                targetPort: 10002
                ambassador: 15010       #Port for ambassador service (must be from env.ambassadorPorts above)
              rpc:
                port: 10003
                targetPort: 10003
              rpcadmin:
                port: 10005
                targetPort: 10005
              dbtcp:
                port: 9101
                targetPort: 1521
              dbweb:             
                port: 8080
                targetPort: 81        
    
        # Specification for the 2nd organization. Each organization maps to a VPC and a separate k8s cluster
        - organization:
          name: manufacturer
          country: CH
          state: Zurich
          location: Zurich
          subject: "O=Manufacturer,OU=Manufacturer,L=Zurich,C=CH"
          type: node
          external_url_suffix: test.corda.blockchaincloudpoc.com
    
          cloud_provider: aws   # Options: aws, azure, gcp
          aws:
            access_key: "aws_access_key"        # AWS Access key, only used when cloud_provider=aws
            secret_key: "aws_secret_key"        # AWS Secret key, only used when cloud_provider=aws
    
          # Kubernetes cluster deployment variables. The config file path and name has to be provided in case
          # the cluster has already been created.
          k8s:
            context: "cluster_context"
            config_file: "cluster_config"
    
          # Hashicorp Vault server address and root-token. Vault should be unsealed.
          # Do not check-in root_token
          vault:
            url: "vault_addr"
            root_token: "vault_root_token"
            secret_path: "secretsv2"
    
          # Git Repo details which will be used by GitOps/Flux.
          # Do not check-in git_access_token
          gitops:
            git_protocol: "https" # Option for git over https or ssh
            git_url: "https://github.com/<username>/bevel.git"         # Gitops https or ssh url for flux value files 
            branch: "develop"           # Git branch where release is being made
            release_dir: "platforms/r3-corda/releases/dev" # Relative Path in the Git repo for flux sync per environment. 
            chart_source: "platforms/r3-corda/charts"     # Relative Path where the Helm charts are stored in Git repo
            git_repo: "github.com/<username>/bevel.git"   # Gitops git repository URL for git push 
            username: "git_username"          # Git Service user who has rights to check-in in all branches
            password: "git_access_token"          # Git Server user password/token (Optional for ssh; Required for https)
            email: "git@email.com"                # Email to use in git config
            private_key: "path_to_private_key"          # Path to private key file which has write-access to the git repo (Optional for https; Required for ssh)
    
          # Cordapps Repository details (optional if cordapps jar are store in a repository)
          cordapps:
            jars: 
            - jar:
                # e.g https://maven.pkg.github.com/hyperledger/bevel/com.supplychain.bcc.cordapp-supply-chain/4.9/cordapp-supply-chain-4.9.jar
                url: "https://repo/path/cordapp1.jar"
            - jar:
                # e.g https://maven.pkg.github.com/hyperledger/bevel/com.supplychain.bcc.cordapp-contracts-states/4.9/cordapp-contracts-states-4.9.jar
                url: "https://repo/path/cordapp2.jar"
            username: "git_username"
            password: "git_access_token"
    
          # The participating nodes are named as peers 
          services:
            peers:
            - peer:
              name: manufacturer
              subject: "O=Manufacturer,OU=Manufacturer,L=47.38/8.54/Zurich,C=CH"  # This is the node identity. L=lat/long is mandatory for supplychain sample app
              type: node
              p2p:
                port: 10002
                targetPort: 10002
                ambassador: 15010       #Port for ambassador service (must be from env.ambassadorPorts above)
              rpc:
                port: 10003
                targetPort: 10003
              rpcadmin:
                port: 10005
                targetPort: 10005
              dbtcp:
                port: 9101
                targetPort: 1521
              dbweb:             
                port: 8080
                targetPort: 81
              springboot:             # This is for the springboot server
                targetPort: 20001
                port: 20001 
              expressapi:             # This is for the express api server
                targetPort: 3000
                port: 3000
    
  3. Run playbook

    The add-new-organization.yaml playbook is used to add a new organization to the existing network. This can be done using the following command

    ansible-playbook platforms/shared/configuration/add-new-organization.yaml --extra-vars "@path-to-network.yaml"
    

    Note

    If you have CorDapps and applications, please deploy them as well.

Method 2: Using helm install

Refer this guide for details on editing the configuration file.

  1. Update the node.yaml file

    Following changes are must in the node.yaml file for a new member to be added to the network:

    • global.proxy.externalUrlSuffix
    • nodeConf.legalName
  2. Get the init and static nodes from existing member and place in corda-init/files

    cd ./corda-init/files/
    kubectl --namespace supplychain-ns get secret nms-tls-certs -o jsonpath='{.data.tls\.crt}' > nms.crt
    kubectl --namespace supplychain-ns get secret doorman-tls-certs  -o jsonpath='{.data.tls\.crt}' > doorman.crt
    
  3. Install the init-sec chart

    helm install init ./corda-init --namespace manufacturer-ns --values ./values/proxy-and-vault/init-sec.yaml
    
    helm install manufacturer ./corda-node --namespace manufacturer-ns --values ./values/proxy-and-vault/node.yaml --set nodeConf.legalName="O=Manufacturer\,OU=Manufacturer\,L=47.38/8.54/Zurich\,C=CH"