n8n - henk52/knowledgesharing GitHub Wiki

n8n

Introduction

Purpose

Describe how to install, operate and use n8n.

n8n - building automated command flows.

References

Vocabulary

  • n8n - nodemation

Overview

  • n8n enables you to create automated process flows using pre-made modules, with and without AI.
  • There are a lot of pre-made modules,
    • providing access to a number of services, like slack, gitlab, Jira etc.
    • There are also data handling modules, for transformation, filtering etc.
  • It will cost 800,-€ per month, for a self-hosted solutions. see n8n pricing
  • For testing; You need to register to get an activation key for you local instance.

TL;DR

  • This seems like a fast way to prototype
    • When there are pre-written nodes(code blocks) it is simply add-and-configure
    • It is easy to connect nodes together to set up work flows.
    • Some of the workflows might be more secure/maintainable if moved to lambda functions.
  • It might be possible to write you own nodes.
  • The language used in the nodes seems to be javascript.
  • It is easy to tie in LLM operations.
  • Opportunities
    • AWS: Cert mgr, DynamoDB, ELK, IAM, Lambda, S3, SES, SNS, SQS
    • command shell
    • Elasticsearch
    • GitLab (not full API, but the rest can be done via the generic node: HTTP Request)
    • Google: Analytics, Calendar, Contacts, Docs, Drive, Sheets, Slides, Tasks
    • Grafana: limited? (TODO investigate what it can do)
    • Jira
    • Kibana
    • Npm
    • Postgres
    • RSS Read
    • SSH
    • UptimeRobot

Usage of n8n

  • Who could benefit from n8n?
    • Generally people with some understanding of coding.
  • What could n8n be used for?
    • Slack automation
      • annotation of alerts
      • work as a support bot
      • scraping channels and generate statistics
    • gitlab MR automation
      • test renovate MRs (see below)
      • review MRs
    • e-mail organization
    • Jira automation

Challenges to using n8n

  • for some reviewing the UI could be a challenge, since you have to look inside each node to understand what is going on.
  • With the 'Business' version you get git version control, so that might alleviate this issue.
  • Security needs some effort, to ensure there is still control over who is allowed to do what, and that it is possible to trace who did what.

Alternative to n8n

  • make.io
    • It seems to solve the same sort of issues
    • One youtuber showed that n8n has a lot more adoption and that n8n adoption is growing faster that make.io

TODO

  • webhooks
    • Investigate if webhook messages are authorized before processesing?
      • run tcpdump
      • try to create and send a fake message on behalf of slack
  • commands in slack /n8n
    • send it to a single flow that will then call a sub-flow depending on the command given, e.g. /n8n help
  • get notifications each time an alert comes in on a slack channel
  • store postgresql on an ebs that can be backed up
  • backup and restore flows
  • figure out the danger thingy in chrome
  • bedrock integration

Subjects to test

  • slack access
    • post message
    • respond to requests
    • anotate alerts
  • gitlab access
    • test out renovate bot things, to find the MRs that can just be merged.
  • elasticsearch access
    • LLM analysis on logs
      • only look at the message to keep the token cost down.
  • grafana access
    • ?
    • act on high RDS IOPS
      • run investigations, possibly via an iam role?
        • is vacuum running etc
  • cloudwatch access
  • run aws commands

Installing n8n

Installing n8n in a Local docker version

Installing n8n in aws

TODO how to handle security issues.

configure access for n8n

Certificates

configure Access to AWS bedrock

Securely connect Amazon Bedrock to n8n

Create an IAM user with access to bedrock

  • Create Access key
    • Third party service
    • Copy out the access key and secret key.
    • click done
  • Create credential on n8n
    • click Credential tab on the main page.
    • Click ‘Create credential’ button in top right corner
    • Search for AWS(IAM)
    • click create
      • Region: eu-west-1
      • Access Key ID: from above
      • Secret Access Key: from above
      • Click Save
        • it should show ‘Connection tested successfully’ a moment later.
      • click the 'X' to close.

configure Access to slack

How to Connect Slack to n8n (2025) (Step-by-Step)

Create the slack app for n8n(I think this is on slack)

  • go to the Slack api page
  • Create the app
  • Copy the Bot User OAuth Token
  • Access Token: paste the token in that field
  • Signature Secret:
  • Auths needed
    • chat:write
      • must be invited to the channel.

Create credential for n8n slack

  • Configure the slack connection in n8n
    • click the ‘Credential’ tab on the front page
      • or '+' in the upper left, if no workflows have been created.
    • click ‘Create credential’ in the top right corner.
    • Find the ‘Slack API’ and click continue
    • Access Token
      • In the n8n slack app find the ‘Bot User OAuth Token' and copy that into the 'Access Token’ field
        • Under Settings -> Install App (in the left column of the slack app page)
          • Bot User OAuth Token
    • Signature Secret
      • from slack: Settings -> Basic Infromation (in the left column of the slack app page)
        • Signing Secret
    • Click ‘Save’
    • Click 'x' to close the credentials window.

