рдореА рдорд╛рдЭреНрдпрд╛ рдЙрд░реНрд╡рд░рд┐рдд рдЖрдпреБрд╖реНрдпрд╛рд╕рд╛рдареА рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рдирд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рдЪреЗ рд╣реЗ 6 рдзрдбреЗ рд╢рд┐рдХрд▓реЛ.

рд╕реЛрдмрдд рдХрд╛рдо рдХрд░реВ рд▓рд╛рдЧрд▓реЛ рдврдЧ 4 рд╡рд░реНрд╖рд╛рдВрдкреВрд░реНрд╡реА. рддреЗрд╡реНрд╣рд╛рдкрд╛рд╕реВрди рдореА рдмрд░реНтАНрдпрд╛рдЪ рдкрд╛рдпрд╛рднреВрдд рд╕реБрд╡рд┐рдзрд╛ рдореЛрдбрд▓реНрдпрд╛ рдЖрд╣реЗрдд, рдЕрдЧрджреА рддреНрдпрд╛рд╣реА рдЬреНрдпрд╛ рдЖрдзреАрдЪ рдЙрддреНрдкрд╛рджрдирд╛рдд рд╣реЛрддреНрдпрд╛. рдкрдг рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдореА рдХрд╛рд╣реАрддрд░реА рдЧрдбрдмрдб рдХреЗрд▓реА, рдореА рдХрд╛рд╣реАрддрд░реА рдирд╡реАрди рд╢рд┐рдХрд▓реЛ. рдпрд╛ рдЕрдиреБрднрд╡рд╛рддреВрди, рдореА рд╢рд┐рдХрд▓реЗрд▓реЗ рдХрд╛рд╣реА рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдзрдбреЗ рд╢реЗрдЕрд░ рдХрд░реЗрди.

рдореА рдорд╛рдЭреНрдпрд╛ рдЙрд░реНрд╡рд░рд┐рдд рдЖрдпреБрд╖реНрдпрд╛рд╕рд╛рдареА рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рдирд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рдЪреЗ рд╣реЗ 6 рдзрдбреЗ рд╢рд┐рдХрд▓реЛ.

рдзрдбрд╛ 1: рддреЗ рддреИрдирд╛рдд рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдмрджрд▓рд╛рдВрдЪреА рдЪрд╛рдЪрдгреА рдШреНрдпрд╛

рдореА рдХрд╛рдо рдХрд░рд╛рдпрд▓рд╛ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реНрдпрд╛рд╡рд░ рд▓рдЧреЗрдЪрдЪ рд╣рд╛ рдзрдбрд╛ рд╢рд┐рдХрд▓реЛ рдврдЧ. рддреЗрд╡реНрд╣рд╛ рдореА рдиреЗрдордХреЗ рдХрд╛рдп рддреЛрдбрд▓реЗ рддреЗ рдорд▓рд╛ рдЖрдард╡рдд рдирд╛рд╣реА, рдкрд░рдВрддреБ рдорд▓рд╛ рдирд┐рд╢реНрдЪрд┐рддрдкрдгреЗ рдЖрдард╡рддреЗ рдХреА рдореА рдХрдорд╛рдВрдб рд╡рд╛рдкрд░рд▓реА рд╣реЛрддреА aws рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рдЕрдкрдбреЗрдЯ. рд╣реА рдХрдорд╛рдВрдб рддреИрдирд╛рдд рдХрд░рдгреНрдпрд╛рдд рдпреЗрдгрд╛рд░реНтАНрдпрд╛ рдмрджрд▓рд╛рдВрдЪреЗ рдХреЛрдгрддреЗрд╣реА рдкреНрд░рдорд╛рдгреАрдХрд░рдг рди рдХрд░рддрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ рд░реЛрд▓ рдЖрдЙрдЯ рдХрд░рддреЗ. рд╕рд░реНрд╡ рдмрджрд▓ рдЙрдкрдпреЛрдЬрд┐рдд рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рддреБрдореНрд╣реА рдХрд╛ рддрдкрд╛рд╕рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗрдд рдпрд╛рд╕рд╛рдареА рдХреЛрдгрддреЗрд╣реА рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЕрд╕реЗ рдорд▓рд╛ рд╡рд╛рдЯрдд рдирд╛рд╣реА.

