Skip to content

orionstaking/terraform-aws-chainlink-node

Repository files navigation

Chainlink Node Terraform Module

Terraform module which creates AWS serverless infra for Chainlink Node:

  • AWS Fargate
  • AWS Network Load Balancer
  • AWS Route53&ACM (optional, if enabled)
  • AWS IAM
  • AWS CloudWatch (optional, if monitoring is enabled)

Module could be used independently or together with Chainlink External Adapters module

Architecture overview

Where:

  • #DAE8FC Covered by this Chainlink Node terraform module
  • #D5E8D4 Covered by Chainlink External Adapters terraform module
  • #D0CEE2 Covered by RDS community terraform module
  • #FFE6CC Covered by VPC community terraform module

Usage

Basic example

Full example here

module "chainlink_node" {
  source  = "ChainOrion/chainlink-node/aws"

  project     = local.project
  environment = local.environment

  aws_region     = "eu-west-1"
  aws_account_id = data.aws_caller_identity.current.account_id

  vpc_id              = module.vpc.vpc_id
  vpc_cidr_block      = module.vpc.vpc_cidr_block
  vpc_private_subnets = module.vpc.private_subnets

  secrets_secret_arn = aws_secretsmanager_secret.secrets.arn

  # Always check latest versions
  node_version        = "1.12.0"
  task_cpu            = 1024
  task_memory         = 2048
  subnet_mapping      = {
    (module.vpc.azs[0]) = {
      ip            = aws_eip.chainlink_p2p[module.vpc.azs[0]].public_ip
      subnet_id     = module.vpc.public_subnets[0]
      allocation_id = aws_eip.chainlink_p2p[module.vpc.azs[0]].id
    }
    (module.vpc.azs[1]) = {
      ip            = aws_eip.chainlink_p2p[module.vpc.azs[1]].public_ip
      subnet_id     = module.vpc.public_subnets[1]
      allocation_id = aws_eip.chainlink_p2p[module.vpc.azs[1]].id
    }
  }

  route53_enabled = true
  route53_domain_name = "domain_name.com"
  route53_subdomain_name = "chainlink_eth"
  route53_zoneid = "your_zoneid"
}

Notes

Chainlink Node configuration

This module now supports only TOML configuration. See the CONFIG.md and SECRETS.md on GitHub to learn more.

Place your config.toml in the root of terraform directory. This module will parse and verify it. You will see an error in case of invalid config.toml configuration for this terraform module. Please see an example before proceed.

Additionally, it's possible to pass any environment variable to Fargate container using env_vars terraform module variable.

Check example here.

Secrets

Module is required the following AWS Secrets Manager secrets created and set:

  • Secret that contain secrets.toml (base64)
  • Secret that contain TLS_CERT (base64) (required when WebServer.TLS configuration exist in TOML config)
  • Secret that contain TLS_KEY (base64) (required when WebServer.TLS configuration exist in TOML config)

Deploy order:

  • Firstly, it's required to create and set AWS Secrets Manager objects (example)
  • Then, AWS ARN values of the created secrets should be specified in the module. (example)

Check example here.

Failover

Chainlink Node failover is realized using AnnounceAddresses in P2P.V2 in your config.toml file. Please specify the same IP's as you have in subnet_mapping terraform variable. In case of one of AWS availability zone failure, Fargate will drain node container in one az and run a new one in another based on NLB target group health checks.

This module will check provided values and you will see an error if you specified different IP addresses.

Check example with properly set subnet_mapping terraform module variable here.

TLS & HTTPS Support

Module support two types of configuration to secure UI connection

  • AWS ACM (recommended). This option requires configured Route53 hosted zone to create records for AWS NLB and AWS ACM certificate validation. Check example here.
  • Imported TLS as described here (deprecated).This option requires providing AWS Secrets Manager ARN's with self signed TLS key and certificate. Check example with imported TLS configuration here.

UI Access

By default security group connected to NLB allows only p2p connections for chainlink node.In order to access the UI it's required to add AWS security group ingress rule for required IP range or ranges. Check example here

Notifications

It's possible to specify your own AWS SNS topic for notifications. Otherwise, module will create SNS topic for notifications. Then you should manually add subscriptions to that topic.

Examples

Create AWS Secrets Manager objects first by commenting out the section with module. Then set secret values and uncomment module section in the example.

Requirements

Name Version
terraform >= 1.0.0
aws >= 4.40.0
external 2.2.3
random 3.4.3

Providers

Name Version
aws >= 4.40.0
external 2.2.3
random 3.4.3

Modules

Name Source Version
acm terraform-aws-modules/acm/aws ~> 4.0

Resources

