เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฎเบฝเบ™เบฎเบนเป‰ 6 เบšเบปเบ”เบฎเบฝเบ™เบ™เบตเป‰เบ‚เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš cloudformation เบชเปเบฒเบฅเบฑเบšเบชเปˆเบงเบ™เบ—เบตเปˆเป€เบซเบผเบทเบญเบ‚เบญเบ‡เบŠเบตเบงเบดเบ”เบ‚เบญเบ‡เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒ.

เบ‚เป‰เบญเบเป€เบฅเบตเปˆเบกเป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš เบ‚เปเป‰เบกเบนเบ™เบ‚เปˆเบฒเบงเบชเบฒเบ™เบŸเบฑเบ‡ 4 เบ›เบตเบเปˆเบญเบ™. เบ•เบฑเป‰เบ‡โ€‹เปเบ•เปˆโ€‹เบ™เบฑเป‰เบ™โ€‹เบกเบฒโ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เป„เบ”เป‰โ€‹เบ—เปเบฒโ€‹เบฅเบฒเบโ€‹เบซเบผเบฒเบโ€‹เป‚เบ„เบ‡โ€‹เบฅเปˆเบฒเบ‡โ€‹เบžเบทเป‰เบ™โ€‹เบ–เบฒเบ™, เปเบกเปˆเบ™โ€‹เปเบ•เปˆโ€‹เบ—เบตเปˆโ€‹เบกเบตโ€‹เบเบฒเบ™โ€‹เบœเบฐโ€‹เบฅเบดเบ”โ€‹เปเบฅเป‰เบง. เปเบ•เปˆโ€‹เบ—เบธเบโ€‹เบ„เบฑเป‰เบ‡โ€‹เบ—เบตเปˆโ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒ messed เป€เบ–เบดเบ‡, เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เป„เบ”เป‰โ€‹เบฎเบฝเบ™โ€‹เบฎเบนเป‰โ€‹เบšเบฒเบ‡โ€‹เบชเบดเปˆเบ‡โ€‹เบšเบฒเบ‡โ€‹เบขเปˆเบฒเบ‡โ€‹เปƒเบซเบกเปˆ. เป‚เบ”เบเบœเปˆเบฒเบ™เบ›เบฐเบชเบปเบšเบเบฒเบ™เบ™เบตเป‰, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบˆเบฐเปเบšเปˆเบ‡เบ›เบฑเบ™เบšเบฒเบ‡เบšเบปเบ”เบฎเบฝเบ™เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบ—เบตเปˆเบชเบธเบ”เบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฎเบฝเบ™เบฎเบนเป‰.

เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฎเบฝเบ™เบฎเบนเป‰ 6 เบšเบปเบ”เบฎเบฝเบ™เบ™เบตเป‰เบ‚เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš cloudformation เบชเปเบฒเบฅเบฑเบšเบชเปˆเบงเบ™เบ—เบตเปˆเป€เบซเบผเบทเบญเบ‚เบญเบ‡เบŠเบตเบงเบดเบ”เบ‚เบญเบ‡เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒ.

เบšเบปเบ”เบฎเบฝเบ™เบ—เบต 1: เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ™เบณเปƒเบŠเป‰เบžเบงเบเบกเบฑเบ™

เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบฎเบฝเบ™เบฎเบนเป‰เบšเบปเบ”เบฎเบฝเบ™เบ™เบตเป‰เบ—เบฑเบ™เบ—เบตเบซเบผเบฑเบ‡เบˆเบฒเบเบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš เบ‚เปเป‰เบกเบนเบ™เบ‚เปˆเบฒเบงเบชเบฒเบ™เบŸเบฑเบ‡. เบ‚เป‰เบญเบเบšเปเปˆเบˆเบทเปˆเบชเบดเปˆเบ‡เบ—เบตเปˆเบ‚เป‰เบญเบเปเบ•เบเบซเบฑเบเปƒเบ™เป€เบงเบฅเบฒเบ™เบฑเป‰เบ™, เปเบ•เปˆเบ‚เป‰เบญเบเบˆเบทเปˆเป„เบ”เป‰เบขเปˆเบฒเบ‡เปเบ™เปˆเบ™เบญเบ™เบงเปˆเบฒเบ‚เป‰เบญเบเปƒเบŠเป‰เบ„เปเบฒเบชเบฑเปˆเบ‡ Aws cloudformation update. เบ„เปเบฒโ€‹เบชเบฑเปˆเบ‡โ€‹เบ™เบตเป‰โ€‹เบžเบฝเบ‡โ€‹เปเบ•เปˆ rolls เบญเบญเบโ€‹เปเบกเปˆโ€‹เปเบšเบšโ€‹เป‚เบ”เบโ€‹เบšเปเปˆโ€‹เบกเบตโ€‹เบเบฒเบ™โ€‹เบเบงเบ”โ€‹เบชเบญเบšโ€‹เบเบฒเบ™โ€‹เบ›เปˆเบฝเบ™โ€‹เปเบ›เบ‡โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบ–เบทเบโ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹. เบ‚เป‰เบญเบเบšเปเปˆเบ„เบดเบ”เบงเปˆเบฒเบ„เปเบฒเบญเบฐเบ—เบดเบšเบฒเบเปƒเบ”เป†เปเบกเปˆเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบชเปเบฒเบฅเบฑเบšเบงเปˆเบฒเป€เบ›เบฑเบ™เบซเบเบฑเบ‡เบ—เปˆเบฒเบ™เบ„เบงเบ™เบ—เบปเบ”เบชเบญเบšเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰เบžเบงเบเบกเบฑเบ™.

เบซเบผเบฑเบ‡เบˆเบฒเบเบ„เบงเบฒเบกเบฅเบปเป‰เบกเป€เบซเบฅเบงเบ™เบตเป‰, เบ‚เป‰เบญเบเป„เบ”เป‰เบ›เปˆเบฝเบ™เบ—เบฑเบ™เบ—เบต deployment pipeline, เบเบฒเบ™เบ›เปˆเบฝเบ™เบ„เปเบฒเบชเบฑเปˆเบ‡เบ›เบฑเบšเบ›เบธเบ‡เบ”เป‰เบงเบเบ„เปเบฒเบชเบฑเปˆเบ‡ เบชเป‰เบฒเบ‡-เบ›เปˆเบฝเบ™-เบ•เบฑเป‰เบ‡

# 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"

เป€เบกเบทเปˆเบญเบŠเบธเบ”เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™, เบกเบฑเบ™เบšเปเปˆเบกเบตเบœเบปเบ™เบ•เปเปˆ stack เบ—เบตเปˆเบกเบตเบขเบนเปˆเปเบฅเป‰เบง. เบšเปเปˆเป€เบซเบกเบทเบญเบ™เบเบฑเบšเบ„เปเบฒเบชเบฑเปˆเบ‡เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡, เบงเบดเบ—เบตเบเบฒเบ™ changeset เบšเปเปˆเป„เบ”เป‰เบเบฐเบ•เบธเป‰เบ™เปƒเบซเป‰เบกเบตเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ•เบปเบงเบˆเบดเบ‡. เปเบ—เบ™เบ—เบตเปˆเบˆเบฐ, เบกเบฑเบ™เบชเป‰เบฒเบ‡เบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ‚เบญเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ—เบปเบšเบ—เบงเบ™เบ„เบทเบ™เบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰. เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบšเบดเปˆเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบ‚เบญเบ‡ aws console. เปเบ•เปˆเบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบ—เบธเบเบขเปˆเบฒเบ‡เบ—เบตเปˆเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบเบงเบ”เป€เบšเบดเปˆเบ‡เบžเบงเบเบกเบฑเบ™เบขเบนเปˆเปƒเบ™ 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: เปƒเบŠเป‰เบ™เบฐเป‚เบเบšเบฒเบ stack เป€เบžเบทเปˆเบญเบ›เป‰เบญเบ‡เบเบฑเบ™เบšเปเปˆเปƒเบซเป‰เบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เบ‚เบญเบ‡เบฅเบฑเบ”เบ–เบทเบเบ›เปˆเบฝเบ™เปเบ—เบ™ เบซเบผเบทเป€เบญเบปเบฒเบญเบญเบ

เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบžเบฝเบ‡เปเบ•เปˆเป€เบšเบดเปˆเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปเบกเปˆเบ™เบšเปเปˆเบžเบฝเบ‡เบžเป. เบžเบงเบเป€เบฎเบปเบฒเบ—เบธเบเบ„เบปเบ™เปเบกเปˆเบ™เบกเบฐเบ™เบธเบ”เปเบฅเบฐเบžเบงเบเป€เบฎเบปเบฒเบ—เบธเบเบ„เบปเบ™เป€เบฎเบฑเบ”เบœเบดเบ”เบžเบฒเบ”. เบซเบผเบฑเบ‡โ€‹เบˆเบฒเบโ€‹เบ—เบตเปˆโ€‹เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เป„เบ”เป‰โ€‹เป€เบฅเบตเปˆเบกโ€‹เบ•เบปเป‰เบ™โ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบเบฒเบ™โ€‹เบ›เปˆเบฝเบ™โ€‹เปเบ›เบ‡โ€‹เบšเปเปˆโ€‹เบ”เบปเบ™, เป€เบžเบทเปˆเบญเบ™โ€‹เบฎเปˆเบงเบกโ€‹เบ—เบตเบกโ€‹เบ‚เบญเบ‡โ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบšเปเปˆโ€‹เบฎเบนเป‰โ€‹เบˆเบฑเบโ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบ—เบตเปˆโ€‹เป€เบฎเบฑเบ”โ€‹เปƒเบซเป‰โ€‹เบกเบตโ€‹เบเบฒเบ™โ€‹เบ›เบฑเบšโ€‹เบ›เบธเบ‡โ€‹เบ–เบฒเบ™โ€‹เบ‚เปเป‰โ€‹เบกเบนเบ™. เบšเปเปˆเบกเบตเบซเบเบฑเบ‡เบ—เบตเปˆเบšเปเปˆเบ”เบตเป€เบเบตเบ”เบ‚เบถเป‰เบ™เป€เบžเบฒเบฐเบงเปˆเบฒเบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบกเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš.

เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเบชเบฐเบ„เบดเบšเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบชเบฐเปเบ”เบ‡เบฅเบฒเบเบŠเบทเปˆเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เปเบฅเบฐเบฎเป‰เบญเบ‡เบ‚เปเบเบฒเบ™เบขเบทเบ™เบขเบฑเบ™, เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡ Replace เป„เบ”เป‰เบ–เบทเบเบ‚เป‰เบฒเบกเป„เบ›เป€เบžเบฒเบฐเบงเปˆเบฒเบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ‚เบญเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบกเบตเบ‚เบฐเบซเบ™เบฒเบ”เปƒเบซเบเปˆเบ—เบตเปˆเบกเบฑเบ™เบšเปเปˆเป€เบซเบกเบฒเบฐเบชเบปเบกเบเบฑเบšเบซเบ™เป‰เบฒเบˆเป. เปเบฅเบฐเบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ™เบตเป‰เปเบกเปˆเบ™เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เบ›เบปเบเบเบฐเบ•เบดเปƒเบ™เบชเบฐเบžเบฒเบšเปเบงเบ”เบฅเป‰เบญเบกเบเบฒเบ™เบ—เบปเบ”เบชเบญเบš, เบšเปเปˆเป„เบ”เป‰เป€เบญเบปเบฒเปƒเบˆเปƒเบชเปˆเบซเบผเบฒเบเบ•เปเปˆเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡.

เบกเบตเบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เบ—เบตเปˆเบ—เปˆเบฒเบ™เบšเปเปˆเป€เบ„เบตเบเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ—เบปเบ”เปเบ—เบ™เบซเบผเบทเป€เบญเบปเบฒเบญเบญเบ. เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบเบฒเบ™เบšเปเบฅเบดเบเบฒเบ™ statefull, เป€เบŠเบฑเปˆเบ™: เบ–เบฒเบ™เบ‚เปเป‰เบกเบนเบ™ RDS เบซเบผเบทเบเบธเปˆเบก elasticsearch, เปเบฅเบฐเบญเบทเปˆเบ™เป†. เบกเบฑเบ™เบˆเบฐเบ”เบตเบ–เป‰เบฒ aws เบˆเบฐเบ›เบฐเบ•เบดเป€เบชเบ”เบเบฒเบ™เบ™เปเบฒเป„เบ›เปƒเบŠเป‰เป‚เบ”เบเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบ–เป‰เบฒเบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ—เบตเปˆเบเปเบฒเบฅเบฑเบ‡เบ›เบฐเบ•เบดเบšเบฑเบ”เปเบกเปˆเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบฅเบถเบšเบŠเบฑเบšเบžเบฐเบเบฒเบเบญเบ™เบ”เบฑเปˆเบ‡เบเปˆเบฒเบง. เป‚เบŠเบเบ”เบต, เบฎเบนเบšเปเบšเบš cloudformation เบกเบตเบงเบดเบ—เบตเบเบฒเบ™เบ—เบตเปˆเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰. เบ™เบตเป‰เป€เบญเบตเป‰เบ™เบงเปˆเบฒเบ™เบฐเป‚เบเบšเบฒเบ stack, เปเบฅเบฐเบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบญเปˆเบฒเบ™เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบเปˆเบฝเบงเบเบฑเบšเบกเบฑเบ™เบขเบนเปˆเปƒเบ™ เป€เบญเบเบฐเบชเบฒเบ™:

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 เป€เบกเบทเปˆเบญเบญเบฑเบšเป€เบ”เบ” stack เบ—เบตเปˆเบกเบตเบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเบฅเบฑเบš

เป€เบกเบทเปˆเบญเบ—เปˆเบฒเบ™เบชเป‰เบฒเบ‡ RDS mysql entity, AWS เบฎเบฝเบเบฎเป‰เบญเบ‡เปƒเบซเป‰เบ—เปˆเบฒเบ™เปƒเบซเป‰ MasterUsername เปเบฅเบฐ MasterUserPassword. เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบกเบฑเบ™เบ”เบตเบเบงเปˆเบฒเบ—เบตเปˆเบˆเบฐเบšเปเปˆเบฎเบฑเบเบชเบฒเบ„เบงเบฒเบกเบฅเบฑเบšเปƒเบ™เบฅเบฐเบซเบฑเบ”เปเบซเบผเปˆเบ‡เปเบฅเบฐเบ‚เป‰เบญเบเบ•เป‰เบญเบ‡เบเบฒเบ™เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เบ—เบธเบเบขเปˆเบฒเบ‡, เบ‚เป‰เบญเบเป„เบ”เป‰เบ›เบฐเบ•เบดเบšเบฑเบ” "เบเบปเบ™เป„เบเบ—เบตเปˆเบชเบฐเบซเบผเบฒเบ”" เป€เบŠเบดเปˆเบ‡เบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ™เปเบฒเปƒเบŠเป‰เบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบงเบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบˆเบฒเบ s3, เปเบฅเบฐเบ–เป‰เบฒเบšเปเปˆเบžเบปเบšเบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบง, เบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบงเปƒเบซเบกเปˆเบˆเบฐเบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™. เป€เบเบฑเบšเป„เบงเป‰เปƒเบ™ s3.

เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบงเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบˆเบฐเบ–เบทเบเบชเบปเปˆเบ‡เบœเปˆเบฒเบ™เป€เบ›เบฑเบ™เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบตเป„เบ›เบซเบฒเบ„เปเบฒเบชเบฑเปˆเบ‡เบชเป‰เบฒเบ‡ - เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡ - เบŠเบธเบ” cloudformation. เปƒเบ™เบ‚เบฐเบ™เบฐเบ—เบตเปˆเบเบฒเบ™เบ—เบปเบ”เบฅเบญเบ‡เบเบฑเบšเบชเบฐเบ„เบดเบš, เบกเบฑเบ™เป€เบเบตเบ”เบ‚เบถเป‰เบ™เบงเปˆเบฒเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบš s3 เป„เบ”เป‰เบชเบนเบ™เป€เบชเบเป„เบ›, เปเบฅเบฐ "เบเบปเบ™เป„เบเบ—เบตเปˆเบชเบฐเบซเบฅเบฒเบ”" เบ‚เบญเบ‡เบ‚เป‰เบญเบเป„เบ”เป‰เบ›เบฐเบ•เบดเบšเบฑเบ”เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบฑเบ™เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบชเป‰เบฒเบ‡เบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบงเปƒเบซเบกเปˆ.

เบ–เป‰เบฒเบ‚เป‰เบญเบเป€เบฅเบตเปˆเบกเปƒเบŠเป‰ script เบ™เบตเป‰เปƒเบ™เบเบฒเบ™เบœเบฐเบฅเบดเบ”เปเบฅเบฐเบšเบฑเบ™เบซเบฒเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเป€เบเบตเบ”เบ‚เบถเป‰เบ™เบญเบตเบเป€เบ—เบทเปˆเบญเบซเบ™เบถเปˆเบ‡, เบกเบฑเบ™เบˆเบฐเบ›เบฑเบšเบ›เบธเบ‡ stack เบ”เป‰เบงเบเบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบ•เบปเบงเปƒเบซเบกเปˆ. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰, เบšเปเปˆเบกเบตเบซเบเบฑเบ‡เบ—เบตเปˆเบšเปเปˆเบ”เบตเบˆเบฐเป€เบเบตเบ”เบ‚เบถเป‰เบ™. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบ›เบฐเบ–เบดเป‰เบกเบงเบดเบ—เบตเบเบฒเบ™เบ™เบตเป‰เปเบฅเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปƒเบŠเป‰เบญเบตเบเบญเบฑเบ™เบซเบ™เบถเปˆเบ‡, เบชเบฐเบซเบ™เบญเบ‡เบ‚เปเป‰เบกเบนเบ™เบ›เบฐเบˆเปเบฒเบžเบฝเบ‡เปเบ•เปˆเบ„เบฑเป‰เบ‡เบ”เบฝเบง - เป€เบกเบทเปˆเบญเบชเป‰เบฒเบ‡ stack. เปเบฅเบฐเบ•เปเปˆเบกเบฒ, เป€เบกเบทเปˆเบญ stack เบ•เป‰เบญเบ‡เบเบฒเบ™เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡, เปเบ—เบ™เบ—เบตเปˆเบˆเบฐเบฅเบฐเบšเบธเบ„เปˆเบฒเบฅเบฑเบšเบ‚เบญเบ‡เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบต, เบ‚เป‰เบญเบเบžเบฝเบ‡เปเบ•เปˆเปƒเบŠเป‰ UsePreviousValue=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: เปƒเบŠเป‰เบเบฒเบ™เบเบณเบ™เบปเบ”เบ„เปˆเบฒ rollback