рдпрд╛ рдЕрдкрдпрд╢рд╛рдирдВрддрд░ рдореА рд▓рдЧреЗрдЪ рдмрджрд▓рд▓реЗ рддреИрдирд╛рддреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди, рдЕрдкрдбреЗрдЯ рдХрдорд╛рдВрдбрд▓рд╛ рдХрдорд╛рдВрдбрдиреЗ рдмрджрд▓рдгреЗ рддрдпрд╛рд░-рдмрджрд▓-рд╕рдВрдЪ

# OPERATION is either "UPDATE" or "CREATE"
changeset_id=$(aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "$OPERATION" 
    --parameters "$PARAMETERS" 
    --output text 
    --query Id)

aws cloudformation wait 
    change-set-create-complete --change-set-name "$changeset_id"

рдПрдХрджрд╛ рдЪреЗрдВрдЬрд╕реЗрдЯ рддрдпрд╛рд░ рдЭрд╛рд▓реНрдпрд╛рдирдВрддрд░, рддреНрдпрд╛рдЪрд╛ рд╡рд┐рджреНрдпрдорд╛рди рд╕реНрдЯреЕрдХрд╡рд░ рдХреЛрдгрддрд╛рд╣реА рдкрд░рд┐рдгрд╛рдо рд╣реЛрдд рдирд╛рд╣реА. рдЕрдкрдбреЗрдЯ рдХрдорд╛рдВрдбрдЪреНрдпрд╛ рд╡рд┐рдкрд░реАрдд, рдЪреЗрдВрдЬрд╕реЗрдЯ рджреГрд╖реНрдЯреАрдХреЛрди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддреИрдирд╛рддреА рдЯреНрд░рд┐рдЧрд░ рдХрд░рдд рдирд╛рд╣реА. рддреНрдпрд╛рдРрд╡рдЬреА, рддреЗ рдмрджрд▓рд╛рдВрдЪреА рд╕реВрдЪреА рддрдпрд╛рд░ рдХрд░рддреЗ рдЬреНрдпрд╛рдЪреЗ рддреБрдореНрд╣реА рдЙрдкрдпреЛрдЬрди рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдХрд░реВ рд╢рдХрддрд╛. рддреБрдореНрд╣реА aws рдХрдиреНрд╕реЛрд▓ рдЗрдВрдЯрд░рдлреЗрд╕рдордзреАрд▓ рдмрджрд▓ рдкрд╛рд╣реВ рд╢рдХрддрд╛. рдкрд░рдВрддреБ рдЖрдкрдг рд╕рд░реНрд╡рдХрд╛рд╣реА рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдХрд░рдгреНрдпрд╛рд╕ рдкреНрд░рд╛рдзрд╛рдиреНрдп рджреЗрдд рдЕрд╕рд▓реНрдпрд╛рд╕, CLI рдордзреНрдпреЗ рддреЗ рддрдкрд╛рд╕рд╛:

# this command is presented only for demonstrational purposes.
# the real command should take pagination into account
aws cloudformation describe-change-set 
    --change-set-name "$changeset_id" 
    --query 'Changes[*].ResourceChange.{Action:Action,Resource:ResourceType,ResourceId:LogicalResourceId,ReplacementNeeded:Replacement}' 
    --output table

рдпрд╛ рдХрдорд╛рдВрдбрдиреЗ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрдЙрдЯрдкреБрдЯ рддрдпрд╛рд░ рдХреЗрд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ:

--------------------------------------------------------------------
|                         DescribeChangeSet                        |
+---------+--------------------+----------------------+------------+
| Action  | ReplacementNeeded  |      Resource        | ResourceId |
+---------+--------------------+----------------------+------------+
|  Modify | True               |  AWS::ECS::Cluster   |  MyCluster |
|  Replace| True               |  AWS::RDS::DBInstance|  MyDB      |
|  Add    | None               |  AWS::SNS::Topic     |  MyTopic   |
+---------+--------------------+----------------------+------------+