Configure slack event subscription

TODO 'Slash Commands' TODO each slash command has its own URL I wonder how that works since only one url can be verified? TODO how can I verify that it is a valid slack package that is recieved?

  • url_verification event

  • Developer changelog

  • Allow slack webhooks

    • Slack uses IP ranges managed by Amazon Web Services (AWS), as Slack is hosted on AWS. However, Slack does not publish a dedicated or fixed list of IP addresses for its services. Here’s what you should know:
      1. AWS IP ranges: Slack traffic can originate from any of the IP ranges used by AWS. You can find the full list here https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html https://ip-ranges.amazonaws.com/ip-ranges.json
      1. AWS documentation: To filter specifically for IPs used in Slack’s regions (e.g. us-east-1, ap-south-1), you can parse the JSON using service: AMAZON or service: CLOUDFRONT.
      1. Slack does not support static IP allowlisting: Because we use dynamic cloud infrastructure, IPs can change. So Slack doesn’t support allowlisting or firewall configurations based on fixed IPs.
cat << 'EOF' > generate_ips.sh
#!/bin/bash

echo 'variable "n8n_slack_src_ips_eu_west_1" {'
echo '  type    = list(string)'
echo '  default = ['

curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | \
  jq -r '.prefixes[] | select(.region == "eu-west-1") | .ip_prefix' | \
  awk '{print "    \"" $1 "\","}'

echo '  ]'
echo '}'
EOF

chmod +x generate_ips.sh
./generate_ips.sh > n8n_slack_src_ips_eu_west_1.tf

First you need to configure a webhook on you n8n instance

  • Configure your security group for you instance to allow the slack IP addresses

  • Create a new workflow

  • Add 'Webhook' (not the response)

    • HTTP Method: POST
    • Path: slack-messages
    • Authentication: None
    • Respond: When Last Node Finishes
    • Response Data: All Entries
  • Go to the Slack App settings

  • go to Event Subscriptions, under the 'Features' heading in the left pane.

  • Toggle "Enable Events" to On

  • In the Request URL field, enter your n8n webhook URL:

Under Subscribe to bot events, add these events:

message.channels - for public channels message.groups - for private channels (if needed) message.im - for direct messages (if needed)

Click Save Changes

Verify slack webhook

Slack webhook - verify signature

  • TODO if there are multiple jsons should I verify the header of each?
  • TODO how do I get the known secret, from the slack app thingy, from a secure storage so it is not part of the code?
function encodeFormData(data) {
  const encodedData = Object.keys(data)
    .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
    .join('&')
    .replaceAll("%20", "+") // Slack does not encode "+" signs
    .replaceAll("*", "%2A") // Slack encodes "*" signs
    .replaceAll("~", "%7E"); // Slack encodes "~" signs
    
  return encodedData;
}

function buildSignatureBaseString(requestJson) {
  const version = "v0"; // Slack Webhook version (Always v0 for the moment)
  
  const timestamp = requestJson.headers["x-slack-request-timestamp"];
  
  const body = requestJson.body;
  const encodedBody = encodeFormData(body);
  
  const signatureBaseString = `${version}:${timestamp}:${encodedBody}`;

  return signatureBaseString;
}

# TODO this only gets the first message, what about the rest of the messages?
const requestJson = $input.first().json;

const signatureBaseString = buildSignatureBaseString(requestJson);

const requestSignature = requestJson.headers["x-slack-signature"];

console.log({
    signatureBaseString,
    requestSignature
  });
return {
  json: {
    signatureBaseString,
    requestSignature
  },
  pairedItem: 0
}

Projects

First project - Send messages to slack

  • create the slack “application” for n8n to connect to slack
  • Create a channel
    • Click the big '+' above the profile picture in the lower left corner
    • Select channel
    • fill out name
    • etc.
  • Invite the n8n app to the channel you want to use for testing
    • /invite @n8n
  • Get the Channel id
    • Click the channel name
    • In the pop-up window at the very bottom there is a ‘Channel ID: xxx’ with a copy icon, copy that.
  • Create a workflow
    • Click the ‘workflows’ tab
    • Click ‘Create workflow’ in the upper right corner.
    • and name it ‘send slack message'
    • add manual trigger
    • add slack
      • click +
      • type in slack in search
      • click slack
      • select ‘Send a message’ under ‘Message actions’
      • Fill out the information:
        • Credentials: Slack account
        • Resource: Message
        • Operation: Send
        • Send Message To: Channel
        • Channel: By ID
          • Paste in the channel ID
        • Message Text: first message
        • Click Execute step in the top right of the pop-up
          • You should see a json dump showing the information has been received by slack.
          • Click ‘Back to canvas’ in the upper left.
  • Click Save
  • Click the ‘Overview’ icon in the left panel, to return to the overview screen.

