diff --git a/WorkingCFN.yaml b/WorkingCFN.yaml new file mode 100644 index 0000000..51196a2 --- /dev/null +++ b/WorkingCFN.yaml @@ -0,0 +1,155 @@ +AWSTemplateFormatVersion: '2010-09-09' +Parameters: + VPC: + Type: AWS::EC2::VPC::Id + Description: The ID for the VPC in which the EC2 instance will be launched. + + Subnet: + Type: AWS::EC2::Subnet::Id + Description: The ID for the Subnet in which the EC2 instance will be launched. + +Resources: + SampleInstanceProfileRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: + - ec2.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/AWSElasticBeanstalkWebTier + XRayWriteOnlyPolicy: + Type: AWS::IAM::Policy + Properties: + PolicyName: AWSXRayWriteOnlyAccess + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - sns:Publish + - xray:PutTelemetryRecords + - xray:PutTraceSegments + - dynamodb:PutItem + Resource: + - "*" + Roles: + - Ref: SampleInstanceProfileRole + SampleInstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + Path: "/" + Roles: + - Ref: SampleInstanceProfileRole + SampleEBServiceRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Sid: '' + Effect: Allow + Principal: + Service: elasticbeanstalk.amazonaws.com + Action: sts:AssumeRole + Condition: + StringEquals: + sts:ExternalId: elasticbeanstalk + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkService + - arn:aws:iam::aws:policy/service-role/AWSElasticBeanstalkEnhancedHealth + ElasticBeanstalkApplication: + Type: AWS::ElasticBeanstalk::Application + Properties: + ApplicationName: + Ref: AWS::StackName + ElasticBeanstalkApplicationVersion: + Type: AWS::ElasticBeanstalk::ApplicationVersion + Properties: + ApplicationName: + Ref: ElasticBeanstalkApplication + SourceBundle: + S3Bucket: + Fn::Join: + - "." + - - aws-xray-assets + - Ref: AWS::Region + S3Key: samples/aws-xray-node-sample-app.zip + ElasticBeanstalkEnvironment: + Type: AWS::ElasticBeanstalk::Environment + Properties: + ApplicationName: + Ref: ElasticBeanstalkApplication + Description: AWS X-Ray Getting Started Sample Application + EnvironmentName: + Ref: AWS::StackName + OptionSettings: + - Namespace: aws:autoscaling:launchconfiguration + OptionName: InstanceType + Value: t3.large + - Namespace: aws:autoscaling:launchconfiguration + OptionName: IamInstanceProfile + Value: + Ref: SampleInstanceProfile + - Namespace: aws:elasticbeanstalk:environment + OptionName: ServiceRole + Value: + Ref: SampleEBServiceRole + - Namespace: aws:elasticbeanstalk:environment + OptionName: EnvironmentType + Value: SingleInstance + - Namespace: aws:elasticbeanstalk:healthreporting:system + OptionName: SystemType + Value: enhanced + - + Namespace: "aws:ec2:vpc" + OptionName: AssociatePublicIpAddress + Value: true + - + Namespace: "aws:ec2:vpc" + OptionName: ELBSubnets + Value: !Ref Subnet + - + Namespace: "aws:ec2:vpc" + OptionName: Subnets + Value: !Ref Subnet + - + Namespace: "aws:ec2:vpc" + OptionName: VPCId + Value: !Ref VPC + PlatformArn: + Fn::Join: + - ":" + - - arn:aws:elasticbeanstalk + - Ref: AWS::Region + - :platform/Node.js 16 running on 64bit Amazon Linux 2/5.6.2 + VersionLabel: + Ref: ElasticBeanstalkApplicationVersion +Outputs: + ElasticBeanstalkEnvironmentURL: + Description: URL for the Elastic Beanstalk Getting Started Sample Application + Value: + Fn::GetAtt: + - ElasticBeanstalkEnvironment + - EndpointURL + SampleInstanceProfileRole: + Description: IAM Role used for AWS X-Ray Getting Started Sample Application + Value: + Fn::GetAtt: + - SampleInstanceProfileRole + - Arn + SampleInstanceProfile: + Description: Instance Profile used for AWS X-Ray Getting Started Sample Application + Value: + Ref: SampleInstanceProfile + SampleEBServiceRole: + Description: IAM Role used for AWS Elastic Beanstalk Service Role + Value: + Fn::GetAtt: + - SampleEBServiceRole + - Arn diff --git a/app.js b/app.js index 08a7b0b..38018fa 100644 --- a/app.js +++ b/app.js @@ -23,43 +23,29 @@ if (cluster.isMaster) { // Code to run if we're in a worker process } else { - // Include the AWS X-Ray Node.js SDK and set configuration - var XRay = require('aws-xray-sdk'); - var AWS = XRay.captureAWS(require('aws-sdk')); - var http = XRay.captureHTTPs(require('http')); + var AWS = require('aws-sdk'); var express = require('express'); var bodyParser = require('body-parser'); - var queryString = require('querystring'); AWS.config.region = process.env.REGION - XRay.config([XRay.plugins.EC2Plugin, XRay.plugins.ElasticBeanstalkPlugin]); - XRay.middleware.setSamplingRules('sampling-rules.json'); - XRay.middleware.enableDynamicNaming(); - - var app = express(); var sns = new AWS.SNS(); var ddb = new AWS.DynamoDB(); - var ddbTable = process.env.STARTUP_SIGNUP_TABLE; - var snsTopic = process.env.NEW_SIGNUP_TOPIC; - var apiCNAME = process.env.API_CNAME || 'localhost'; + + var ddbTable = process.env.STARTUP_SIGNUP_TABLE; + var snsTopic = process.env.NEW_SIGNUP_TOPIC; + var app = express(); app.set('view engine', 'ejs'); app.set('views', __dirname + '/views'); app.use(bodyParser.urlencoded({extended:false})); - app.use(XRay.express.openSegment('myfrontend')); app.get('/', function(req, res) { - XRay.captureAsyncFunc('Page Render', function(seg) { - res.render('index', { - static_path: 'static', - theme: process.env.THEME || 'flatly', - flask_debug: process.env.FLASK_DEBUG || 'false' - }); - seg.close(); + res.render('index', { + static_path: 'static', + theme: process.env.THEME || 'flatly', + flask_debug: process.env.FLASK_DEBUG || 'false' }); - - res.status(200).end(); }); app.post('/signup', function(req, res) { @@ -70,22 +56,20 @@ if (cluster.isMaster) { 'theme': {'S': req.body.theme} }; - var seg = XRay.getSegment(); - seg.addAnnotation('email', req.body.email); - seg.addAnnotation('theme', req.body.theme); - seg.addAnnotation('previewAccess', req.body.previewAccess); - ddb.putItem({ 'TableName': ddbTable, 'Item': item, 'Expected': { email: { Exists: false } } }, function(err, data) { if (err) { + var returnStatus = 500; + if (err.code === 'ConditionalCheckFailedException') { - res.status(409).end("User already exists"); - } else { - res.status(500).end("DDB Error"); + returnStatus = 409; } + + res.status(returnStatus).end(); + console.log('DDB Error: ' + err); } else { sns.publish({ 'Message': 'Name: ' + req.body.name + "\r\nEmail: " + req.body.email @@ -95,58 +79,16 @@ if (cluster.isMaster) { 'TopicArn': snsTopic }, function(err, data) { if (err) { - res.status(500).end("SNS Error"); + res.status(500).end(); + console.log('SNS Error: ' + err); } else { - res.status(201).end("Success"); + res.status(201).end(); } }); } }); }); - app.post('/remoteSignup', function(req, res) { - var seg = XRay.getSegment(); - seg.addAnnotation('theme', req.body.theme); - seg.addAnnotation('previewAccess', req.body.previewAccess); - - var reqData = queryString.stringify(req.body); - - var options = { - host: apiCNAME, - port: '80', - path: '/signup', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(reqData) - } - }; - - // Set up the request - var remoteReq = http.request(options, function(remoteRes) { - var body = ''; - remoteRes.setEncoding('utf8'); - - remoteRes.on('data', function(chunk) { - body += chunk; - }); - - remoteRes.on('end', function() { - res.status(remoteRes.statusCode).send(body); - }); - }); - - remoteReq.on('error', function(err) { - res.status(500).end("Remote error"); - }); - - // post the data - remoteReq.write(reqData); - remoteReq.end(); - }); - - app.use(XRay.express.closeSegment()); - var port = process.env.PORT || 3000; var server = app.listen(port, function () { diff --git a/iam_policy.json b/iam_policy.json index c74e433..d6d9322 100644 --- a/iam_policy.json +++ b/iam_policy.json @@ -3,25 +3,13 @@ "Statement": [ { "Effect": "Allow", - "Action": [ - "dynamodb:PutItem" - ], + "Action": [ "dynamodb:PutItem" ], "Resource": [ "*" ] }, { "Effect": "Allow", - "Action": [ - "sns:Publish" - ], + "Action": [ "sns:Publish" ], "Resource": [ "*" ] - }, - { - "Effect":"Allow", - "Action": [ - "xray:PutTraceSegments", - "xray:PutTelemetryRecords" - ], - "Resource":[ "*" ] } ] -} +} \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json new file mode 100644 index 0000000..e648c9c --- /dev/null +++ b/npm-shrinkwrap.json @@ -0,0 +1,379 @@ +{ + "name": "Elastic-Beanstalk-Sample-App", + "version": "0.0.1", + "dependencies": { + "aws-sdk": { + "version": "2.1.39", + "from": "aws-sdk@latest", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1.39.tgz", + "dependencies": { + "sax": { + "version": "0.5.3", + "from": "sax@0.5.3", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.3.tgz" + }, + "xml2js": { + "version": "0.2.8", + "from": "xml2js@0.2.8", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz" + }, + "xmlbuilder": { + "version": "0.4.2", + "from": "xmlbuilder@0.4.2", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.2.tgz" + } + } + }, + "body-parser": { + "version": "1.13.2", + "from": "body-parser@latest", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.13.2.tgz", + "dependencies": { + "bytes": { + "version": "2.1.0", + "from": "bytes@2.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.1.0.tgz" + }, + "content-type": { + "version": "1.0.1", + "from": "content-type@~1.0.1", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.1.tgz" + }, + "debug": { + "version": "2.2.0", + "from": "debug@~2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dependencies": { + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + } + } + }, + "depd": { + "version": "1.0.1", + "from": "depd@~1.0.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz" + }, + "http-errors": { + "version": "1.3.1", + "from": "http-errors@~1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "inherits@~2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "statuses": { + "version": "1.2.1", + "from": "statuses@1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz" + } + } + }, + "iconv-lite": { + "version": "0.4.11", + "from": "iconv-lite@0.4.11", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.11.tgz" + }, + "on-finished": { + "version": "2.3.0", + "from": "on-finished@~2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "dependencies": { + "ee-first": { + "version": "1.1.1", + "from": "ee-first@1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + } + } + }, + "qs": { + "version": "4.0.0", + "from": "qs@4.0.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz" + }, + "raw-body": { + "version": "2.1.2", + "from": "raw-body@~2.1.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.2.tgz", + "dependencies": { + "unpipe": { + "version": "1.0.0", + "from": "unpipe@1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + } + } + }, + "type-is": { + "version": "1.6.5", + "from": "type-is@~1.6.4", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.5.tgz", + "dependencies": { + "media-typer": { + "version": "0.3.0", + "from": "media-typer@0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + }, + "mime-types": { + "version": "2.1.3", + "from": "mime-types@~2.1.3", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.3.tgz", + "dependencies": { + "mime-db": { + "version": "1.15.0", + "from": "mime-db@~1.15.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.15.0.tgz" + } + } + } + } + } + } + }, + "ejs": { + "version": "2.3.3", + "from": "ejs@latest", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.3.3.tgz" + }, + "express": { + "version": "4.13.1", + "from": "express@latest", + "resolved": "https://registry.npmjs.org/express/-/express-4.13.1.tgz", + "dependencies": { + "accepts": { + "version": "1.2.11", + "from": "accepts@~1.2.10", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.2.11.tgz", + "dependencies": { + "mime-types": { + "version": "2.1.3", + "from": "mime-types@~2.1.3", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.3.tgz", + "dependencies": { + "mime-db": { + "version": "1.15.0", + "from": "mime-db@~1.15.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.15.0.tgz" + } + } + }, + "negotiator": { + "version": "0.5.3", + "from": "negotiator@0.5.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.5.3.tgz" + } + } + }, + "array-flatten": { + "version": "1.1.0", + "from": "array-flatten@1.1.0", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.0.tgz" + }, + "content-disposition": { + "version": "0.5.0", + "from": "content-disposition@0.5.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.0.tgz" + }, + "content-type": { + "version": "1.0.1", + "from": "content-type@~1.0.1", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.1.tgz" + }, + "cookie": { + "version": "0.1.3", + "from": "cookie@0.1.3", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.3.tgz" + }, + "cookie-signature": { + "version": "1.0.6", + "from": "cookie-signature@1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + }, + "debug": { + "version": "2.2.0", + "from": "debug@~2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "dependencies": { + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + } + } + }, + "depd": { + "version": "1.0.1", + "from": "depd@~1.0.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.0.1.tgz" + }, + "escape-html": { + "version": "1.0.2", + "from": "escape-html@1.0.2", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.2.tgz" + }, + "etag": { + "version": "1.7.0", + "from": "etag@~1.7.0", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.7.0.tgz" + }, + "finalhandler": { + "version": "0.4.0", + "from": "finalhandler@0.4.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.4.0.tgz", + "dependencies": { + "unpipe": { + "version": "1.0.0", + "from": "unpipe@~1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + } + } + }, + "fresh": { + "version": "0.3.0", + "from": "fresh@0.3.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.3.0.tgz" + }, + "merge-descriptors": { + "version": "1.0.0", + "from": "merge-descriptors@1.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.0.tgz" + }, + "methods": { + "version": "1.1.1", + "from": "methods@~1.1.1", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.1.tgz" + }, + "on-finished": { + "version": "2.3.0", + "from": "on-finished@~2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "dependencies": { + "ee-first": { + "version": "1.1.1", + "from": "ee-first@1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + } + } + }, + "parseurl": { + "version": "1.3.0", + "from": "parseurl@~1.3.0", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.0.tgz" + }, + "path-to-regexp": { + "version": "0.1.6", + "from": "path-to-regexp@0.1.6", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.6.tgz" + }, + "proxy-addr": { + "version": "1.0.8", + "from": "proxy-addr@~1.0.8", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.8.tgz", + "dependencies": { + "forwarded": { + "version": "0.1.0", + "from": "forwarded@~0.1.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz" + }, + "ipaddr.js": { + "version": "1.0.1", + "from": "ipaddr.js@1.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.0.1.tgz" + } + } + }, + "qs": { + "version": "4.0.0", + "from": "qs@4.0.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-4.0.0.tgz" + }, + "range-parser": { + "version": "1.0.2", + "from": "range-parser@~1.0.2", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.2.tgz" + }, + "send": { + "version": "0.13.0", + "from": "send@0.13.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.13.0.tgz", + "dependencies": { + "destroy": { + "version": "1.0.3", + "from": "destroy@1.0.3", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" + }, + "http-errors": { + "version": "1.3.1", + "from": "http-errors@~1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "inherits@~2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "mime": { + "version": "1.3.4", + "from": "mime@1.3.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" + }, + "ms": { + "version": "0.7.1", + "from": "ms@0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" + }, + "statuses": { + "version": "1.2.1", + "from": "statuses@~1.2.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.2.1.tgz" + } + } + }, + "serve-static": { + "version": "1.10.0", + "from": "serve-static@~1.10.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.10.0.tgz" + }, + "type-is": { + "version": "1.6.5", + "from": "type-is@~1.6.4", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.5.tgz", + "dependencies": { + "media-typer": { + "version": "0.3.0", + "from": "media-typer@0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + }, + "mime-types": { + "version": "2.1.3", + "from": "mime-types@~2.1.3", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.3.tgz", + "dependencies": { + "mime-db": { + "version": "1.15.0", + "from": "mime-db@~1.15.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.15.0.tgz" + } + } + } + } + }, + "vary": { + "version": "1.0.1", + "from": "vary@~1.0.0", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.0.1.tgz" + }, + "utils-merge": { + "version": "1.0.0", + "from": "utils-merge@1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" + } + } + } + } +} diff --git a/package.json b/package.json index 780d139..57d32fd 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,10 @@ "version": "0.0.1", "private": true, "dependencies": { - "ejs": "2.5.5", - "aws-sdk": "2.682.0", - "express": "4.14.0", - "body-parser": "1.16.0", - "querystring": "0.2.0", - "aws-xray-sdk": "3.0.1" + "ejs": "latest", + "aws-sdk": "latest", + "express": "latest", + "body-parser": "latest" }, "scripts": { "start": "node app.js" diff --git a/views/index.ejs b/views/index.ejs index 807cbe6..7686624 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -6,16 +6,18 @@ -
- Aww yeah, you've successfully launched the AWS X-Ray sample application. Use the start/stop buttons below to control the generation of signup requests. The application will generate up to 10 signup requests per minute with a duplicate signup each minute. Alternatively, you can use the form below to manually generate signup requests. Once you've generated a few requests, go to the AWS X-Ray Console to view the service map and traces. -
-Status: click 'Start' to begin
+ <% if (flask_debug === 'true') { %> +- We're pretty thrilled to unveil our latest creation. Sign up below to be notified when we officially launch! -
-- Sign up today -
+We're pretty thrilled to unveil our latest creation. Sign up below to be notified when we officially launch!
+