рдЬреЗрдереЗ рдХреНрд░рд┐рдпрд╛ рдЖрд╣реЗ рддреНрдпрд╛ рдмрджрд▓рд╛рдВрдХрдбреЗ рд╡рд┐рд╢реЗрд╖ рд▓рдХреНрд╖ рджреНрдпрд╛ рдкреБрдирд░реНрд╕реНрдерд┐рдд рдХрд░рд╛, рд╣рдЯрд╡рд╛ рдХрд┐рдВрд╡рд╛ рдХреБрдареЗ рдмрджрд▓реА рдЖрд╡рд╢реНрдпрдХ - рдЦрд░реЗ. рд╣реЗ рд╕рд░реНрд╡рд╛рдд рдзреЛрдХрд╛рджрд╛рдпрдХ рдмрджрд▓ рдЖрд╣реЗрдд рдЖрдгрд┐ рд╕рд╣рд╕рд╛ рдорд╛рд╣рд┐рддреА рдЧрдорд╛рд╡рддрд╛рдд.

рдПрдХрджрд╛ рдмрджрд▓рд╛рдВрдЪреЗ рдкреБрдирд░рд╛рд╡рд▓реЛрдХрди рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рддреЗ рддреИрдирд╛рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд

aws cloudformation execute-change-set --change-set-name "$changeset_id"

operation_lowercase=$(echo "$OPERATION" | tr '[:upper:]' '[:lower:]')
aws cloudformation wait "stack-${operation_lowercase}-complete" 
    --stack-name "$STACK_NAME"

рдзрдбрд╛ 2: рд╕реНрдЯреЗрдЯрдлреБрд▓ рд╕рдВрд╕рд╛рдзрдиреЗ рдмрджрд▓рдгреНрдпрд╛рдкрд╛рд╕реВрди рдХрд┐рдВрд╡рд╛ рдХрд╛рдвреВрди рдЯрд╛рдХрдгреНрдпрд╛рдкрд╛рд╕реВрди рд░реЛрдЦрдгреНрдпрд╛рд╕рд╛рдареА рд╕реНрдЯреЕрдХ рдзреЛрд░рдг рд╡рд╛рдкрд░рд╛

рдХрдзреАрдХрдзреА рдлрдХреНрдд рдмрджрд▓ рдкрд╛рд╣рдгреЗ рдкреБрд░реЗрд╕реЗ рдирд╕рддреЗ. рдЖрдкрдг рд╕рд░реНрд╡ рдорд╛рдирд╡ рдЖрд╣реЛрдд рдЖрдгрд┐ рдЖрдкрдг рд╕рд░реНрд╡ рдЪреБрдХрд╛ рдХрд░рддреЛ. рдЖрдореНрд╣реА рдЪреЗрдВрдЬрд╕реЗрдЯреНрд╕ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рдереЛрдбреНрдпрд╛рдЪ рд╡реЗрд│рд╛рдд, рдорд╛рдЭреНрдпрд╛ рдЯреАрдордореЗрдЯрдиреЗ рдирдХрд│рдд рдПрдХ рдЙрдкрдпреЛрдЬрди рдХреЗрд▓реЗ рдЬреНрдпрд╛рдореБрд│реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдкрдбреЗрдЯ рдЭрд╛рд▓рд╛. рдХрд╛рд╣реАрд╣реА рд╡рд╛рдИрдЯ рдШрдбрд▓реЗ рдирд╛рд╣реА рдХрд╛рд░рдг рддреЗ рдЪрд╛рдЪрдгреАрдЪреЗ рд╡рд╛рддрд╛рд╡рд░рдг рд╣реЛрддреЗ.

