AWS为dev和prod部署环境并创建环境

时间:2018-01-22 17:14:27

标签: amazon-web-services amazon-s3 aws-lambda amazon-dynamodb aws-api-gateway

全心全意,

我正在寻找一种部署我的应用程序的方法,其中包含:

  • API网关
  • DynamoDB
  • Lambda函数
  • 一个S3存储桶

我查看了CloudFormation和CodeDeploy,但我不确定如何在没有EC2的情况下继续...

我找到的所有信息都是针对EC2的,我还没有找到任何关于在上面部署应用程序的信息......

目标是拥有一个部署脚本,该脚本使用AWS的技术自动将应用程序部署到环境中。 (基本上重复我的环境)

非常感谢任何帮助。

编辑:我需要能够从一个AWS账户导出,然后导入另一个AWS账户。

干杯!

4 个答案:

答案 0 :(得分:2)

要将CloudFormation堆栈部署到“不同”环境,您必须参数化CloudFormation堆栈名称和资源名称。 (您不必在此示例中参数化AWS::Serverless::Function函数,因为AWS会自动执行此操作,因为未指定函数名称,但对于大多数其他资源,它是必需的)

示例CloudFormation模板cfn.yml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Deploys a simple AWS Lambda using different environments.

Parameters:
  Env:
    Type: String
    Description: The environment you're deploying to.

Resources:
  ServerlessFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs6.10
      CodeUri: ./
      Policies:
        - AWSLambdaBasicExecutionRole

  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'my-bucket-name-${Env}'

示例deploy.sh脚本:

#!/usr/bin/env bash

LAMBDA_BUCKET="Your-S3-Bucket-Name"
# change this ENV variable depending on the environment you want to deploy
ENV="prd"
STACK_NAME="aws-lambda-cf-environments-${ENV}"

# now package the CloudFormation template, upload SAM artifacts to S3 and deploy it
aws cloudformation package --template-file cfn.yml --s3-bucket ${LAMBDA_BUCKET} --output-template-file cfn.packaged.yml
aws cloudformation deploy --template-file cfn.packaged.yml --stack-name ${STACK_NAME} --capabilities CAPABILITY_IAM --parameter-overrides Env=${ENV}

请参阅完整示例代码here。只需使用./deploy.sh部署脚本并更改ENV变量。

答案 1 :(得分:1)

基于JSON示例。

Lambda函数AWS::Lambda::Function

  • 此示例创建一个Lambda函数和一个附加到其上的IAM角色。

语言: NodeJs

"LambdaRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "lambda.amazonaws.com"
                        ]
                    },
                    "Action": [
                        "sts:AssumeRole"
                    ]
                }
            ]
        },
        "Policies": [
            {
                "PolicyName": "LambdaSnsNotification",
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Sid": "AllowSnsActions",
                            "Effect": "Allow",
                            "Action": [
                                "sns:Publish",
                                "sns:Subscribe",
                                "sns:Unsubscribe",
                                "sns:DeleteTopic",
                                "sns:CreateTopic"
                            ],
                            "Resource": "*"
                        }
                    ]
                }
            }
        ]
    }
},
"LambdaFunctionMessageSNSTopic": {
    "Type": "AWS::Lambda::Function",
    "Properties": {
        "Description": "Send message to a specific topic that will deliver MSG to a receiver.",
        "Handler": "index.handler",
        "MemorySize": 128,
        "Role": {
            "Fn::GetAtt": [
                "LambdaRole",
                "Arn"
            ]
        },
        "Runtime": "nodejs6.10",
        "Timeout": 60,
        "Environment": {
            "Variables": {
                "sns_topic_arn": ""
            }
        },
        "Code": {
            "ZipFile": {
                "Fn::Join": [
                    "\n",
                    [
                        "var AWS = require('aws-sdk');",                        
                        "};"
                    ]
                ]
            }
        }
    }
}

API网关AWS::ApiGateway::RestApi

  • 此示例创建Role,RestAPI,Usageplan,Keys和从Request方法执行lambda的权限。
