微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将S3中的node.js脚本与Cloudwatch合成金丝雀一起使用?

如何解决如何将S3中的node.js脚本与Cloudwatch合成金丝雀一起使用?

我有一个使用嵌入式node.js脚本的Cloudwatch Canary,但是希望该节点脚本可以在S3中使用,然后让lambda引用该脚本。希望导出一些Cloudformation参数(HostName,Path和Port),并将其作为输入传递到node.js脚本中以供使用。

为此,我尝试遵循金丝雀上的AWS documentation,但仍然出现错误

INFO:error.toString()和error.stack.toString():错误:找不到模块'/ opt / nodejs / node_modules / exports'堆栈:错误:找不到模块'/ opt / nodejs / node_modules / exports '

我的Cloudformation模板在这里

Parameters:
  CanaryName:
    Type: String
    Default: my-canary
    MaxLength: 21
  HostName:
    Type: String
    Default: api.net
    MaxLength: 128
  Path:
    Type: String
    Default: /v1/status
    MaxLength: 256
  Port:
    Type: Number
    Default: 443

Resources:
  CloudWatchSyntheticsRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName:
        Fn::Sub: CloudWatchSyntheticsRole-${CanaryName}-${AWS::Region}
      Description: CloudWatch Synthetics lambda execution role for running canaries
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
            Condition: {}

  RolePermissions:
    Type: AWS::IAM::Policy
    Properties:
      Roles:
        - Ref: CloudWatchSyntheticsRole
      PolicyName:
        Fn::Sub: CloudWatchSyntheticsPolicy-${CanaryName}-${AWS::Region}
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - s3:PutObject
              - s3:GetBucketLocation
              - s3:Getobject
              - s3:GetobjectVersion
            Resource:
              - Fn::Sub: arn:aws:s3:::${ResultsBucket}/*
          - Effect: Allow
            Action:
              - logs:CreateLogStream
              - logs:PutLogEvents
              - logs:CreateLogGroup
            Resource:
              - Fn::Sub: arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/cwsyn-test-*
          - Effect: Allow
            Action:
              - s3:ListAllMyBuckets
            Resource: '*'
          - Effect: Allow
            Resource: '*'
            Action: cloudwatch:PutMetricData
            Condition:
              StringEquals:
                cloudwatch:namespace: CloudWatchSynthetics
          - Effect: Allow
            Action:
              - ssm:getParameter
            Resource: "*"

  ResultsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName:
        Fn::Sub: cw-syn-results-${AWS::AccountId}-${AWS::Region}
      BucketEncryption:
        ServerSideEncryptionConfiguration:
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256

  Canary:
    Type: AWS::Synthetics::Canary
    Properties:
      Name:
        Fn::Sub: ${CanaryName}
      Code:
        Handler: exports.handler
        S3Bucket: canary-source-code-ACCOUNT-us-east-1 
        S3Key: exports.zip
      ExecutionRoleArn:
        Fn::GetAtt:
          - CloudWatchSyntheticsRole
          - Arn
      RuntimeVersion: syn-nodejs-2.0
      runconfig:
        TimeoutInSeconds: 60
      ArtifactS3Location:
        Fn::Join:
          - ''
          - - s3://
            - Ref: ResultsBucket
      StartCanaryAfterCreation: True
      Schedule:
        Expression: rate(5 minutes) # every minute
        DurationInSeconds: 0 # run indefinitely
      SuccessRetentionPeriod: 5
      FailureRetentionPeriod: 30

Outputs:
  CanaryRoleArn:
    Value:
      Fn::GetAtt:
        - CloudWatchSyntheticsRole
        - Arn
  ResultsBucketArn:
    Value:
      Fn::GetAtt:
        - ResultsBucket
        - Arn
  ResultsBucketName:
    Value:
      Ref: ResultsBucket

我的Node脚本代码在这里

'use strict';
const AWS = require('aws-sdk')
const parameterStore = new AWS.SSM()

// Read SSM

AWS.config.update({
  region: 'us-east-1'
})

const getParam = param => {
  return new Promise((res,rej) => {
    parameterStore.getParameter({
      Name: param,WithDecryption: true

    },(err,data) => {
        if (err) {
          return rej(err)
        }
        return res(data)
    })
  })
}

module.exports.get = async (event,context) => {
  const param = await getParam(param)
  console.log(param);
  return {
    statusCode: 200,body: JSON.stringify(param)
  };
};

var synthetics = require('Synthetics');
const log = require('Syntheticslogger');
const https = require('https');

const apiCanaryBlueprint = async function () {
    const postData = "";

    var tempsecret = await getParam('token')
    const secret = tempsecret.Parameter.Value

    var temphostname = await getParam('hostname')
    const hostname = temphostname.Parameter.Value

    var temppath = await getParam('path')
    const path = temppath.Parameter.Value

    var tempport = await getParam('port')
    const port = tempport.Parameter.Value

    const verifyRequest = async function (requestOption) {
      return new Promise((resolve,reject) => {
        log.info("Making request with options: " + JSON.stringify(requestOption));
        let req
          req = https.request(requestOption);

        req.on('response',(res) => {
          log.info(`Status Code: ${res.statusCode}`)
          log.info(`Response Headers: ${JSON.stringify(res.headers)}`)

          // If the response status code is not a 2xx success code
          if (res.statusCode < 200 || res.statusCode > 299) {
             reject("Failed: " + requestOption.path);
          }
          res.on('data',(d) => {
            log.info("Response: " + d);
          });
          res.on('end',() => {
            resolve();
          })
        });

        req.on('error',(error) => {
          reject(error);
        });

        if (postData) {
          req.write(postData);
        }
        req.end();
      });
    }
    const headers = { "Authorization" : secret}
    headers['User-Agent'] = [synthetics.getCanaryUserAgentString(),headers['User-Agent']].join(' ');
    const requestOptions = { "hostname" : hostname,"method" : "GET","path" : path,"port" : port }
    requestOptions['headers'] = headers;
    await verifyRequest(requestOptions);
};

exports.handler = async () => {
    return await apiCanaryBlueprint();
};

我读到该文件必须为.zip格式,并且必须与处理程序名称一致,在这种情况下,如上面所述,在本例中为exports.handler。我是CloudWatch的新手,所以我可以对可能出现的问题使用一些指导。

解决方法

我怀疑您没有将文件放在此结构中 exports.zip └nodejs / node_modules / apiCanaryBlueprint.js

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。