рдЬрд░реА рдЖрдордЪреНрдпрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕рдиреА рдмрджрд▓рд╛рдВрдЪреА рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреЗрд▓реА рдЖрдгрд┐ рдкреБрд╖реНрдЯреАрдХрд░рдгрд╛рд╕рд╛рдареА рд╡рд┐рдЪрд╛рд░рд▓реЗ рддрд░реАрд╣реА, рдмрджрд▓рд╛ рдмрджрд▓ рд╡рдЧрд│рдгреНрдпрд╛рдд рдЖрд▓рд╛ рдХрд╛рд░рдг рдмрджрд▓рд╛рдВрдЪреА рд╕реВрдЪреА рдЗрддрдХреА рдореЛрдареА рд╣реЛрддреА рдХреА рддреА рд╕реНрдХреНрд░реАрдирд╡рд░ рдмрд╕рдд рдирд╛рд╣реА. рдЖрдгрд┐ рд╣реЗ рдЪрд╛рдЪрдгреА рд╡рд╛рддрд╛рд╡рд░рдгрд╛рдд рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЕрджреНрдпрддрди рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рдмрджрд▓рд╛рдВрдХрдбреЗ рдЬрд╛рд╕реНрдд рд▓рдХреНрд╖ рджрд┐рд▓реЗ рдЧреЗрд▓реЗ рдирд╛рд╣реА.

рдЕрд╢реА рд╕рдВрд╕рд╛рдзрдиреЗ рдЖрд╣реЗрдд рдЬреА рддреБрдореНрд╣реА рдХрдзреАрд╣реА рдмрджрд▓реВ рдХрд┐рдВрд╡рд╛ рдХрд╛рдвреВ рдЗрдЪреНрдЫрд┐рдд рдирд╛рд╣реА. рдпрд╛ рд╕реНрдЯреЗрдЯрдлреБрд▓ рд╕реЗрд╡рд╛ рдЖрд╣реЗрдд, рдЬрд╕реЗ рдХреА RDS рдбреЗрдЯрд╛рдмреЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд┐рдВрд╡рд╛ рдЗрд▓реЕрд╕реНрдЯрд┐рдХрд╕рд░реНрдЪ рдХреНрд▓рд╕реНрдЯрд░ рдЗ. рдЬрд░ рдСрдкрд░реЗрд╢рди рдХреЗрд▓реЗ рдЬрд╛рдд рдЕрд╕реЗрд▓ рддрд░ рдЕрд╢рд╛ рд╕рдВрд╕рд╛рдзрдиреЗ рд╣рдЯрд╡рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реНрдпрд╛рд╕ aws рдЖрдкреЛрдЖрдк рддреИрдирд╛рддреА рдирд╛рдХрд╛рд░реЗрд▓ рддрд░ рдЪрд╛рдВрдЧрд▓реЗ рд╣реЛрдИрд▓. рд╕реБрджреИрд╡рд╛рдиреЗ, рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рдирдордзреНрдпреЗ рдЕрдВрдЧрднреВрдд рдорд╛рд░реНрдЧ рдЖрд╣реЗ. рдпрд╛рд▓рд╛ рд╕реНрдЯреЕрдХ рдкреЙрд▓рд┐рд╕реА рдореНрд╣рдгрддрд╛рдд рдЖрдгрд┐ рддреБрдореНрд╣реА рддреНрдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рд╡рд╛рдЪреВ рд╢рдХрддрд╛ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг:

STACK_NAME=$1
RESOURCE_ID=$2

POLICY_JSON=$(cat <<EOF
{
    "Statement" : [{
        "Effect" : "Deny",
        "Action" : [
            "Update:Replace",
            "Update:Delete"
        ],
        "Principal": "*",
        "Resource" : "LogicalResourceId/$RESOURCE_ID"
    }]
}
EOF
)

aws cloudformation set-stack-policy --stack-name "$STACK_NAME" 
    --stack-policy-body "$POLICY_JSON"

рдзрдбрд╛ 3: рдЧреБрдкреНрдд рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕рд╕рд╣ рд╕реНрдЯреЕрдХ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛рдирд╛ UsePreviousValue рд╡рд╛рдкрд░рд╛

рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣реА RDS mysql рдЕрд╕реНрддрд┐рддреНрд╡ рддрдпрд╛рд░ рдХрд░рддрд╛, рддреЗрд╡реНрд╣рд╛ AWS рд▓рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ MasterUsername рдЖрдгрд┐ MasterUserPassword рдкреНрд░рджрд╛рди рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рддреЗ. рд╕реНрддреНрд░реЛрдд рдХреЛрдбрдордзреНрдпреЗ рд░рд╣рд╕реНрдпреЗ рди рдареЗрд╡рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ рдЕрд╕рд▓реНрдпрд╛рдиреЗ рдЖрдгрд┐ рдорд▓рд╛ рдкреВрд░реНрдгрдкрдгреЗ рд╕рд░реНрд╡рдХрд╛рд╣реА рд╕реНрд╡рдпрдВрдЪрд▓рд┐рдд рдХрд░рд╛рдпрдЪреЗ рд╣реЛрддреЗ, рдореА рдПрдХ "рд╕реНрдорд╛рд░реНрдЯ рдпрдВрддреНрд░рдгрд╛" рд▓рд╛рдЧреВ рдХреЗрд▓реА рдЬрд┐рдереЗ рддреИрдирд╛рдд рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓реНрд╕ s3 рд╡рд░реВрди рдорд┐рд│рддреАрд▓ рдЖрдгрд┐ рдЬрд░ рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓реНрд╕ рд╕рд╛рдкрдбрд▓реЗ рдирд╛рд╣реАрдд рддрд░ рдирд╡реАрди рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗ рдЬрд╛рддреАрд▓ рдЖрдгрд┐ s3 рдордзреНрдпреЗ рд╕рдВрдЧреНрд░рд╣рд┐рдд.

рд╣реА рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓ рдирдВрддрд░ рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рдХреНрд░рд┐рдПрдЯ-рдЪреЗрдВрдЬ-рд╕реЗрдЯ рдХрдорд╛рдВрдбрд▓рд╛ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдореНрд╣рдгреВрди рдкрд╛рд╕ рдХреЗрд▓реА рдЬрд╛рддреАрд▓. рд╕реНрдХреНрд░рд┐рдкреНрдЯрдЪрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░рдд рдЕрд╕рддрд╛рдирд╛, рдЕрд╕реЗ рдШрдбрд▓реЗ рдХреА s3 рдЪреЗ рдХрдиреЗрдХреНрд╢рди рддреБрдЯрд▓реЗ рдЖрдгрд┐ рдорд╛рдЭреНрдпрд╛ тАЬрд╕реНрдорд╛рд░реНрдЯ рдореЗрдХреЕрдирд┐рдЭрдотАЭ рдиреЗ рддреЗ рдирд╡реАрди рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рд┐рдЧреНрдирд▓ рдорд╛рдирд▓реЗ.

рдЬрд░ рдореА рд╣реА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЙрддреНрдкрд╛рджрдирд╛рдордзреНрдпреЗ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА рдЖрдгрд┐ рдХрдиреЗрдХреНрд╢рди рд╕рдорд╕реНрдпрд╛ рдкреБрдиреНрд╣рд╛ рдЖрд▓реА, рддрд░ рддреЗ рдирд╡реАрди рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓реНрд╕рд╕рд╣ рд╕реНрдЯреЕрдХ рдЕрджреНрдпрддрдирд┐рдд рдХрд░реЗрд▓. рдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд░рдгрд╛рдд, рдХрд╛рд╣реАрд╣реА рд╡рд╛рдИрдЯ рд╣реЛрдгрд╛рд░ рдирд╛рд╣реА. рддрдерд╛рдкрд┐, рдореА рд╣рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрди рд╕реЛрдбреВрди рджрд┐рд▓рд╛ рдЖрдгрд┐ рджреБрд╕рд░рд╛ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА, рдлрдХреНрдд рдПрдХрджрд╛рдЪ рдХреНрд░реЗрдбреЗрдиреНрд╢рд┐рдпрд▓ рдкреНрд░рджрд╛рди рдХреЗрд▓реЗ - рд╕реНрдЯреЕрдХ рддрдпрд╛рд░ рдХрд░рддрд╛рдирд╛. рдЖрдгрд┐ рдирдВрддрд░, рдЬреЗрд╡реНрд╣рд╛ рд╕реНрдЯреЕрдХрд▓рд╛ рдЕрдкрдбреЗрдЯ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рддреЗ, рддреЗрд╡реНрд╣рд╛ рдкреЕрд░рд╛рдореАрдЯрд░рдЪреЗ рдЧреБрдкреНрдд рдореВрд▓реНрдп рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреНрдпрд╛рдРрд╡рдЬреА, рдореА рдлрдХреНрдд рд╡рд╛рдкрд░рддреЛ PreviousValue=true рд╡рд╛рдкрд░рд╛:

aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "UPDATE" 
    --parameters "ParameterKey=MasterUserPassword,UsePreviousValue=true"

рдзрдбрд╛ 4: рд░реЛрд▓рдмреЕрдХ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рд╡рд╛рдкрд░рд╛

рдореА рдХрд╛рдо рдХреЗрд▓реЗрд▓реНрдпрд╛ рджреБрд╕рд░реНтАНрдпрд╛ рдЯреАрдордиреЗ рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░рд▓реЗ рдврдЧ, рдореНрд╣рдгрддрд╛рдд рд░реЛрд▓рдмреЕрдХ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди. рдореА рдЖрдзреА рддреЗ рдкрд╛рд╣рд┐рд▓реЗ рдирд╡реНрд╣рддреЗ рдЖрдгрд┐ рдкрдЯрдХрди рд▓рдХреНрд╖рд╛рдд рдЖрд▓реЗ рдХреА рддреЗ рдорд╛рдЭреЗ рд╕реНрдЯреЕрдХ рддреИрдирд╛рдд рдХрд░рдгреЗ рдЕрдзрд┐рдХ рдердВрдб рдХрд░реЗрд▓. рдЖрддрд╛ рдореА рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рд╡рд╛рдкрд░реВрди рдорд╛рдЭрд╛ рдХреЛрдб lambda рдХрд┐рдВрд╡рд╛ ECS рд╡рд░ рдЙрдкрдпреЛрдЬрд┐рдд рдХрд░рддреЛ рддреЗрд╡реНрд╣рд╛ рддреЗ рд╡рд╛рдкрд░рддреЛ.

рддреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ: рдЖрдкрдг рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рд╛ рдХреНрд▓рд╛рдЙрдбрд╡реЙрдЪ рдЕрд▓рд╛рд░реНрдо рдкреЕрд░рд╛рдореАрдЯрд░ рдордзреНрдпреЗ --рд░реЛрд▓рдмреЕрдХ-рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рдирдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣реА рдЪреЗрдВрдЬрд╕реЗрдЯ рддрдпрд╛рд░ рдХрд░рддрд╛. рдирдВрддрд░, рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣реА рдмрджрд▓рд╛рдВрдЪрд╛ рд╕рдВрдЪ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛, рддреЗрд╡реНрд╣рд╛ aws рдХрд┐рдорд╛рди рдПрдХ рдорд┐рдирд┐рдЯрд╛рд╕рд╛рдареА рдЕрд▓рд╛рд░реНрдордЪреЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рддреЗ. рдпрд╛ рд╡реЗрд│реА рдЕрд▓рд╛рд░реНрдордЪреА рд╕реНрдерд┐рддреА ALARM рдордзреНрдпреЗ рдмрджрд▓рд▓реНрдпрд╛рд╕ рддреЗ рддреИрдирд╛рддреА рдкрд░рдд рдЖрдгрддреЗ.

рдЦрд╛рд▓реА рдЯреЗрдореНрдкрд▓реЗрдЯ рдЙрддрд╛рд░рд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд╣реЗ рдврдЧрдЬреНрдпрд╛рдордзреНрдпреЗ рдореА рддрдпрд╛рд░ рдХрд░рддреЛ рдХреНрд▓рд╛рдЙрдбрд╡реЙрдЪ рдЕрд▓рд╛рд░реНрдо, рдЬреЗ рдХреНрд▓рд╛рдЙрдб рд▓реЙрдЧрдордзреАрд▓ рддреНрд░реБрдЯреАрдВрдЪреА рд╕рдВрдЦреНрдпрд╛ рдореНрд╣рдгреВрди рдХреНрд▓рд╛рдЙрдб рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдореЗрдЯреНрд░рд┐рдХрдЪрд╛ рдорд╛рдЧреЛрд╡рд╛ рдШреЗрддреЗ (рдореЗрдЯреНрд░рд┐рдХ рдпрд╛рджреНрд╡рд╛рд░реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗ рдЬрд╛рддреЗ MetricFilter):