"MSGGatewayRestApi": {
    "Type": "AWS::ApiGateway::RestApi",
    "Properties": {
        "Name": "MSG RestApi",
        "Description": "API used for sending MSG",
        "FailOnWarnings": true
    }
},
"MSGGatewayRestApiUsagePlan": {
    "Type": "AWS::ApiGateway::UsagePlan",
    "Properties": {
        "ApiStages": [
            {
                "ApiId": {
                    "Ref": "MSGGatewayRestApi"
                },
                "Stage": {
                    "Ref": "MSGGatewayRestApiStage"
                }
            }
        ],
        "Description": "Usage plan for stage v1",
        "Quota": {
            "Limit": 5000,
            "Period": "MONTH"
        },
        "Throttle": {
            "BurstLimit": 200,
            "RateLimit": 100
        },
        "UsagePlanName": "Usage_plan_for_stage_v1"
    }
},
"RestApiUsagePlanKey": {
    "Type": "AWS::ApiGateway::UsagePlanKey",
    "Properties": {
        "KeyId": {
            "Ref": "MSGApiKey"
        },
        "KeyType": "API_KEY",
        "UsagePlanId": {
            "Ref": "MSGGatewayRestApiUsagePlan"
        }
    }
},
"MSGApiKey": {
    "Type": "AWS::ApiGateway::ApiKey",
    "Properties": {
        "Name": "MSGApiKey",
        "Description": "CloudFormation API Key v1",
        "Enabled": "true",
        "StageKeys": [
            {
                "RestApiId": {
                    "Ref": "MSGGatewayRestApi"
                },
                "StageName": {
                    "Ref": "MSGGatewayRestApiStage"
                }
            }
        ]
    }
},
"MSGGatewayRestApiStage": {
    "DependsOn": [
        "ApiGatewayAccount"
    ],
    "Type": "AWS::ApiGateway::Stage",
    "Properties": {
        "DeploymentId": {
            "Ref": "RestAPIDeployment"
        },
        "MethodSettings": [
            {
                "DataTraceEnabled": true,
                "HttpMethod": "*",
                "LoggingLevel": "INFO",
                "ResourcePath": "/*"
            }
        ],
        "RestApiId": {
            "Ref": "MSGGatewayRestApi"
        },
        "StageName": "v1"
    }
},
"ApiGatewayCloudWatchLogsRole": {
    "Type": "AWS::IAM::Role",
    "Properties": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                            "apigateway.amazonaws.com"
                        ]
                    },
                    "Action": [
                        "sts:AssumeRole"
                    ]
                }
            ]
        },
        "Policies": [
            {
                "PolicyName": "ApiGatewayLogsPolicy",
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Action": [
                                "logs:CreateLogGroup",
                                "logs:CreateLogStream",
                                "logs:DescribeLogGroups",
                                "logs:DescribeLogStreams",
                                "logs:PutLogEvents",
                                "logs:GetLogEvents",
                                "logs:FilterLogEvents"
                            ],
                            "Resource": "*"
                        }
                    ]
                }
            }
        ]
    }
},
"ApiGatewayAccount": {
    "Type": "AWS::ApiGateway::Account",
    "Properties": {
        "CloudWatchRoleArn": {
            "Fn::GetAtt": [
                "ApiGatewayCloudWatchLogsRole",
                "Arn"
            ]
        }
    }
},
"RestAPIDeployment": {
    "Type": "AWS::ApiGateway::Deployment",
    "DependsOn": [
        "MSGGatewayRequest"
    ],
    "Properties": {
        "RestApiId": {
            "Ref": "MSGGatewayRestApi"
        },
        "StageName": "DummyStage"
    }
},
"ApiGatewayMSGResource": {
    "Type": "AWS::ApiGateway::Resource",
    "Properties": {
        "RestApiId": {
            "Ref": "MSGGatewayRestApi"
        },
        "ParentId": {
            "Fn::GetAtt": [
                "MSGGatewayRestApi",
                "RootResourceId"
            ]
        },
        "PathPart": "delivermessage"
    }
},
"MSGGatewayRequest": {
    "DependsOn": "LambdaPermission",
    "Type": "AWS::ApiGateway::Method",
    "Properties": {
        "ApiKeyRequired": true,
        "AuthorizationType": "NONE",
        "HttpMethod": "POST",
        "Integration": {
            "Type": "AWS",
            "IntegrationHttpMethod": "POST",
            "Uri": {
                "Fn::Join": [
                    "",
                    [
                        "arn:aws:apigateway:",
                        {
                            "Ref": "AWS::Region"
                        },
                        ":lambda:path/2015-03-31/functions/",
                        {
                            "Fn::GetAtt": [
                                "LambdaFunctionMessageSNSTopic",
                                "Arn"
                            ]
                        },
                        "/invocations"
                    ]
                ]
            },
            "IntegrationResponses": [
                {
                    "StatusCode": 200
                },
                {
                    "SelectionPattern": "500.*",
                    "StatusCode": 500
                },
                {
                    "SelectionPattern": "412.*",
                    "StatusCode": 412
                }
            ],
            "RequestTemplates": {
                "application/json": ""
            }
        },
        "RequestParameters": {
        },
        "ResourceId": {
            "Ref": "ApiGatewayMSGResource"
        },
        "RestApiId": {
            "Ref": "MSGGatewayRestApi"
        },
        "MethodResponses": [
            {
                "StatusCode": 200
            },
            {
                "StatusCode": 500
            },
            {
                "StatusCode": 412
            }
        ]
    }
},
"LambdaPermission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "Action": "lambda:invokeFunction",
        "FunctionName": {
            "Fn::GetAtt": [
                "LambdaFunctionMessageSNSTopic",
                "Arn"
            ]
        },
        "Principal": "apigateway.amazonaws.com",
        "SourceArn": {
            "Fn::Join": [
                "",
                [
                    "arn:aws:execute-api:",
                    {
                        "Ref": "AWS::Region"
                    },
                    ":",
                    {
                        "Ref": "AWS::AccountId"
                    },
                    ":",
                    {
                        "Ref": "MSGGatewayRestApi"
                    },
                    "/*"
                ]
            ]
        }
    }
}

