2017-07-17 83 views
1

我有以下的CloudFormation模板。 (這是默認的基於關閉在AWS運行LAMBDA C#的Web API創建的模板,但可能不相關。)CloudFormation:創建資源,如果他們不存在,但不刪除它們

它創建了一個AWS lambda函數。如果現有資源的名稱不作爲參數提供,模板還會創建IAM角色和DynamoDB表。

那部分工作。如果沒有爲角色和表提供名稱,則會創建它們。

當我第二次運行模板執行更新時存在問題:此時,我的角色和表已存在,因此我提供了名稱作爲參數。但是,當CloudFormation第二次運行時,首次創建的資源(角色和表)將被刪除。

是否有某種方法可以設置模板,使其在不存在的情況下創建新資源,但是如果它們已經存在則不會將其刪除?

我沒有做很多與CloudFormation,但我沒去,可通過文檔。我發現的最接近是setting a stack policy,但它似乎並沒有成爲模板的一部分。看起來事實之後,我必須在管理控制檯中執行此操作。

{ 
    "AWSTemplateFormatVersion" : "2010-09-09", 
    "Transform" : "AWS::Serverless-2016-10-31", 
    "Description" : "...", 

    "Parameters" : { 
    "ShouldCreateTable" : { 
     "Type" : "String",   
     "AllowedValues" : ["true", "false"], 
     "Description" : "If true then the underlying DynamoDB table will be created with the CloudFormation stack." 
    }, 
    "TableName" : { 
     "Type" : "String", 
     "Description" : "Name of DynamoDB table to be used for underlying data store. If left blank a new table will be created.", 
     "MinLength" : "0" 
    }, 
    "ShouldCreateRole" : { 
     "Type" : "String",   
     "AllowedValues" : ["true", "false"], 
     "Description" : "If true then the role for the Lambda function will be created with the CloudFormation stack." 
    }, 
    "RoleARN" : { 
     "Type" : "String", 
     "Description" : "ARN of the IAM Role used to run the Lambda function. If left blank a new role will be created.", 
     "MinLength" : "0" 
    } 
    }, 

    "Conditions" : { 
    "CreateDynamoTable" : {"Fn::Equals" : [{"Ref" : "ShouldCreateTable"}, "true"]}, 
    "TableNameGenerated" : {"Fn::Equals" : [{"Ref" : "TableName"}, ""]}, 
    "CreateRole":{"Fn::Equals" : [{"Ref" : "ShouldCreateRole"}, "true"]}, 
    "RoleGenerated" : {"Fn::Equals" : [{"Ref" : "RoleARN"}, ""]} 
    }, 

    "Resources" : { 

    "Get" : { 
     "Type" : "AWS::Serverless::Function", 
     "Properties": { 
     ... 
     "Role": {"Fn::If" : ["CreateRole", {"Fn::GetAtt":["LambdaRole", "Arn"]}, {"Ref":"RoleARN"}]}, 
     "Environment" : { 
      "Variables" : { 
      "AppDynamoTable" : { "Fn::If" : ["CreateDynamoTable", {"Ref":"DynamoTable"}, { "Ref" : "TableName" } ] } 
      } 
     }, 
     ... 
     } 
    }, 

    "LambdaRole":{ 
     "Type":"AWS::IAM::Role", 
     "Condition":"CreateRole", 
     "Properties":{ 
      "ManagedPolicyArns":["arn:aws:iam::aws:policy/AWSLambdaFullAccess"], 
      "AssumeRolePolicyDocument": { 
       "Version" : "2012-10-17", 
       "Statement": [ { 
        "Effect": "Allow", 
        "Principal": { 
        "Service": [ "lambda.amazonaws.com" ] 
        }, 
        "Action": [ "sts:AssumeRole" ] 
       } ] 
      }, 
      "Policies": [ { 
       "PolicyName": "root", 
       "PolicyDocument": { 
         "Version": "2012-10-17", 
         "Statement": [ 
          { 
           "Effect": "Allow", 
           "Action": [ 
            "dynamodb:Query", 
            "dynamodb:Scan", 
            "dynamodb:PutItem", 
            "dynamodb:GetItem", 
            "dynamodb:UpdateItem", 
            "dynamodb:DeleteItem", 
            "logs:CreateLogGroup", 
            "logs:CreateLogStream", 
            "logs:PutLogEvents" 
           ], 
           "Resource": [ 
            "*" 
           ] 
          } 
         ] 
        } 
       } 
      ] 
     } 
    }, 

    "DynamoTable" : { 
     "Type" : "AWS::DynamoDB::Table", 
     "Condition" : "CreateDynamoTable", 
     "Properties" : { 
      "TableName" : { "Fn::If" : ["TableNameGenerated", {"Ref" : "AWS::NoValue" }, { "Ref" : "TableName" } ] }, 
      "AttributeDefinitions": [ 
       { "AttributeName" : "id", "AttributeType" : "S" } 
      ], 
      "KeySchema" : [ 
       { "AttributeName" : "id", "KeyType" : "HASH"} 
      ],   
      "ProvisionedThroughput" : { "ReadCapacityUnits" : "5", "WriteCapacityUnits" : "5" } 
     } 
    } 
    }, 

    "Outputs" : { 
    "UnderlyingDynamoTable" : { 
     "Value" : { "Fn::If" : ["CreateDynamoTable", {"Ref":"DynamoTable"}, { "Ref" : "TableName" } ] } 
    }, 
    "LambdaRole" : { 
     "Value" : {"Fn::If" : ["CreateRole", {"Fn::GetAtt":["LambdaRole", "Arn"]}, {"Ref":"RoleARN"} ] } 
    } 
    } 
} 

我可以刪除創建步驟和API網關之前手動創建資源,但它似乎像什麼,我要做的應該是可能的。

回答

2

當您更新現有堆棧時,請勿更改參數。因此,即使當你更新堆棧,ShouldCreateTabletrue

是的,當一個表已經存在,但你需要這樣做時,更新你的堆棧來說「創建表」似乎是違反直覺的。

原因是這樣的:

  1. 在創建堆棧,您可以設置ShouldCreateTabletrue,並且模板應用於它的條件邏輯,並創建爲它自己的管理資源表。
  2. 更新堆棧時,您將ShouldCreateTable設置爲false,並且該模板將其應用於條件邏輯並確定您不再需要託管表,因爲您現在正在提供自己的託管表。資源應該被刪除。它不承認表格是相同的。

使用您的模板,只能說ShouldCreateTable == false如果你提供自己的表您創建

相關問題