เบ—เบตเบกเบ‡เบฒเบ™เบญเบทเปˆเบ™เบ—เบตเปˆเบ‚เป‰เบญเบเป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเปƒเบŠเป‰เบซเบ™เป‰เบฒเบ—เบตเปˆ เบ‚เปเป‰เบกเบนเบ™เบ‚เปˆเบฒเบงเบชเบฒเบ™เบŸเบฑเบ‡, เป€เบญเบตเป‰เบ™เบงเปˆเบฒ เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒ rollback. เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบšเปเปˆโ€‹เป„เบ”เป‰โ€‹เบžเบปเบšโ€‹เป€เบซเบฑเบ™โ€‹เบกเบฑเบ™โ€‹เบกเบฒโ€‹เบเปˆเบญเบ™โ€‹เปเบฅเบฐโ€‹เบขเปˆเบฒเบ‡โ€‹เบงเปˆเบญเบ‡โ€‹เป„เบงโ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เบฎเบนเป‰โ€‹เบงเปˆเบฒโ€‹เบกเบฑเบ™โ€‹เบˆเบฐโ€‹เป€เบฎเบฑเบ”โ€‹เปƒเบซเป‰โ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰ stacks เบ‚เบญเบ‡โ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เป€เบ–เบดเบ‡โ€‹เปเบกเปˆเบ™โ€‹เป€เบขเบฑเบ™. เบ•เบญเบ™เบ™เบตเป‰เบ‚เป‰เบญเบเปƒเบŠเป‰เบกเบฑเบ™เบ—เบธเบเบ„เบฑเป‰เบ‡เบ—เบตเปˆเบ‚เป‰เบญเบเปƒเบŠเป‰เบฅเบฐเบซเบฑเบ”เบ‚เบญเบ‡เบ‚เป‰เบญเบเปƒเบชเปˆ lambda เบซเบผเบท ECS เป‚เบ”เบเปƒเบŠเป‰ cloudformation.

เบกเบฑเบ™เป€เบฎเบฑเบ”เบงเบฝเบเปเบ™เบงเปƒเบ”: เบ—เปˆเบฒเบ™เบฅเบฐเบšเบธ เบŸเบฑเบ‡เบŠเบฑเบ™เบ›เบธเบ CloudWatch เปƒเบ™เบžเบฒเบฅเบฒเบกเบดเป€เบ•เบต --rollback-configurationเป€เบกเบทเปˆเบญเบ—เปˆเบฒเบ™เบชเป‰เบฒเบ‡เบŠเบธเบ”เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡. เบ•เปเปˆเบกเบฒ, เป€เบกเบทเปˆเบญเบ—เปˆเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบŠเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡, Aws เบ•เบดเบ”เบ•เบฒเบกเบชเบฑเบ™เบเบฒเบ™เป€เบ•เบทเบญเบ™เบขเปˆเบฒเบ‡เบซเบ™เป‰เบญเบเบซเบ™เบถเปˆเบ‡เบ™เบฒเบ—เบต. เบกเบฑเบ™โ€‹เบˆเบฐโ€‹เบเบฑเบšโ€‹เบ„เบทเบ™โ€‹เป„เบ›โ€‹เบšเปˆเบญเบ™โ€‹เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เปƒเบŠเป‰โ€‹เบ–เป‰เบฒโ€‹เบซเบฒเบโ€‹เบงเปˆเบฒโ€‹เบ›เบธเบโ€‹เบ›เปˆเบฝเบ™โ€‹เบชเบฐโ€‹เบ–เบฒโ€‹เบ™เบฐโ€‹เป€เบ›เบฑเบ™ ALARM เปƒเบ™โ€‹เบฅเบฐโ€‹เบซเบงเปˆเบฒเบ‡โ€‹เป€เบงโ€‹เบฅเบฒโ€‹เบ™เบตเป‰.

