Send a message from SNS to Slack using Lambda

1. Create a Topic on SNS

To set up Amazon SNS notifications

  1. Open the Amazon SNS console at https://eu-central-1.console.aws.amazon.com/sns/v3/home
  2. Choose Topics > Create topic
  3. Create a topic with Name: CheckHealthW3Server and Display name: Health WWW servers. Other things should be default.
  4. After that go to view detail of CheckHealthW3Server to create a subscription.

2. Create a subscription

We can ignore this step if we didn’t create a lambda function before.

  1. Click Create subscription
  2. Topic ARN: Enter a ARN of the CheckHealthW3Server topic.
  3. Protocol: select AWS Lambda
  4. Endpoint: An AWS Lambda function that can receive notifications from Amazon SNS
  5. That’s all for a subscription. We can create many subscriptions with other protocol.

3. Create a channel and config to get message from lambda function

  1. Slack > Create channel: #sns-notifications
  2. Create a apps to post messages from external sources into Slack. Visit the link: https://channel.slack.com/apps and search app name: Incoming WebHooks
  3. At homepage the app choose Add configuration and choose Post to Channel is #sns-notifications
  4. After that you can get value for Webhook URL like that: https://hooks.slack.com/services/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

4. Create a lambda function to be trigger by SNS service

  1. AWS Lambda > Create function
  2. We have three ways to create a function lambda. But we should use a blueprint because it helps us to assign this function to the topic we want automatically. At search field we use the keyword is sns-message and choose language is Nodejs.
  3. Fill these information for this function:
    1. Function name: notificationToSlack
    2. Execution role: Create a new role with basic Lambda permissions
    3. SNS topic: search CheckHealthW3Server
    4. Tick to Enable trigger
    5. Lambda function code: In this code you have to config again the path for calling webhook slack.
var https = require('https');
var util = require('util');

exports.handler = function(event, context) {
console.log(JSON.stringify(event, null, 2));
console.log('From SNS:', event.Records[0].Sns.Message);

var postData = {
"text": "*" + event.Records[0].Sns.Subject + "*"
};

var message = event.Records[0].Sns.Message;
var severity = "danger";

postData.attachments = [
{
"color": severity,
"text": message
}
];

var options = {
method: 'POST',
hostname: 'hooks.slack.com',
port: 443,
path: '/services/T2KFETZAQ/BH9KNUKU4/QOfFx4h08TF3D1OVKnhCmRS1'
};

var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
context.done(null);
});
});

req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});

req.write(util.format("%j", postData));
req.end();
};

5. Publish a message to test

At the detail of the CheckHealthW3Server page.

  1. Click on Publish message
  2. Enter: Subject and Message body to send to the endpoint
  3. Open the #sns-notifications channel to see the result.

Install Website on Amazon Linux 2

1. Lauch Instance

Step 1: Choose an Amazon Machine Image is Amazon Linux 2 AMI (HVM), SSD Volume Type
Step 2: Choose an Instance Type is t2.small (Variable ECUs, 1 vCPUs, 2.5 GHz, Intel Xeon Family, 2 GiB memory, EBS only)
Step 3: Configure Instance Details is set as default
Step 4: Add Storage is 8 GiB, General Purpose SSD
Step 5: Add Tags
Name: Resales Online Website on Linux
Step 6: Configure Security Group
Choose an existing security group is Website on Linux Group
Launch: Choose an existing key pair is WebsiteForLinux.pem

2. LOGIN INTO INSTANCE
Open console to connect this instance by command line:

ssh -i "WebsiteForLinux.pem" [email protected]*-*-*-*.eu-central-1.compute.amazonaws.com

3. INSTALL PYTHON PACKAGES

sudo yum install python-pip
sudo yum install python-virtualenv

4. INSTALL GIT

sudo yum install git

Check version:

git —version

5. INSTALL PHP

sudo amazon-linux-extras install php7.1
sudo yum install php-mbstring php-xml

Check version:

php —version

6. INSTALL COMPOSER

cd ~
sudo curl -sS https://getcomposer.org/installer | sudo php
sudo mv composer.phar /usr/local/bin/composer
sudo ln -s /usr/local/bin/composer /usr/bin/composer

Check version:

composer —version

7. INSTALL NGINX

sudo amazon-linux-extras install nginx1.12
sudo chmod 664 /etc/nginx/nginx.conf
sudo usermod -a -G nginx ec2-user
sudo chown -R ec2-user:nginx /usr/share/nginx/
sudo chmod 2775 /usr/share/nginx/ && find /usr/share/nginx/ -type d -exec sudo chmod 2775 {} \;
find /usr/share/nginx/ -type f -exec sudo chmod 0664 {} \;
echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/phpinfo.php
sudo systemctl start nginx

8. GENERATE SSH KEY

ssh-keygen

Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): /home/ec2-user/.ssh/example-com
The key fingerprint is: example-com

Add SSH KEY to Authentication Agent

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/example-com

You have to run these commands every you login to the Instance

9. CLONE SOURCES CODE
Create folder in server:

mkdir /usr/share/nginx/sites
mkdir /usr/share/nginx/sites/example.com

Clone source code the http://example.com

cd /usr/share/nginx/sites/example.com
git clone [email protected]:***/example_com.git .
composer install

10. SETUP DOMAINS
Open and modify file nginx.conf (/etc/nginx/nginx.conf)

# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

server {
listen 443 ssl;
server_name example.com;
root /usr/share/nginx/sites/example.com/;
location / {
index index.php;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}

11. INSTALL SSL

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto --no-bootstrap

Requesting to rerun ./certbot-auto with root privileges…
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
1: example.com
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter ‘c’ to cancel): Enter

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
Waiting for verification…
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/nginx.conf

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
1: No redirect – Make no further changes to the webserver configuration.
2: Redirect – Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you’re confident your site works on HTTPS. You can undo this
change by editing your web server’s configuration.
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Select the appropriate number [1-2] then [enter] (press ‘c’ to cancel): 2

Traffic on port 80 already redirecting to ssl in /etc/nginx/nginx.conf

– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –
Congratulations! You have successfully enabled https://example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
– – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2019-06-16. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again with the “certonly” option. To non-interactively renew *all*
of your certificates, run “certbotauto renew
– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

12. RENEW SSL CERTIFICATE
Create a cron job and let it run at midnight everyday:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /home/ec2-user/certbot-auto renew