cardano_node
Cardano Node Role
Installs Cardano Node as a systemd service on Ubuntus and Debians. Then wraps it with Ansible tortilla to make certain ops controllable, idempotent and way simpler in general.
Can add and integrate CNCLI when directed to.
Supported Distros
Adoption and support of more distributions will greatly depend on the users' feedback.
Please add your use cases to the issue tracker and we will triage those as we go.
Ubuntu
- 20.04
- 18.04
Debian
- bullseye
Installation
one of:
ansible-galaxy install grzegorznowak.cardano_node
- clone the repo directly
Example playbook
There are 2 main modes of installation:
- Compilation from source
- Using pre-built dist binaries from IOHK
controllable with the cardano_install_method
flag.
See the Configuration
section further down.
Binary dist install should generally fit most of the cases, but go ahead and use src to unlock the ultimate nerd-build.
This role attempts to test both of the approaches.
When cloned from github
- name: Converge Cardano Node
hosts: all
vars:
cncli_add: true # will include CNCLI
cardano_wallets: # will create two wallets for you
- savings
- operations
roles:
- cardano-node-role
When installed with ansible-galaxy
- name: Converge Cardano Node
hosts: all
vars:
cncli_add: true # will include CNCLI
cardano_wallets: # will create two wallets for you
- savings
- operations
roles:
- grzegorznowak.cardano_node
Configuration & Usage
By default installs cardano for a cardano
user and group. Which is a recommended practice.
All other cogs to fiddle with can be found under defaults/main.yml
.
More detailed usage examples and copy-pasteable commands will be arriving with subsequent sprints.
NFT Tokens
Idempotently mint native NFT tokens with this role. I will not re-attempt to mint the token if it's already present and in the wanted quantity.
At this point minted tokens are sent to the address we used for minting.
Minimal config needed on mainnet:
cardano_install_method: dist
active_network: main
cardano_wallets:
- &wallet_default default
cardano_nfts:
- slug: BurningGiraffe
description: Burning Giraffe
image: "" # an IPFS hash of the NFT
name: Burning Giraffe
id: 1
# how many slots to reserve for this NFT's policy metadata to be editable:
open_period: 1000000
quantity: 10
wallet: *wallet_default
Native Tokens
Idempotently mint native tokens (not NFTs) with this role. I will not re-attempt to mint the token if it's already present and in the wanted quantity.
At this point minted tokens are sent to the address we used for minting.
Minimal config needed on mainnet:
cardano_install_method: dist
active_network: main
cardano_wallets:
- &wallet_default default
cardano_assets:
- name: MyAsset
quantity: 1000000
wallet: *wallet_default
Payment Addresses
We can keep track of ADA addresses at our disposal.
NOTE: This role doesn't (yet) integrate any sort of wallet software. What we do is create needed files to send and receive payments using cli commands. "Wallet" in this context means a named path that holds files belonging together
The current approach is to only create wallets that do not exist, as well as report if it finds ones that are broken - ie. missing private keys. For security reasons we will not try to delete existing wallets, even though this stands opposite to the ansible philosophy of defining and converging to specified state of the system.
# populate with a list wallet names you wish to track with the role
cardano_wallets:
- savings
- operations
Based on the sample above - assuming all default values are used - materialized wallet addresses will be located under:
/home/cardano/wallets/savings/payment.addr
/home/cardano/wallets/operations/payment.addr
alongside wallets' private keys
Node Sync Status Assertion
Block execution of a playbook until cardano node is fully synced.
- name: Wait until we are fully synced
assert_cardano_synced:
cardano_node_socket: "{{ cardano_node_socket }}"
cardano_bin_path: "{{ cardano_bin_path }}"
active_network: "{{ active_network }}"
testnet_magic: "{{ network_magic }}" # only used on testnet
retries: 60
delay: 240 # wait up to 4h for full sync
become: true
become_user: "{{ cardano_user }}"
register: sync_check_result
until: sync_check_result.progress | int == 100
Funds Assertion
Make sure the specific address has at least the given amount of Ada at it's disposal. Useful for monitoring a service that has to have some Ada all times, or blocking specific Ops that require certain amounts to be available.
- set_fact
wallet_to_check: default
lovelace_needed: 1000000000
- name: Collect wallets
cardano_wallet:
cardano_bin_path: "{{ cardano_bin_path }}"
name: "{{ wallet_to_check }}"
active_network: "{{ active_network }}"
testnet_magic: "{{ network_magic }}" # only used on testnet
become: true
become_user: "{{ cardano_user }}"
register: wallet_results
- name: Make sure we have some Lovelace
assert_address_funded:
cardano_node_socket: "{{ cardano_node_socket }}"
cardano_bin_path: "{{ cardano_bin_path }}"
active_network: "{{ active_network }}"
testnet_magic: "{{ network_magic }}" # only used on testnet
expected_lovelace: "{{ lovelace_needed }}"
address: "{{ wallet_results['wallets_addresses'][wallet_to_check] }}"
retries: 60
delay: 240 # wait up to 4h for full sync
become: true
become_user: "{{ cardano_user }}"
register: lovelace_result
until: lovelace_result.lovelace | int > lovelace_needed
General Settings
# Cardano user
cardano_user: cardano
cardano_group: cardano
cardano_home_directory: "/home/{{ cardano_user }}"
# possible options:
# src - compile from source
# dist - use the official binary
cardano_install_method: dist
# Version variables
ghc_version: 8.10.4
cabal_version: 3.4.0.0
# Applicable only when building from src
cardano_node_version: 1.33.0
# Applicable only when installing from dist
cardano_hydra_build: 9941151
# always confirm your sha, or a poison might be coming
cardano_dist_sha_256: eb7fbc652f79bcb8f56699ed7fee174a4ed321307c7086838d44972136795543
cardano_dist_url: "https://hydra.iohk.io/build/{{ cardano_hydra_build }}/download/1"
# Service Config
cardano_listen_addr: 127.0.0.1
cardano_listen_port: 22322 # has to be in the upper bracket if it's running as non-privileged user
# CNCLI config
cncli_add: false # set to 'true' to enable cncli with cncli-sync service
There's more, so head on to the defaults/main.yml
file directly to see all the little details.
Cardano CLI
One of the end goals of this repository is to abstract cardano Ops with ansible tasks, but there is no stopping you to interact with services and binaries directly.
su cardano
cd ~/bin
./cardano-cli --help
For usage details go to cardano-cli documentation directly
CNCLI
For usage details see the original repository
Managing Services
Use it as any other service
# managing the cardano-node process:
systemctl status cardano-node
systemctl restart cardano-node
# looking at general logs
journalctl -u cardano-node
Interacting with CNCLI sync service, when it's enabled
# managing the cncli-sync process
systemctl status cncli-sync
systemctl restart cncli-sync
# looking at general logs
journalctl -u cncli-sync
Integration Testing
locally on LXD
LXD should already be installed and configured.
Trigger the full suite with ./test-local.sh
Compilation of the required binaries is a CPU heavy task, so be prepared for a long-haul process.
on Cloud via CI pipeline
CI built on top of DO infrastructure and getting triggered against every meaningful changeset in the main
branch.
To limit running costs the from-source CI done against Focal Fossa only atm.
The pre-built binary CI done against focal and bionic.
The other supported platforms are being assessed locally.
Motivation
This role is a rolling exploration of cardano backend and services' configuration, with functionality that will grow over time as we understand the search-space better.
Brewed using high TDD and coding standards, making sure changes don't break any of the existing components.
Remember to always ask for tests when ordering your ansible pizza.
When should I use this role over the official docker image ?
First of all docker is a great tool that I leverage in my projects a tonne to provide consistent images for concrete tasks. The specificity of docker comes with a price and that is it's not fun when it comes to networking or systemd. On it's own it can't really do any of those things full-on and thus behold kubernetes, docker-swarms et al. Which is perfectly fine until you need to actually do a bespoke setup with mesh VPN or live services monitoring - you start adding layer after layer of complexity to the system only to solve problems that docker itself brought; with lots dependencies that are not easy to deploy with infra-as-code principle.
If I learnt anything over the years in development, is that there is truly no solution that fits it all. At some point when a production grade platform is considered, trying to shoe hone docker into the frames of correctly defined and controlled environment is just much more work than compiling a well understood and minimal set of roles that provide specific value.
If you're not developing the system with docker first approach, which I personally find really a roundabout fashion eventually, then you might enjoy this role. With an added value of being perfectly transparent; so you're never worried what your docker image comes with prepackaged other than what it claims.
Initial tests were conducted using lxd containers, which are flyweight, fast and native to ubuntu, and can simulate actual servers on a level that docker really can't.
Noteworthy
Thanks to Molecule we're currently in the era of test-driven-infra-as-code. Which this project is a manifestation of too. So please head on to https://github.com/ansible-community/molecule and give it some love and attention.
Target audience
Developers and Ops
Roadmap
The project is rolled with weekly sprints. Have a look there to see what's currently being worked on.
The very broad 10k feet view of what is planned generally:
A baseline Cardano Node installationFull CI/CDIntegrate CNCLIAutomate native tokens mintingAutomate NFT minting- Smart contracts' interfacing
- More/better provisioning examples
- Exposition of what would be the result of running this role as a public node
Automation of keys management
Some food for thought, but not really in plans as of now:
- Research the possibility of Block Producing Node to be ephemeral
- Complete staking pool implementation
the above is subject to change or can be refactored into bespoke roles for modularity.
Cardano node for Debians and Ubuntus wrapped with Ops to simplify the most common use cases, like payment address creation, sync status checks, held Ada balance assertions and more being added. Developed using tests-first approach for unmatched stability.
ansible-galaxy install grzegorznowak/cardano-node-role