Testnet Deployment
This article shares the manifests and other yaml configurations which we have put together for the automated deployment of our testnet (Relay Chain + Parachain). If you are interested to find out more about our journey towards cutting-edge automated deployment using Kubernetes, together with the technical decisions we had to make on the way, please check out this blog post.
#
Technologies used- Kubernetes - we run it in the cloud (AWS Fargate), mainly for convenience reasons. However, you can adapt the yaml manifests to spin up your own K8s cluster.
- Terraform - because we like having our infra as code.
- GitHub Actions - for CI/CD.
#
Cluster configurationSince we decided to run our Kubernetes cluster in the cloud with AWS Fargate, we can use the following yaml manifest for the cluster configuration:
Once we have this sorted out, it is time to create and apply the Kubernetes objects needed for the Relay Chain and the Parachain.
#
Relay ChainFirst is Alice. We will create 3 types of objects: a Deployment, a Service and an Ingress object.
#
DeploymentIn this manifest, we choose the name of our node, the ports to expose, the command and its arguments, as well as the number of replicas. This parameter is important as we only want one replica per node in order to avoid sync issues. Note that you can have as many nodes as necessary.
#
ServiceWe use the Service object in Kubernetes for at least two purposes here:
- In the first place, we want to allow nodes to communicate with each other (please check this link for more info).
- In the second place, we will be able to expose the service to the outside world using an Ingress object as described in the following step.
Please note that if you wish to expose the service to the outside world, the selector
parameter has a crucial role.
#
IngressThe Ingress object exposes our service to the outside world (in our case using the host address relaychain.hydration.cloud
). For this purpose, we are using the ALB Controller Service of AWS (more information here).
The parameters of the Ingress object are pretty much basic, and can largely be kept as-is (more info here). The most important value to adjust is the one of alb.ingress.kubernetes.io/certificate-arn
, which is the identifier of the ACM Certificate you get when you create an entry in ACM for your host
. More details on this later on.
#
ParachainAfter Alice is all set up, it is now time to take care of Bob. Also here, we will be creating the same types of objects: a Deployment for the collator, the necessary Services and an Ingress object.
#
Deployment (collator)#
Service#
Public RPCIn the cases of Bob, we also want to expose port 9944
which is used for RPC connections to the node.
#
IngressThe Ingress manifest for Bob is the same as the one for Alice above.
#
ACM and Route53If you need to expose your node to the outside world with a nice and secure URL, you can use AWS ACM. Basically, all you need to do is to create a certificate with the name of your URL, validate it (via DNS) and get the result ARN. Then add it as a value of the alb.ingress.kubernetes.io/certificate-arn
parameter in your Ingress Manifest file, and voilà!
#
Terraform for Automated ProvisioningOf course, the creation of your certificate can be done through Terraform in case you want to automate it in your CI (we didn't make this choice yet, but we still might do so in the future). For some inspiration you can take a look at the .tf
file below:
The output value of this TF is the ARN to be used in your Ingress
manifest file.
#
Github ActionsAfter having the manifests ready, it is time to bring everything together and deploy the defined Kubernetes objects. Instead of using kubectl apply
, we decided to integrate it in a CI/CD pipeline. We use Github Actions, and it's pretty straight-forward:
This workflow creates the AWS Fargate profile after which it deploys the manifest file containing all your Kubernetes objects to the chosen Cluster. Don't forget to provide the correct access and secret keys :)
Good luck and hit us up on Discord if you have any questions!