Ansible Cloudformation,如果资源已经存在,如何不破解?

时间:2018-02-05 19:01:22

标签: amazon-web-services amazon-cloudformation

我有以下AWS Cloudformation配置,它设置了S3,存储库。

当我通过ansible playbook运行时,第二次运行playbook时会发生这种情况

AWS::ECR::Repository Repository CREATE_FAILED: production-app-name already exists
etc

我怎样才能这样做,以便在多次运行时,它会保留现有的s3和存储库,而不仅仅是炸毁? (我假设参数"DeletionPolicy": "Retain",会这样做)

我想要实现的目标:

如果我运行这个100x,我想要与运行#1之后相同的资源状态。我不希望任何资源被删除/删除任何数据。

{


 "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Pre-reqs for Elastic Beanstalk application",
  "Parameters": {
    "BucketName": {
      "Type": "String",
      "Description": "S3 Bucket name"
    },
    "RepositoryName": {
      "Type": "String",
      "Description": "ECR Repository name"
    }
  },
  "Resources": {
    "Bucket": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain",
      "Properties": {
        "BucketName": { "Fn::Join": [ "-", [
          { "Ref": "BucketName" },
          { "Ref": "AWS::Region" }
        ]]}
      }
    },
    "Repository": {
      "Type": "AWS::ECR::Repository",
      "DeletionPolicy": "Retain",
      "Properties": {
        "RepositoryName": { "Ref": "RepositoryName" }
      }
    }
  },
  "Outputs": {
    "S3Bucket": {
      "Description": "Full S3 Bucket name",
      "Value": { "Ref": "Bucket" }
    },
    "Repository": {
      "Description": "ECR Repo",
      "Value": { "Fn::Join": [ "/", [
        {
          "Fn::Join": [ ".", [
            { "Ref": "AWS::AccountId" },
            "dkr",
            "ecr",
            { "Ref": "AWS::Region" },
            "amazonaws.com"
          ]]
        },
        { "Ref": "Repository" }
      ]]}
    }
  }
}

编辑:

在运行两次时出现类似问题的数据库

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "DBPassword": {
            "MinLength": "8",
            "NoEcho": true,
            "Type": "String"
        },
        "Environment": {
            "MinLength": "1",
            "Type": "String"
        },
        "DBName": {
            "Type": "String",
            "Description": "DBName"
        },
        "DBInstanceIdentifier": {
            "Type": "String",
            "Description": "DBInstanceIdentifier"
        },
        "DBPort": {
            "Type": "String",
            "Description": "DBPort"
        },
        "DBUsername": {
            "Type": "String",
            "Description": "DBName"
        }
    },
    "Outputs": {
        "Url": {
            "Value": {
                "Fn::Sub": "postgres://${DBUsername}:${DBPassword}@${Instance.Endpoint.Address}:${Instance.Endpoint.Port}/${DBName}"
            }
        }
    },
    "Resources": {
        "Instance": {
            "Type": "AWS::RDS::DBInstance",
            "DeletionPolicy": "Retain",
            "Properties": {
                "AllocatedStorage": "10",
                "DBInstanceClass": "db.t2.micro",
                "DBInstanceIdentifier": {"Ref": "DBInstanceIdentifier"},
                "DBName": {
                    "Ref": "DBName"
                },
                "Engine": "postgres",
                "EngineVersion": "9.6.6",
                "MasterUsername": {
                    "Ref": "DBUsername"
                },
                "MasterUserPassword": {
                    "Ref": "DBPassword"
                },
                "MultiAZ": "false",
                "Port": {
                    "Ref": "DBPort"
                },
                "PubliclyAccessible": "false",
                "StorageType": "gp2"
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

RepositoryName中的字段AWS::ECR::Repository实际上不是必需的,我建议不要指定一个。通过让 CloudFormation 为存储库动态分配唯一名称,您将避免冲突。

如果您以后想要使用存储库名称,例如:在任务定义中,您可以像"Ref"一样使用{ "Ref": "Repository" }函数来提取由 CloudFormation <生成的唯一名称/ em>的。

至于 RDS实例的问题,tt归结为硬编码资源名称的相同问题。

使用retain会使资源保持活动状态,但 CloudFormation 将不再对其进行管理,这是一个很大的问题。

确保在进行更新时永远不要修改需要资源“替换”的参数。文档始终说明参数更改将产生何种更新。

enter image description here 图片取自(here

如果您确实需要更改需要替换的参数。使用适配器参数创建新资源,迁移数据库中的任何数据或 ECR存储库,然后从模板中删除旧资源。如果您不需要迁移任何内容,请确保您没有硬编码名称,并让 CloudFormation 执行替换。