Resources:
  # this metric tracks number of errors in the cloudwatch logs. In this
  # particular case it's assumed logs are in json format and the error logs are
  # identified by level "error". See FilterPattern
  ErrorMetricFilter:
    Type: AWS::Logs::MetricFilter
    Properties:
      LogGroupName: !Ref LogGroup
      FilterPattern: !Sub '{$.level = "error"}'
      MetricTransformations:
      - MetricNamespace: !Sub "${AWS::StackName}-log-errors"
        MetricName: Errors
        MetricValue: 1
        DefaultValue: 0

  ErrorAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmName: !Sub "${AWS::StackName}-errors"
      Namespace: !Sub "${AWS::StackName}-log-errors"
      MetricName: Errors
      Statistic: Maximum
      ComparisonOperator: GreaterThanThreshold
      Period: 1 # 1 minute
      EvaluationPeriods: 1
      Threshold: 0
      TreatMissingData: notBreaching
      ActionsEnabled: yes

рдЖрддрд╛ рдЧрдЬрд░ рдореНрд╣рдгреВрди рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ рд░реЛрд▓рдмреЕрдХ рдЯреВрд▓рдмреЙрдХреНрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддрд╛рдирд╛ рдЯреНрд░рд┐рдЧрд░:

ALARM_ARN=$1

ROLLBACK_TRIGGER=$(cat <<EOF
{
  "RollbackTriggers": [
    {
      "Arn": "$ALARM_ARN",
      "Type": "AWS::CloudWatch::Alarm"
    }
  ],
  "MonitoringTimeInMinutes": 1
}
EOF
)

aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "UPDATE" 
    --rollback-configuration "$ROLLBACK_TRIGGER"

рдзрдбрд╛ 5: рддреБрдореНрд╣реА рдЯреЗрдореНрдкрд▓реЗрдЯрдЪреА рдирд╡реАрдирддрдо рдЖрд╡реГрддреНрддреА рдЙрдкрдпреЛрдЬрд┐рдд рдХреЗрд▓реНрдпрд╛рдЪреА рдЦрд╛рддреНрд░реА рдХрд░рд╛

рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рдЯреЗрдореНрдкреНрд▓реЗрдЯрдЪреА рд╕рд░реНрд╡рд╛рдд рдХрдореА-рдирд╡реАрди рдЖрд╡реГрддреНрддреА рдЙрдкрдпреЛрдЬрд┐рдд рдХрд░рдгреЗ рд╕реЛрдкреЗ рдЖрд╣реЗ, рдкрд░рдВрддреБ рдЕрд╕реЗ рдХреЗрд▓реНрдпрд╛рдиреЗ рдмрд░реЗрдЪ рдиреБрдХрд╕рд╛рди рд╣реЛрдИрд▓. рд╣реЗ рдЖрдордЪреНрдпрд╛ рдмрд╛рдмрддреАрдд рдПрдХрджрд╛ рдШрдбрд▓реЗ: рдПрдХрд╛ рд╡рд┐рдХрд╕рдХрд╛рдиреЗ Git рдордзреАрд▓ рдирд╡реАрдирддрдо рдмрджрд▓ рдкреБрд╢ рдХреЗрд▓реЗ рдирд╛рд╣реАрдд рдЖрдгрд┐ рдирдХрд│рддрдкрдгреЗ рд╕реНрдЯреЕрдХрдЪреА рдорд╛рдЧреАрд▓ рдЖрд╡реГрддреНрддреА рддреИрдирд╛рдд рдХреЗрд▓реА. рдпрд╛рдореБрд│реЗ рд╣рд╛ рд╕реНрдЯреЕрдХ рд╡рд╛рдкрд░рдгрд╛рд▒реНрдпрд╛ рдНрдкреНрд▓рд┐рдХреЗрд╢рдирд╕рд╛рдареА рдбрд╛рдЙрдирдЯрд╛рдЗрдо рдЭрд╛рд▓рд╛.

