deploy-node-network.yml 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. name: Deploy Network
  2. on:
  3. workflow_dispatch:
  4. inputs:
  5. jsonInput:
  6. description: 'Json input (refer to .pipelines/deploy-node-network-inputs.json)'
  7. required: true
  8. default: ''
  9. defaults:
  10. run:
  11. working-directory: devops/aws
  12. jobs:
  13. deploy-node-network:
  14. name: Create CloudFormation stack and run Ansible playbook
  15. runs-on: ubuntu-latest
  16. env:
  17. STACK_NAME: ga-deploy-node-network-${{ github.run_number }}
  18. steps:
  19. - name: Checkout
  20. uses: actions/checkout@v2
  21. - name: Set env variables
  22. id: myoutputs # set the outputs
  23. run: |
  24. jsonInput=$(jq -r '.inputs.jsonInput' $GITHUB_EVENT_PATH)
  25. export ENCRYPTION_KEY=$(echo $jsonInput | jq -r '.encryptionKey.value')
  26. echo ::set-output name=encryptionKey::$ENCRYPTION_KEY
  27. echo "::add-mask::$ENCRYPTION_KEY"
  28. echo ::set-output name=gitRepo::$(echo $jsonInput | jq -r '.gitRepo.value')
  29. echo ::set-output name=branchName::$(echo $jsonInput | jq -r '.branchName.value')
  30. echo ::set-output name=keyName::$(echo $jsonInput | jq -r '.keyName.value')
  31. echo ::set-output name=numberOfValidators::$(echo $jsonInput | jq -r '.numberOfValidators.value')
  32. echo ::set-output name=validatorInstanceType::$(echo $jsonInput | jq -r '.validatorInstanceType.value')
  33. echo ::set-output name=buildInstanceType::$(echo $jsonInput | jq -r '.buildInstanceType.value')
  34. echo ::set-output name=rpcInstanceType::$(echo $jsonInput | jq -r '.rpcInstanceType.value')
  35. echo ::set-output name=ec2AMI::$(echo $jsonInput | jq -r '.ec2AMI.value')
  36. echo ::set-output name=networkSuffix::$(echo $jsonInput | jq -r '.networkSuffix.value')
  37. echo ::set-output name=deploymentType::$(echo $jsonInput | jq -r '.deploymentType.value')
  38. echo ::set-output name=volumeSize::$(echo $jsonInput | jq -r '.volumeSize.value')
  39. echo ::set-output name=rpcVolumeSize::$(echo $jsonInput | jq -r '.rpcVolumeSize.value')
  40. echo ::set-output name=skipChainSetup::$(echo $jsonInput | jq -r '.skipChainSetup.value')
  41. initialBalancesFile=$(echo $jsonInput | jq -r '.initialBalancesFile.value')
  42. initialMembersFile=$(echo $jsonInput | jq -r '.initialMembersFile.value')
  43. proposalParametersInput=$(echo $jsonInput | jq -r '.proposalParameters.value')
  44. if [ $proposalParametersInput = "{}" ]
  45. then
  46. echo ::set-output name=proposalParameters::''
  47. else
  48. echo ::set-output name=proposalParameters::$proposalParametersInput
  49. fi
  50. if [ -z "$initialBalancesFile" ]
  51. then
  52. echo ::set-output name=initialBalancesFilePath::''
  53. else
  54. wget $initialBalancesFile -O initial-balances.json
  55. echo ::set-output name=initialBalancesFilePath::'initial-balances.json'
  56. fi
  57. if [ -z "$initialMembersFile" ]
  58. then
  59. echo ::set-output name=initialMembersFilePath::''
  60. else
  61. wget $initialMembersFile -O initial-members.json
  62. echo ::set-output name=initialMembersFilePath::'initial-members.json'
  63. fi
  64. - name: Install Ansible dependencies
  65. run: pipx inject ansible-core boto3 botocore
  66. - name: Configure AWS credentials
  67. uses: aws-actions/configure-aws-credentials@v1
  68. with:
  69. aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
  70. aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  71. aws-region: us-east-1
  72. - name: Check if CloudFormation stack exists
  73. id: stack_exists
  74. run: |
  75. if aws cloudformation describe-stacks --stack-name ${{ env.STACK_NAME }} >/dev/null 2>/dev/null; then
  76. echo "Stack already exists"
  77. exit 1
  78. else
  79. echo "Stack does not exist"
  80. fi
  81. - name: Deploy to AWS CloudFormation
  82. uses: aws-actions/aws-cloudformation-github-deploy@v1
  83. id: deploy_stack
  84. with:
  85. name: ${{ env.STACK_NAME }}
  86. template: devops/aws/cloudformation/infrastructure.yml
  87. no-fail-on-empty-changeset: '1'
  88. parameter-overrides: >-
  89. KeyName=${{ steps.myoutputs.outputs.keyName }},
  90. ValidatorEC2InstanceType=${{ steps.myoutputs.outputs.validatorInstanceType }},
  91. RPCEC2InstanceType=${{ steps.myoutputs.outputs.rpcInstanceType }},
  92. BuildEC2InstanceType=${{ steps.myoutputs.outputs.buildInstanceType }},
  93. EC2AMI=${{ steps.myoutputs.outputs.ec2AMI }},
  94. NumberOfValidators=${{ steps.myoutputs.outputs.numberOfValidators }},
  95. VolumeSize=${{ steps.myoutputs.outputs.volumeSize }},
  96. RPCVolumeSize=${{ steps.myoutputs.outputs.rpcVolumeSize }}
  97. - name: Prepare inventory for Ansible
  98. run: |
  99. ASG=${{ steps.deploy_stack.outputs.AutoScalingId }}
  100. VALIDATORS=""
  101. INSTANCES=$(aws autoscaling describe-auto-scaling-instances \
  102. --query "AutoScalingInstances[?AutoScalingGroupName=='${ASG}'].InstanceId" --output text);
  103. for ID in $INSTANCES
  104. do
  105. IP=$(aws ec2 describe-instances --instance-ids $ID --query "Reservations[].Instances[].PublicIpAddress" --output text)
  106. VALIDATORS+="$IP\n"
  107. done
  108. echo -e "[build]\n${{ steps.deploy_stack.outputs.BuildPublicIp }}\n" >> inventory
  109. echo -e "[validators]\n$VALIDATORS" >> inventory
  110. echo -e "[rpc]\n${{ steps.deploy_stack.outputs.RPCPublicIp }}" >> inventory
  111. cat inventory
  112. - name: Run playbook to compile joystream-node on build server
  113. uses: dawidd6/action-ansible-playbook@v2
  114. # Build binaries if AMI not specified or a custom proposals parameter is passed
  115. if: steps.myoutputs.outputs.ec2AMI == '' || steps.myoutputs.outputs.proposalParameters != ''
  116. with:
  117. playbook: build-code.yml
  118. directory: devops/aws
  119. requirements: requirements.yml
  120. key: ${{ secrets.SSH_PRIVATE_KEY }}
  121. options: |
  122. --inventory inventory
  123. --extra-vars "branch_name=${{ steps.myoutputs.outputs.branchName }} \
  124. git_repo=${{ steps.myoutputs.outputs.gitRepo }} data_path=mydata \
  125. proposal_parameters=${{ steps.myoutputs.outputs.proposalParameters }}"
  126. - name: Run playbook to install additional utils on build server
  127. uses: dawidd6/action-ansible-playbook@v2
  128. if: steps.myoutputs.outputs.ec2AMI == ''
  129. with:
  130. playbook: setup-build-server.yml
  131. directory: devops/aws
  132. requirements: requirements.yml
  133. key: ${{ secrets.SSH_PRIVATE_KEY }}
  134. options: |
  135. --inventory inventory
  136. - name: Run playbook to configure chain-spec
  137. uses: dawidd6/action-ansible-playbook@v2
  138. with:
  139. playbook: configure-network.yml
  140. directory: devops/aws
  141. requirements: requirements.yml
  142. key: ${{ secrets.SSH_PRIVATE_KEY }}
  143. options: |
  144. --inventory inventory
  145. --extra-vars "network_suffix=${{ steps.myoutputs.outputs.networkSuffix }} data_path=mydata \
  146. number_of_validators=${{ steps.myoutputs.outputs.numberOfValidators }} \
  147. git_repo=${{ steps.myoutputs.outputs.gitRepo }} \
  148. deployment_type=${{ steps.myoutputs.outputs.deploymentType }} \
  149. branch_name=${{ steps.myoutputs.outputs.branchName }} \
  150. initial_members_file=${{ steps.myoutputs.outputs.initialMembersFilePath }} \
  151. initial_balances_file=${{ steps.myoutputs.outputs.initialBalancesFilePath }} \
  152. skip_chain_setup=${{ steps.myoutputs.outputs.skipChainSetup }}"
  153. - name: Terminate Build instance
  154. continue-on-error: true
  155. run: |
  156. echo "Deleting build instance with id ${{ steps.deploy_stack.outputs.BuildInstanceId }}"
  157. aws ec2 terminate-instances --instance-ids ${{ steps.deploy_stack.outputs.BuildInstanceId }}
  158. - name: Encrpyt the artifacts
  159. run: |
  160. 7z a -p${{ steps.myoutputs.outputs.encryptionKey }} chain-data.7z mydata/*
  161. - name: Save the output as an artifact
  162. uses: actions/upload-artifact@v2
  163. with:
  164. name: data-chainspec-auth
  165. path: devops/aws/chain-data.7z
  166. - name: Save the endpoints file as an artifact
  167. uses: actions/upload-artifact@v2
  168. with:
  169. name: endpoints
  170. path: devops/aws/endpoints.json
  171. - name: Delete CloudFormation Stack if any step failed
  172. # Skip only if stack already existed or all steps passed succesfully
  173. if: ( failure() || cancelled() ) && steps.stack_exists.outcome != 'failure'
  174. run: |
  175. echo "Deleting ${{ env.STACK_NAME }} stack"
  176. aws cloudformation delete-stack --stack-name ${{ env.STACK_NAME }}
  177. echo "Waiting for ${{ env.STACK_NAME }} to be deleted..."
  178. aws cloudformation wait stack-delete-complete --stack-name ${{ env.STACK_NAME }}