เบ‚เป‰เบฒเบ‡เบฅเบธเปˆเบกเบ™เบตเป‰เปเบกเปˆเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡เปเบกเปˆเปเบšเบš excerpt เบ‚เปเป‰เบกเบนเบ™เบ‚เปˆเบฒเบงเบชเบฒเบ™เบŸเบฑเบ‡เปƒเบ™โ€‹เบ—เบตเปˆโ€‹เบ‚เป‰เบฒโ€‹เบžเบฐโ€‹เป€เบˆเบปเป‰เบฒโ€‹เบชเป‰เบฒเบ‡โ€‹ เป‚เบกเบ‡เบ›เบธเบ cloudwatch, เป€เบŠเบดเปˆเบ‡เบ•เบดเบ”เบ•เบฒเบก metric เบœเบนเป‰เปƒเบŠเป‰เบ„เบฅเบฒเบงเป€เบ›เบฑเบ™เบˆเปเบฒเบ™เบงเบ™เบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”เปƒเบ™เบšเบฑเบ™เบ—เบถเบเบ‚เบญเบ‡เบ„เบฅเบฒเบง (metric เปเบกเปˆเบ™เบชเป‰เบฒเบ‡เบœเปˆเบฒเบ™ 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

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™ เบ›เบธเบ เบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เป€เบ›เบฑเบ™ rollback เบเบฐเบ•เบธเป‰เบ™เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเบ›เบฐเบ•เบดเบšเบฑเบ”เบเปˆเบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบกเบท:

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: เปƒเบซเป‰เปเบ™เปˆเปƒเบˆเบงเปˆเบฒเบ—เปˆเบฒเบ™เบ™เบณเปƒเบŠเป‰เปเบกเปˆเปเบšเบšเป€เบงเบตเบŠเบฑเบ™เบซเบผเป‰เบฒเบชเบธเบ”

เบกเบฑเบ™เบ‡เปˆเบฒเบเบ—เบตเปˆเบˆเบฐเปƒเบŠเป‰เปเบกเปˆเปเบšเบšเบฎเบนเบšเปเบšเบš cloudformation เบฅเบธเป‰เบ™เบฅเป‰เบฒเบชเบธเบ”เบ—เบตเปˆเปœเป‰เบญเบเบเบงเปˆเบฒ, เปเบ•เปˆเบเบฒเบ™เป€เบฎเบฑเบ”เปเบšเบšเบ™เบฑเป‰เบ™เบˆเบฐเป€เบฎเบฑเบ”เปƒเบซเป‰เป€เบเบตเบ”เบ„เบงเบฒเบกเป€เบชเบเบซเบฒเบเบซเบผเบฒเบ. เบ™เบตเป‰เป€เบเบตเบ”เบ‚เบถเป‰เบ™เบเบฑเบšเบžเบงเบเป€เบฎเบปเบฒเบ„เบฑเป‰เบ‡เบ”เบฝเบง: เบœเบนเป‰เบžเบฑเบ”เบ—เบฐเบ™เบฒเบšเปเปˆเป„เบ”เป‰เบŠเบธเบเบเบนเป‰เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบซเบผเป‰เบฒเบชเบธเบ”เบˆเบฒเบ Git เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰ stack เบฎเบธเปˆเบ™เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒเป‚เบ”เบเบšเปเปˆเบฎเบนเป‰เบ•เบปเบง. เบญเบฑเบ™เบ™เบตเป‰เป€เบฎเบฑเบ”เปƒเบซเป‰เบเบฒเบ™เบขเบธเบ”เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡เปเบญเบฑเบšเบžเบฅเบดเป€เบ„เบŠเบฑเบ™เบ—เบตเปˆเปƒเบŠเป‰ stack เบ™เบตเป‰.

เบšเบฒเบ‡เบชเบดเปˆเบ‡เบšเบฒเบ‡เบขเปˆเบฒเบ‡เบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบ„เบทเบเบฒเบ™เป€เบžเบตเปˆเบกเบเบฒเบ™เบเบงเบ”เบชเบญเบšเป€เบžเบทเปˆเบญเป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบชเบฒเบ‚เบฒเปเบกเปˆเบ™เบ—เบฑเบ™เบชเบฐเป„เบซเบกเบเปˆเบญเบ™เบ—เบตเปˆเบˆเบฐเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบเบฑเบšเบกเบฑเบ™เบˆเบฐเบ”เบต (เบชเบปเบกเบกเบธเบ”เบงเปˆเบฒ 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: เบขเปˆเบฒเบ›เบฐเบ”เบดเบ”เบฅเปเป‰เปƒเปเปˆ

เบกเบฑเบ™โ€‹เบญเบฒเบ”โ€‹เบˆเบฐโ€‹เป€เบšเบดเปˆเบ‡โ€‹เบ„เบทโ€‹เบงเปˆเบฒโ€‹เบเบฒเบ™โ€‹เบ›เบฐโ€‹เบ•เบดโ€‹เบšเบฑเบ”โ€‹เบเบฑเบšโ€‹ เบ‚เปเป‰เบกเบนเบ™เบ‚เปˆเบฒเบงเบชเบฒเบ™เบŸเบฑเบ‡ - เบกเบฑเบ™เบ‡เปˆเบฒเบ. เบ—เปˆเบฒเบ™เบžเบฝเบ‡เปเบ•เปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เบชเบฐเบ„เบดเบš bash เบซเบผเบฒเบเป†เบญเบฑเบ™เบ—เบตเปˆเบ›เบฐเบ•เบดเบšเบฑเบ”เบ„เปเบฒเบชเบฑเปˆเบ‡ aws cli.

เป€เบกเบทเปˆเบญ 4 เบ›เบตเบเปˆเบญเบ™เบ‚เป‰เบญเบเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบ scripts เบ‡เปˆเบฒเบเป†เบ—เบตเปˆเป€เบญเบตเป‰เบ™เบงเปˆเบฒเบ„เปเบฒเบชเบฑเปˆเบ‡ aw cloudformation create-stack. เบšเปเปˆเบ”เบปเบ™ script เปเบกเปˆเบ™เบšเปเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบญเบตเบเบ•เปเปˆเป„เบ›. เปเบ•เปˆเบฅเบฐเบšเบปเบ”เบฎเบฝเบ™เบ—เบตเปˆเบ–เบญเบ”เบ–เบญเบ™เป„เบ”เป‰เป€เบฎเบฑเบ”เปƒเบซเป‰ script เบกเบตเบ„เบงเบฒเบกเบŠเบฑเบšเบŠเป‰เบญเบ™เบซเบผเบฒเบเบ‚เบถเป‰เบ™. เบกเบฑเบ™เบšเปเปˆเบžเบฝเบ‡เปเบ•เปˆเบกเบตเบ„เบงเบฒเบกเบซเบเบธเป‰เบ‡เบเบฒเบ, เปเบ•เปˆเบเบฑเบ‡เป€เบ•เบฑเบกเป„เบ›เบ”เป‰เบงเบเปเบกเบ‡เป„เบกเป‰.

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป€เบฎเบฑเบ”เบงเบฝเบเบขเบนเปˆเปƒเบ™เบžเบฐเปเบ™เบ IT เบ‚เบฐเบซเบ™เบฒเบ”เบ™เป‰เบญเบ. เบ›เบฐเบชเบปเบšเบเบฒเบ™เป„เบ”เป‰เบชเบฐเปเบ”เบ‡เปƒเบซเป‰เป€เบซเบฑเบ™เบงเปˆเบฒเปเบ•เปˆเบฅเบฐเบ—เบตเบกเบกเบตเบงเบดเบ—เบตเบเบฒเบ™เบ‚เบญเบ‡เบ•เบปเบ™เป€เบญเบ‡เปƒเบ™เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ stackformation cloud. เปเบฅเบฐเบ™เบฑเป‰เบ™เบเปเปˆเบšเปเปˆเบ”เบต. เบกเบฑเบ™เบˆเบฐเบ”เบตเบเบงเปˆเบฒเบ–เป‰เบฒเบ—เบธเบเบ„เบปเบ™เปƒเบŠเป‰เบงเบดเบ—เบตเบ”เบฝเบงเบเบฑเบ™. เป‚เบŠเบเบ”เบต, เบกเบตเบซเบผเบฒเบเป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ—เบตเปˆเบกเบตเบขเบนเปˆเป€เบžเบทเปˆเบญเบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบ™เบณเปƒเบŠเป‰ เปเบฅเบฐเบเบณเบ™เบปเบ”เบ„เปˆเบฒ stackformation cloud.

เบšเบปเบ”เบฎเบฝเบ™เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เบˆเบฐเบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบซเบผเบตเบเป€เบงเบฑเป‰เบ™เบ„เบงเบฒเบกเบœเบดเบ”เบžเบฒเบ”.

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™