рд╢рд╛рдЦрд╛ рдЕрджреНрдпрдпрд╛рд╡рдд рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рд╣реЗ рдкрд╛рд╣рдгреНрдпрд╛рд╕рд╛рдареА рдЪреЗрдХ рдЬреЛрдбрдгреНрдпрд╛рдЗрддрдХреЗ рд╕реЛрдкреЗ рдЖрд╣реЗ (рдЧрд┐рдЯ рд╣реЗ рддреБрдордЪреЗ рдЖрд╡реГрддреНрддреА рдирд┐рдпрдВрддреНрд░рдг рд╕рд╛рдзрди рдЖрд╣реЗ рдЕрд╕реЗ рдЧреГрд╣реАрдд рдзрд░реВрди):

git fetch
HEADHASH=$(git rev-parse HEAD)
UPSTREAMHASH=$(git rev-parse master@{upstream})

if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then
   echo "Branch is not up to date with origin. Aborting"
   exit 1
fi

рдзрдбрд╛ 6: рдЪрд╛рдХ рдкреБрдиреНрд╣рд╛ рд╢реЛрдзреВ рдирдХрд╛

рд╕рд╣ рддреИрдирд╛рдд рдХреЗрд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ рд╡рд╛рдЯреВ рд╢рдХрддреЗ рдврдЧ - рд╣реЗ рд╕реЛрдкреЗ рдЖрд╣реЗ. рддреБрдореНрд╣рд╛рд▓рд╛ рдлрдХреНрдд aws cli рдХрдорд╛рдВрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдгрд╛рд░реНтАНрдпрд╛ рдмреЕрд╢ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ.

4 рд╡рд░реНрд╖рд╛рдВрдкреВрд░реНрд╡реА рдореА aws рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рдХреНрд░рд┐рдПрдЯ-рд╕реНрдЯреЕрдХ рдХрдорд╛рдВрдб рдирд╛рд╡рд╛рдЪреНрдпрд╛ рд╕реЛрдкреНрдпрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯрд╕рд╣ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА. рд▓рд╡рдХрд░рдЪ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЛрдкреА рд░рд╛рд╣рд┐рд▓реА рдирд╛рд╣реА. рд╢рд┐рдХрд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдзрдбреНрдпрд╛рдореБрд│реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдЧреБрдВрддрд╛рдЧреБрдВрддреАрдЪреА рд╣реЛрдд рдЧреЗрд▓реА. рд╣реЗ рдХреЗрд╡рд│ рдХрдареАрдгрдЪ рдирд╡реНрд╣рддреЗ рддрд░ рдмрдЧрд╛рдВрдиреА рднрд░рд▓реЗрд▓реЗ рд╣реЛрддреЗ.

рдореА рд╕рдзреНрдпрд╛ рдПрдХрд╛ рдЫреЛрдЯреНрдпрд╛ рдЖрдпрдЯреА рд╡рд┐рднрд╛рдЧрд╛рдд рдХрд╛рдо рдХрд░рддреЛ. рдЕрдиреБрднрд╡рд╛рдиреЗ рджрд░реНрд╢рд╡рд┐рд▓реЗ рдЖрд╣реЗ рдХреА рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рд╕реНрдЯреЕрдХ рддреИрдирд╛рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрдШрд╛рдЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ рдорд╛рд░реНрдЧ рдЖрд╣реЗ. рдЖрдгрд┐ рддреЗ рд╡рд╛рдИрдЯ рдЖрд╣реЗ. рд╕рд░реНрд╡рд╛рдВрдиреА рд╕рдорд╛рди рджреГрд╖реНрдЯреАрдХреЛрди рдШреЗрддрд▓рд╛ рддрд░ рдмрд░реЗ рд╣реЛрдИрд▓. рд╕реБрджреИрд╡рд╛рдиреЗ, рдХреНрд▓рд╛рдЙрдбрдлреЙрд░реНрдореЗрд╢рди рд╕реНрдЯреЕрдХ рддреИрдирд╛рдд рдЖрдгрд┐ рдХреЙрдиреНрдлрд┐рдЧрд░ рдХрд░рдгреНрдпрд╛рдд рдорджрдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдиреЗрдХ рд╕рд╛рдзрдиреЗ рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗрдд.

рд╣реЗ рдзрдбреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдЪреБрдХрд╛ рдЯрд╛рд│рдгреНрдпрд╛рд╕ рдорджрдд рдХрд░рддреАрд▓.

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