DynamoDB AWS::DynamoDB::Table

  • 此示例创建一个DynamoDB表MyCrossConfig及其警报。
"TableMyCrossConfig": {
  "Type": "AWS::DynamoDB::Table",
  "Properties": {
    "TableName": "MyCrossConfig",
    "AttributeDefinitions": [
      {
        "AttributeName": "id",
        "AttributeType": "S"
      }
    ],
    "KeySchema": [
      {
        "AttributeName": "id",
        "KeyType": "HASH"
      }
    ],
    "ProvisionedThroughput": {
      "ReadCapacityUnits": "5",
      "WriteCapacityUnits": "5"
    }
  }
},
"alarmTargetTrackingtableMyCrossConfigProvisionedCapacityLowdfcae8d90ee2487a8e59c7bc0f9f6bd9": {
  "Type": "AWS::CloudWatch::Alarm",
  "Properties": {
    "ActionsEnabled": "true",
    "AlarmDescription": {
      "Fn::Join": [
        "",
        [
          "DO NOT EDIT OR DELETE. For TargetTrackingScaling policy arn:aws:autoscaling:",
          {
            "Ref": "AWS::Region"
          },
          ":",
          {
            "Ref": "AWS::AccountId"
          },
          ":scalingPolicy:7558858e-b58c-455c-be34-6de387a0c6d1:resource/dynamodb/table/MyCrossConfig:policyName/DynamoDBReadCapacityUtilization:table/MyCrossConfig."
        ]
      ]
    },
    "ComparisonOperator": "LessThanThreshold",
    "EvaluationPeriods": "3",
    "MetricName": "ProvisionedReadCapacityUnits",
    "Namespace": "AWS/DynamoDB",
    "Period": "300",
    "Statistic": "Average",
    "Threshold": "5.0",
    "AlarmActions": [
      {
        "Fn::Join": [
          "",
          [
            "arn:aws:autoscaling:",
            {
              "Ref": "AWS::Region"
            },
            ":",
            {
              "Ref": "AWS::AccountId"
            },
            ":scalingPolicy:7558858e-b58c-455c-be34-6de387a0c6d1:resource/dynamodb/table/MyCrossConfig:policyName/DynamoDBReadCapacityUtilization:table/MyCrossConfig"
          ]
        ]
      }
    ],
    "Dimensions": [
      {
        "Name": "TableName",
        "Value": "MyCrossConfig"
      }
    ]
  }
}

s3 bucket AWS::S3::Bucket

  • 此示例创建名为configbucket- + AWS::AccountId
  • 的Bucket
"ConfigBucket": {
  "Type": "AWS::S3::Bucket",
  "Properties": {
    "BucketName": {
      "Fn::Join": [
        "",
        [
          "configbucket-",
          {
            "Ref": "AWS::AccountId"
          }
        ]
      ]
    }
  },
  "DeletionPolicy": "Delete"
}

现在你需要完全放置,在模板中做出引用,等等。

希望有所帮助!

答案 2 :(得分:0)

我的猜测是你可以将CloudFormation用于这样的应用程序,但我也不熟悉。

我所取得的成功是编写利用awscli实用程序来完成此任务的小脚本。此外,您还需要一个策略来设置新环境。

通常,我所做的是在DynamoDB表和S3存储桶上使用不同的后缀来表示不同的环境。 Lambda + API Gateway具有不同版本的概念,因此您也可以支持不同的环境。

对于非常小的项目,我甚至设置了我的Dynamo架构来支持单个表中的许多环境。这对宠物或小项目来说很不错,因为它更便宜。

答案 3 :(得分:0)

构建我自己的SDK用于部署,它正在制作中......

https://github.com/LucLaverdure/aws-sdk

您需要在容器中使用以下shell脚本:

export.sh
import.sh

要求:

  • AWS CLI
  • 的Python
  • PIP
  • NPM
  • JQ
相关问题