Name Type
aws_cloudwatch_dashboard.this resource
aws_cloudwatch_log_group.this resource
aws_cloudwatch_log_metric_filter.error_node_unreachable resource
aws_cloudwatch_metric_alarm.cpu_utilization resource
aws_cloudwatch_metric_alarm.log_alarms resource
aws_cloudwatch_metric_alarm.memory_utilization resource
aws_ecs_cluster.this resource
aws_ecs_service.this resource
aws_ecs_task_definition.this resource
aws_iam_policy.this resource
aws_iam_role.this resource
aws_iam_role_policy_attachment.this resource
aws_lb.this resource
aws_lb_listener.node_v2 resource
aws_lb_listener.ui resource
aws_lb_listener.ui_secure resource
aws_lb_target_group.node_v2 resource
aws_lb_target_group.ui resource
aws_route53_record.this resource
aws_secretsmanager_secret.config resource
aws_secretsmanager_secret_version.config resource
aws_security_group.this resource
aws_security_group_rule.egress_allow_all resource
aws_security_group_rule.ingress_allow_node_v2 resource
aws_security_group_rule.ingress_allow_ui resource
aws_sns_topic.this resource
random_string.alb_prefix_node_v2 resource
random_string.alb_prefix_ui resource
aws_iam_policy_document.this data source
external_external.parse_config data source

Inputs

Name Description Type Default Required
aws_account_id AWS account id. Used to add alarms to dashboard string n/a yes
aws_region AWS Region (required for CloudWatch logs configuration) string n/a yes
config_toml Base64 encoded Chainlink node configuration from config.toml string n/a yes
env_vars Map of values that will be set as environment variables for Chainlink node process. By default it isn't required when using TOML configuration, but could be used to pass any environemnt variable to ECS task map(any) {} no
environment Environment name string "nonprod" no
monitoring_enabled Defines whether to create CloudWatch dashboard and custom metrics or not bool true no
node_image_source Chainlink node docker image source. This variable can be used to rewrite default image source. Used AWS registry by default. Set to smartcontract/chainlink to use dockerhub registry string "public.ecr.aws/chainlink/chainlink" no
node_version Chainlink node version. The latest version could be found here: https://hub.docker.com/r/smartcontract/chainlink/tags string n/a yes
project Project name string n/a yes
route53_domain_name Domain name that is used in your AWS Route53 hosted zone. Nameservers of your zone should be added to your domain registrar before creation. It will be used to create record to NLB and verify ACM certificate using DNS string "" no
route53_enabled Defines if AWS Route53 record and AWS ACM certificate for UI access should be created. Nameservers of your zone should be added to your domain registrar before creation. It will be used to create record to NLB and verify ACM certificate using DNS bool false no
route53_subdomain_name Subdomain name that will be used to create Route53 record to NLB endpoint with the following format: $var.route53_subdomain_name.$var.route53_domain_name string "" no
route53_zoneid Route53 hosted zone id. Nameservers of your zone should be added to your domain registrar before creation. It will be used to create record to NLB and verify ACM certificate using DNS string "" no
secrets_secret_arn ARN of the Secrets Manager Secret in the same AWS account and Region that contains TOML secrets for Chainlink Node (base64 encoded). See https://github.com/smartcontractkit/chainlink/blob/v1.11.0/docs/SECRETS.md on github to learn more. string n/a yes
sns_topic_arn SNS topic arn for alerts. If not specified, module will create an empty topic and provide topic arn in the output. Then it will be possible to specify required notification method for this topic string "" no
subnet_mapping A map of values required to enable failover between AZs. See an example in ./examples directory map(any) n/a yes
task_cpu Allocated CPU for chainlink node container number 2048 no
task_memory Allocated Memory for chainlink node container number 4096 no
tls_cert_secret_arn ARN of the Secrets Manager Secret in the same AWS account and Region that contains the TLS certificate (base64 encoded). Required when WebServer.TLS configuration exist in TOML config string "" no
tls_key_secret_arn ARN of the Secrets Manager Secret in the same AWS account and Region that contains the TLS key (base64 encoded). Required when WebServer.TLS configuration exist in TOML config string "" no
vpc_cidr_block The CIDR block of the VPC string n/a yes
vpc_id ID of the VPC where Chainlink EAs should be deployed string n/a yes
vpc_private_subnets VPC private subnets where Chainlink Node should be deployed (at least 2) list(any) n/a yes

Outputs

Name Description
env_vars Chainlink node configuration environment variables
nlb_endpoint NLB endpoint to accsess Chainlink Node UI. UI port is open only to the VPC CIDR block, in order to access the UI it's required to open SSH tunnel to any available host/bastion in the VPC. More info in Readme.md
nlb_security_group_id ID of security group attached to NLB. It's possible to use it to configure additional sg inbound rules
subnet_mapping A map of values required to enable failover between AZs

License

MIT License. See LICENSE for full details.

Docs update

More about terraform-docs.

terraform-docs .