From 3535b08c27bb4bf1ff2fc242fa8ef837cec45a92 Mon Sep 17 00:00:00 2001 From: ArseniiPetrovich Date: Thu, 21 Mar 2019 13:25:55 +0300 Subject: [PATCH] Add lambda script and update README accordingly --- README.md | 6 +- lambda/AMIRefresher.js | 130 +++++++++++++++++++++++++++++++++++++++++ lambda/README.md | 8 +++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 lambda/AMIRefresher.js create mode 100644 lambda/README.md diff --git a/README.md b/README.md index abd2b54..e696526 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # About -This repo contains Ansible playbooks designed in purpose of automation [Blockscout](https://github.com/poanetwork/blockscout) deployment builds. Currently it supports only [AWS](#AWS) as a cloud provider. Playbooks will create all necessary infrastructure along with cloud storage space required for saving configuration and state files. +This repo contains scripts designed to automate [Blockscout](https://github.com/poanetwork/blockscout) deployment builds. Currently it supports only [AWS](#AWS) as a cloud provider. + +In the root folder you can find an Ansible Playbooks that will create all necessary infrastructure and deploy BlockScout. Please, read this ReadMe for more information on configuring and executing this playbooks. + +Also you may want to refer to the `lambda` folder which contains a set of scripts that may be useful in your BlockScout infrastructure. # Prerequisites diff --git a/lambda/AMIRefresher.js b/lambda/AMIRefresher.js new file mode 100644 index 0000000..c5695f8 --- /dev/null +++ b/lambda/AMIRefresher.js @@ -0,0 +1,130 @@ +var aws = require('aws-sdk'); +var https = require('https'); +var url = require('url'); +var util = require("util"); + +var ASGName = process.env.ASGName; +var AMIInstanceID = process.env.AMIInstanceID; +var LCName= process.env.LCName; +var OnlyAMICreation=process.env.ONLY_AMI_CREATION; +var AMIName =process.env.AMIName; + +exports.handler = function(event, context, callback) { + var ec2 = new aws.EC2(); + var autoscaling = new aws.AutoScaling(); + + // Create unique AMI and launch configuration names + var date = new Date(); + var timestamp = date.getTime(); + AMIName = AMIName+timestamp; + LCName = LCName+timestamp; + var AMIID, LC, OldASG; + + // Either simply create an image or execute the whole function + if (OnlyAMICreation) { createImage(); } + else { describeASG(); } + + // Get info about autoscaling groups and proceed to get info about Launch configuration + function describeASG() + { + var params = { + AutoScalingGroupNames: [ + ASGName + ] + }; + + autoscaling.describeAutoScalingGroups(params, function(err, data) { + if (err) console.log("Error", err, err.stack); // an error occurred + else OldASG=data; describeLC(); // successful response + }); + } + + // Get info about launch configuration and proceed to AMI creation + function describeLC() + { + var params = { + LaunchConfigurationNames: [ + OldASG.AutoScalingGroups[0].LaunchConfigurationName + ] + }; + autoscaling.describeLaunchConfigurations(params, function(err, data) { + if (err) console.log(err, err.stack); // an error occurred + else { LC=data; createImage(); } // successful response + }); + } + + // Create AMI and either proceed to create a new launch configuration or exit function + function createImage() + { + var params = { + Description: "Created by AMIRefresher function", + InstanceId: AMIInstanceID, + Name: AMIName, + NoReboot: true + }; + + ec2.createImage(params, function(err, data) { + if (err) console.log("Error!", err, err.stack); // an error occurred + else if (OnlyAMICreation) { process.exit(0); } + else { AMIID=data; createLC(); } // successful response + }); + } + + // Create new launch configuration and proceed to update an autoscaling group + function createLC() + { + var params = { + LaunchConfigurationName: LCName, + AssociatePublicIpAddress: LC.LaunchConfigurations[0].AssociatePublicIpAddress, + BlockDeviceMappings: LC.LaunchConfigurations[0].BlockDeviceMappings, + ClassicLinkVPCId: LC.LaunchConfigurations[0].ClassicLinkVPCId, + ClassicLinkVPCSecurityGroups: LC.LaunchConfigurations[0].ClassicLinkVPCSecurityGroups, + EbsOptimized: LC.LaunchConfigurations[0].EbsOptimized, + IamInstanceProfile: LC.LaunchConfigurations[0].IamInstanceProfile, + ImageId: AMIID.ImageId, + InstanceMonitoring: LC.LaunchConfigurations[0].InstanceMonitoring, + InstanceType: LC.LaunchConfigurations[0].InstanceType, + KeyName: LC.LaunchConfigurations[0].KeyName, + PlacementTenancy: LC.LaunchConfigurations[0].PlacementTenancy, + SecurityGroups: LC.LaunchConfigurations[0].SecurityGroups, + UserData: LC.LaunchConfigurations[0].UserData + }; + autoscaling.createLaunchConfiguration(params, function(err, data) { + if (err) console.log(err, err.stack); // an error occurred + else updateASG(); // successful response + }); + } + + // update an autoscaling group and proceed to cleanup + function updateASG() + { + var params = { + AutoScalingGroupName: ASGName, + LaunchConfigurationName: LCName + }; + autoscaling.updateAutoScalingGroup(params, function(err, data) { + if (err) console.log(err, err.stack); // an error occurred + else clean(); // successful response + }); + } + + // Cleanup and exit - delete old launch configuration and old AMI + function clean() + { + var params = { + LaunchConfigurationName: OldASG.AutoScalingGroups[0].LaunchConfigurationName + }; + autoscaling.deleteLaunchConfiguration(params, function(err, data) { + if (err) console.log(err, err.stack); // an error occurred + else console.log(data); // successful response + }); + + var params = { + ImageId: LC.LaunchConfigurations[0].ImageId, + }; + ec2.deregisterImage(params, function(err, data) { + if (err) console.log(err, err.stack); // an error occurred + else console.log(data); // successful response + }); + } +}; diff --git a/lambda/README.md b/lambda/README.md new file mode 100644 index 0000000..8638f29 --- /dev/null +++ b/lambda/README.md @@ -0,0 +1,8 @@ +# File index + +- `AMIRefresher.js` is a Node.JS script that will automatically create an AMI from your current Archive node instance and update your autoscaling group, so you will have the relevant images to scale or to recover from disaster. Parts of it's code may also be useful for those who search how to copy existing launch configuration in Node.JS. This scripts supposes you have setup the following environment variables: + - `ASGName` - the name of your autoscaling group; + - `AMIInstanceID` - id of your Archive node instance; + - `LCName` - a name of launch configuration to be created; + - `ONLY_AMI_CREATION` - set to true if you want script to simply create an AMI (assignment and old image deletion will not be performed in that case); +