Get RSS feeds and use AWS bedrock to filter the data and send it on to slack

  • Go to the main page
  • Click ‘Create workflow’ in the top right corner
  • Add manual trigger
  • add RSS Read
  • Add Limit
    • Max Items: 3
  • Add Basic LLM Chain
    • Source for Prompt: Defin below
    • Prompt: As a DevOps assistant, examine the following text.
    • If the text describes removal, modification, or changes to Kubernetes components, output the text exactly as provided.
    • If it does not contain any such changes, respond only with the literal string: not-important.
    • Text: {{ $json.contentSnippet }}
      • others tried
        • As a devops if the text contain removal or changes to kubernetes components then pass through the text otherwise show the literal 'not-important': {{ $json.contentSnippet }}
        • If {{ $json.contentSnippet }} contains removal or modification of Kubernetes components, output it exactly. Otherwise output not-important.
        • As a devops if the text contain removal or changes to kubernetes components then show the text otherwise show 'not-important': {{ $json.content }}
      • Click ‘Back to canvas’ in the top left corner
  • click the ‘Model*’ ‘+' below the 'Basic LLM Chain’
    • Select: AWS Bedrock Chat Model
      • Credentials to connect with: AWS (IAM) account
      • Model Source: On-Demand Models
      • Model: Titan Text G1 - Express
        • (The ‘lite’ could only take 4k tokens)
      • Click Back to Canvas
  • Add If
    • {{ $json.text }}
    • is not equal to
    • not-important
  • Add Edit Fields (Set)
    • Drag and drop into individual boxes, from Limit:
      • Title
      • Link
      • pubDate
      • content
    • Click back to canvas
  • Add Slack: send a message
    • Credentials to connect with: Slack account
    • Resource: Message
    • Operation: Send
    • Send Message To: Channel
    • Channel:
      • by ID
        • get id from slack channel
    • Message Type: Simple Text Message
    • Message Text: Important kubernetes information: {{ $json.title }}\n{{ $json.link }}\n{{ $json.pubDate }}\n{{ $json.content }}

Interacting with gitlab - find renovate MRs that has no infracode changes

Outcome: Send a slack message if the MR causes no plan changes, which means it can be merged.

  • create a GitLab Personal Access Token with read_api scope (or a broader api scope)
    • Go to the project
    • Settings → Access tokens
      • Click ‘Add new token’ button
      • Token name: n8n-renovate
      • Token description: for n8n to work with renovate MRs
      • Expiration date: leave default (a month from now)
      • Select role: Developer
      • Select scope: api
      • click ‘Create project access token’
    • Get gitlab project and group id
  • Go to n8n main page
  • Click create workflow
  • Add manual trigger
  • Add HTTP Request - get MRs with Terraform in them
  • Add Filter
    • Conditions
      • {{ $json.title }}
      • contains
      • Terraform
  • Add HTTP Request - do atlantis plan
    • Method: POST
    • URL: https://gitlab.com/api/v4/projects/{{ $json.project_id }}/merge_requests/{{ $json.iid }}/notes
    • Authentication: Predefined Credential Type
    • Credential Type: Gitlab API
    • Gitlab API: Gitlab account
    • Enable ‘Send Body’
    • Body Content Type: Form Urlencoded
    • Specify Body: Using fields Below
      • Name: body
      • Value: atlantis plan
  • Add HTTP Request - look for the response
    • Method: GET
    • URL: https://gitlab.com/api/v4/projects/{{ $json.project_id }}/merge_requests/{{ $json.noteable_iid }}/notes
    • Authentication: Predefined Credential Type
    • Credential Type: Gitlab API
    • Gitlab API: Gitlab account
  • Add Limit
    • 1
  • Add If
    • {{ $json.body }}
    • is equal to
    • atlantis plan
  • True path
    • add Wait - 1 minutes
    • add Edit fields
      • project_id
      • noteable_iid
  • False path
    • add slack send a message
      • Fill out the information:
      • Credentials: Slack account
      • Resource: Message
      • Operation: Send
      • Send Message To: Channel
      • Channel: By ID
        • Paste in the channel ID
      • Message Text: first mesage
      • Click Execute step in the top right of the pop-up
        • You should see a json dump showing the information has been received by slack.
      • Click ‘Back to canvas’ in the upper left.
    • add HTTP Request - atlantis unlock
      • Method: POST
      • URL: https://gitlab.com/api/v4/projects/{{ $json.project_id }}/merge_requests/{{ $json.noteable_iid }}/notes
      • Authentication: Predefined Credential Type
      • Credential Type: Gitlab API
      • Gitlab API: Gitlab account
      • Enable ‘Send Body’
      • Body Content Type: Form Urlencoded
      • Specify Body: Using fields Below
        • Name: body
        • Value: atlantis unlock
⚠️ **GitHub.com Fallback** ⚠️