ЁЯУЛ рдзрдбрд╛ 03 тАФ Plan рдЖрдгрд┐ apply: рдлрдХреНрдд рдлрд░рдХ рдмрд╛рдВрдзрд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: рдзрдбрд╛ 03 / 12 ┬╖ рдорд╛рдЧреЗ: lesson-02-resources-providers ┬╖ рдкреБрдвреЗ: lesson-04-variables-loops
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ02, рдЖрдгрд┐ Terraform рдЪреЗ рд╣реГрджрдп: plan. рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рддреАрди рдЧреЛрд╖реНрдЯреАрдВрдЪреА рддреБрд▓рдирд╛
рдХрд░рддреЛ тАФ рдЖрд░рд╛рдЦрдбрд╛ (config), рдиреЛрдВрджрд╡рд╣реА (state) рдЖрдгрд┐ campus (рдЦрд░реЗ
objects) тАФ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ address рдЪреЗ рддреЛ рдХрд╛рдп рдХрд░реЗрд▓ рдпрд╛рдЪреА рдпрд╛рджреА рдХрд░рддреЛ: create (+), рдЬрд╛рдЧреАрдЪ
update (~), replace (-/+, рдЬреЗрд╡реНрд╣рд╛ ForceNew argument рдмрджрд▓рддреЛ) рдХрд┐рдВрд╡рд╛ destroy (-).
рдордЧ apply рдиреЗрдордХреЗ рддреЗрдЪ рдХрд░рддреЗ. iac/demo.py рдордзреАрд▓ plan_(), iac/engine.py рдордзреАрд▓ plan()
рдЖрдгрд┐ apply().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдЖрд░рд╛рдЦрдбреНрдпрд╛рдЪреА version 1 рдмрд╛рдВрдзреВрди рдЭрд╛рд▓реА рдЖрд╣реЗ: рдПрдХ lab, рдПрдХ art room рдЖрдгрд┐ рдПрдХ рдореБрдЦреНрдп gate.
рдЖрддрд╛ рдРрд╢реНрд╡рд░реНрдпрд╛ рдЖрд░рд╛рдЦрдбреНрдпрд╛рдЪреА version 2 рд▓рд┐рд╣рд┐рддреЗ:
- lab рд▓рд╛ 30 рдРрд╡рдЬреА 40 seats рдорд┐рд│рддрд╛рдд,
- art room floor 3 рд╡рд░ рдЬрд╛рддреЗ,
- gate рдЖрд░рд╛рдЦрдбреНрдпрд╛рддреВрди рдХрд╛рдвреВрди рдЯрд╛рдХрд▓реЗ рдЖрд╣реЗ,
- рдЖрдгрд┐ рдПрдХ рдирд╡реА library рдЖрд╣реЗ.
рдХреЛрдгреА рдПрдХрд╣реА рд╡реАрдЯ рд╣рд▓рд╡рдгреНрдпрд╛рдЖрдзреА рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рдЬрд╛рдЧреЗрд╡рд░ рдлрд┐рд░реВрди рдПрдХ рдпрд╛рджреА рд▓рд┐рд╣рд┐рддреЛ: ЁЯУЭ
~lab: рдлрдХреНрдд 10 рдЦреБрд░реНрдЪреНрдпрд╛ рд╡рд╛рдврд╡рд╛. рддреАрдЪ рдЦреЛрд▓реА.-/+art room: рдЦреЛрд▓реА рдЙрдЪрд▓реВрди рджреБрд╕рд▒реНрдпрд╛ floor рд╡рд░ рдиреЗрддрд╛ рдпреЗрдд рдирд╛рд╣реА. рддреА рдкрд╛рдбрд╛, floor 3 рд╡рд░ рдирд╡реА рдмрд╛рдВрдзрд╛.+library: рдмрд╛рдВрдзрд╛.-gate: рдХрд╛рдвреВрди рдЯрд╛рдХрд╛.
рдРрд╢реНрд╡рд░реНрдпрд╛ рдпрд╛рджреА рд╡рд╛рдЪрддреЗ. рдордЧ рддреА "рд╣реЛ" рдореНрд╣рдгрддреЗ. рддреНрдпрд╛рдирдВрддрд░рдЪ рдмрд╛рдВрдзрдХрд╛рдо рд╕реБрд░реВ рд╣реЛрддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
cfg["ЁЯУЬ plans v2"] --> diff{"ЁЯС╖ compare"}
st["ЁЯУТ register<br/>(state)"] --> diff
campus["ЁЯПл campus<br/>(refresh)"] --> st
diff --> u["~ lab<br/>seats 30 тЖТ 40"]
diff --> r["-/+ art<br/>floor 1 тЖТ 3<br/>forces replacement"]
diff --> c["+ library"]
diff --> d["- gate"]
u & r & c & d --> sum["Plan: 2 to add,<br/>1 to change, 2 to destroy"]
sum -->|"yes"| apply["apply"]
ЁЯЧ║я╕П рд░реЗрдЦрд╛рдЯрд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/terraform/lesson-diagrams.html#l03
тЭУ рдХрд╛рдп
- Plan тАФ campus рдЖрд░рд╛рдЦрдбреНрдпрд╛рд╢реА рдЬреБрд│рд╡рдгреНрдпрд╛рд╕рд╛рдареА рдХрд░рд╛рдпрдЪреНрдпрд╛ рдХреНрд░рд┐рдпрд╛рдВрдЪреА рдпрд╛рджреА. рдХрд╛рд╣реАрд╣реА
рдмрд╛рдВрдзрд▓реЗ рдЬрд╛рдд рдирд╛рд╣реА.
terraform planрддреА рджрд╛рдЦрд╡рддреЗ;terraform plan -out=tfplanрддреА file рдордзреНрдпреЗ рд╕рд╛рдард╡рддреЗ. - Refresh тАФ plan рдХрд░рдгреНрдпрд╛рдЖрдзреА рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рдиреЛрдВрджрд╡рд╣реАрддреАрд▓ рдкреНрд░рддреНрдпреЗрдХ object рдЦрд▒реНрдпрд╛ cloud рдордзреВрди рд╡рд╛рдЪрддреЛ, рдореНрд╣рдгрдЬреЗ рддреЛ рдЦрд░реЛрдЦрд░ рдЬреЗ рдЖрд╣реЗ рддреНрдпрд╛рд╡рд┐рд░реБрджреНрдз plan рдХрд░рддреЛ (рдзрдбрд╛ 09).
- Create
+тАФ рдЖрд░рд╛рдЦрдбреНрдпрд╛рдд рдЖрд╣реЗ, рдиреЛрдВрджрд╡рд╣реАрдд рдирд╛рд╣реА. - рдЬрд╛рдЧреАрдЪ update
~тАФ рджреЛрдиреНрд╣реАрдВрдд рдЖрд╣реЗ, рдХрд╛рд╣реА arguments рд╡реЗрдЧрд│реЗ рдЖрд╣реЗрдд, рдЖрдгрд┐ рддреЗ рд╕рдЧрд│реЗ рдЪрд╛рд▓реВ object рд╡рд░рдЪ рдмрджрд▓рддрд╛ рдпреЗрддрд╛рдд. Id рддреЛрдЪ рд░рд╛рд╣рддреЛ. - Replace
-/+тАФ provider рдиреЗ ForceNew рдореНрд╣рдгреВрди рдЦреВрдг рдХреЗрд▓реЗрд▓рд╛ argument рдмрджрд▓рд▓рд╛. рдЬреБрдирд╛ object destroy рд╣реЛрддреЛ рдЖрдгрд┐ рдирд╡реНрдпрд╛ id рд╕рд╣ рдирд╡рд╛ рддрдпрд╛рд░ рд╣реЛрддреЛ. Terraform рддреНрдпрд╛ argument рд╢реЗрдЬрд╛рд░реА# forces replacementprint рдХрд░рддреЗ. Default рдиреЗ рддреЗ рдЖрдзреА destroy рдХрд░рддреЗ;create_before_destroylifecycle setting рд╣рд╛ рдХреНрд░рдо рдЙрд▓рдЯрд╛ рдХрд░рддреЗ (+/-). - Destroy
-тАФ рдиреЛрдВрджрд╡рд╣реАрдд рдЖрд╣реЗ, рдЖрд░рд╛рдЦрдбреНрдпрд╛рдд рдЖрддрд╛ рдирд╛рд╣реА. - No-op тАФ рджреЛрдиреНрд╣реАрдВрдд рдЖрд╣реЗ, рдХрд╛рд╣реАрдЪ рд╡реЗрдЧрд│реЗ рдирд╛рд╣реА. Print рд╣реЛрдд рдирд╛рд╣реА.
- рд╕рд╛рд░рд╛рдВрд╢рд╛рдЪреА рдУрд│ тАФ
Plan: 2 to add, 1 to change, 2 to destroy.рдПрдХ replace рдПрдХ add рдЖрдгрд┐ рдПрдХ destroy рдореНрд╣рдгреВрди рдореЛрдЬрд▓рд╛ рдЬрд╛рддреЛ, рдореНрд╣рдгреВрдирдЪ 4 рдХреНрд░рд┐рдпрд╛рдВрдордзреВрди 2 + 1 + 2 рдпреЗрддрд╛рдд. - Apply тАФ plan рдЕрдорд▓рд╛рдд рдЖрдгрдгреЗ.
terraform applyрдкреБрдиреНрд╣рд╛ plan рдХрд░рддреЗ рдЖрдгрд┐yesрд╡рд┐рдЪрд╛рд░рддреЗ;terraform apply tfplanрд╕рд╛рдард╡рд▓реЗрд▓рд╛ plan рдиреЗрдордХрд╛ рддрд╕рд╛рдЪ apply рдХрд░рддреЗ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг plan рд╣рд╛ рдЕрдирд░реНрде рдШрдбрдгреНрдпрд╛рдЖрдзреА рдкрдХрдбрдгреНрдпрд╛рдЪрд╛ рдХреНрд╖рдг рдЖрд╣реЗ. Database рд╡рд░ -/+ рдореНрд╣рдгрдЬреЗ
рддреБрдореНрд╣реА рдЖрдзреА рдпреЛрдЬрдирд╛ рдХреЗрд▓реА рдирд╕реЗрд▓ рддрд░ рддреНрдпрд╛рдЪрд╛ data рдЧреЗрд▓рд╛. рдЕрдирдкреЗрдХреНрд╖рд┐рдд - destroy рдореНрд╣рдгрдЬреЗ
рдХрд╛рд╣реАрддрд░реА rename рдЭрд╛рд▓реЗ рдХрд┐рдВрд╡рд╛ рдХрд╛рдврд▓реЗ рдЧреЗрд▓реЗ. рдЪрд╛рдВрдЧрд▓реА team рдкреНрд░рддреНрдпреЗрдХ plan рд╡рд╛рдЪрддреЗ рдЖрдгрд┐ replace рдХрд┐рдВрд╡рд╛
destroy рд▓рд╛ рдЙрддреНрддрд░ рд╣рд╡рд╛ рдЕрд╕рд▓реЗрд▓рд╛ рдкреНрд░рд╢реНрди рдорд╛рдирддреЗ. Plan рдореБрд│реЗ рдмрджрд▓ рд▓рд╣рд╛рдирд╣реА рд░рд╛рд╣рддрд╛рдд: рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░
рдлрдХреНрдд рдлрд░рдХ рдмрд╛рдВрдзрддреЛ, рд╕рдВрдкреВрд░реНрдг campus рдкреБрдиреНрд╣рд╛ рдирд╛рд╣реА.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
iac/engine.py рдордзреАрд▓ plan(cfg, state, cloud) state refresh рдХрд░рддреЗ,
config рдЪреЗ instances рдордзреНрдпреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ address рд╕рд╛рдареА рд╣рд╡реЗ рдЕрд╕рд▓реЗрд▓реЗ arguments
(with_defaults) state рдЪреНрдпрд╛ attributes рд╢реА рддрд╛рдбрддреЗ. рдЬреНрдпрд╛рдЪреНрдпрд╛ schema рдордзреНрдпреЗ force_new рдЖрд╣реЗ рдЕрд╕рд╛
argument рдмрджрд▓рд▓рд╛ рддрд░ рддреЛ рдмрджрд▓ replace рдард░рддреЛ; рдирд╛рд╣реАрддрд░ рддреЛ update рдЕрд╕рддреЛ. State рдордзреНрдпреЗ рдЙрд░рд▓реЗрд▓реЗ
addresses delete рдЕрд╕рддрд╛рдд. Plan.lines() diff print рдХрд░рддреЗ рдЖрдгрд┐ Plan.summary() рд╕рд╛рд░рд╛рдВрд╢рд╛рдЪреА
рдУрд│. apply(p, cloud) рдХреНрд░рд┐рдпрд╛ рдЪрд╛рд▓рд╡рддреЗ рдЖрдгрд┐ рдирд╡реА state рдкрд░рдд рджреЗрддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 iac/demo.py plan
python3 - <<'EOF'
import sys; sys.path.insert(0, "iac")
from cloud import FakeCloud
from engine import plan, apply
base = {"name": "lab", "floor": 1, "seats": 30}
for change in ({}, {"seats": 40}, {"name": "science-lab"}, {"floor": 2}, {"seats": 40, "floor": 2}):
cloud = FakeCloud()
st, _, _ = apply(plan({"resource": {"school_room": {"lab": base}}}, None, cloud), cloud)
p = plan({"resource": {"school_room": {"lab": dict(base, **change)}}}, st, cloud)
print(f"{str(change):<28} тЖТ {p.changes[0]['action']:<8} {p.summary()}")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
plan рдЕрд╕реЗ print рдХрд░рддреЗ:
~ school_room.lab seats: 30 тЖТ 40
-/+ school_room.art floor: 1 тЖТ 3 # forces replacement
+ school_room.library (create)
- school_gate.main (destroy)
Plan: 2 to add, 1 to change, 2 to destroy.
тФАтФА apply тЖТ Apply complete! Resources: 2 added, 1 changed, 2 destroyed.
the art room is a NEW object: room-02 тЖТ room-03 ┬╖ the lab kept its id room-01
рддреБрдордЪрд╛ snippet рдЕрд╕реЗ print рдХрд░рддреЛ:
{} тЖТ no-op No changes. Your infrastructure matches the configuration.
{'seats': 40} тЖТ update Plan: 0 to add, 1 to change, 0 to destroy.
{'name': 'science-lab'} тЖТ update Plan: 0 to add, 1 to change, 0 to destroy.
{'floor': 2} тЖТ replace Plan: 1 to add, 0 to change, 1 to destroy.
{'seats': 40, 'floor': 2} тЖТ replace Plan: 1 to add, 0 to change, 1 to destroy.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдПрдХрд╛рдЪ рдкреНрд░рдХрд╛рд░рдЪрд╛ рдмрджрд▓ тАФ рдПрдХ рдЖрдХрдбрд╛ рдмрджрд▓рдгреЗ тАФ рдирд┐рд░реБрдкрджреНрд░рд╡реА update (seats) рдЕрд╕реВ рд╢рдХрддреЛ рдХрд┐рдВрд╡рд╛
рдкреБрдиреНрд╣рд╛ рдмрд╛рдВрдзрдХрд╛рдо (floor). рдмрджрд▓ рдХрд┐рддреА рдореЛрдард╛ рдЖрд╣реЗ рдпрд╛рд╡рд░реВрди рдирд╛рд╣реА, schema рдард░рд╡рддреЗ. ForceNew рдмрджрд▓
рдЖрдгрд┐ рд╕рд╛рдзрд╛ рдмрджрд▓ рдПрдХрддреНрд░ рдЖрд▓реЗ рддрд░ рд╕рдВрдкреВрд░реНрдг рдЧреЛрд╖реНрдЯ replace рдард░рддреЗ. рдЖрдгрд┐ replace рдирдВрддрд░
art room рд▓рд╛ рдирд╡рд╛ id рдорд┐рд│рд╛рд▓рд╛ (room-02 тЖТ room-03): рдЖрд░рд╛рдЦрдбреНрдпрд╛рдмрд╛рд╣реЗрд░рдЪреЗ рдЬреЗ рдХрд╛рд╣реА
room-02 рд▓рдХреНрд╖рд╛рдд рдареЗрд╡реВрди рд╣реЛрддреЗ рддреЗ рдЖрддрд╛ рдХрд╢рд╛рдХрдбреЗрдЪ рдирд┐рд░реНрджреЗрд╢ рдХрд░рдд рдирд╛рд╣реА.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдЖрдзреА plan рди рд╡рд╛рдЪрддрд╛
terraform apply -auto-approveрдЪрд╛рд▓рд╡рдгреЗ - рд▓рд╛рдВрдм plan рдордзреАрд▓ рдПрдХрдореЗрд╡
-/+рдУрд│ рдирдЬрд░реЗрддреВрди рд╕реБрдЯрдгреЗ тАФ plan рдордзреНрдпреЗ "forces replacement" рдЖрдгрд┐ "destroy" рд╢реЛрдзрд╛ - review рдЭрд╛рд▓реЗрд▓реНрдпрд╛ plan рдРрд╡рдЬреА рд╡реЗрдЧрд│рд╛ plan apply рдХрд░рдгреЗ (apply рдЪреНрдпрд╛ рд╡реЗрд│реА рддрд╛рдбреВрди рди рдкрд╛рд╣рддрд╛ рдкреБрдиреНрд╣рд╛ plan рдХрд░рдгреЗ тАФ рдзрдбрд╛ 12)
- рдЖрд░рд╛рдЦрдбреНрдпрд╛рдд resource rename рдХрд░рдгреЗ рдЖрдгрд┐ plan рдЖрддрд╛ destroy + create рдореНрд╣рдгрддреЛ рд╣реЗ рд▓рдХреНрд╖рд╛рдд рди рдпреЗрдгреЗ (рдзрдбрд╛ 09 рд╣реЗ
movedрдиреЗ рд╕реЛрдбрд╡рддреЛ) - data рдареЗрд╡рдгрд╛рд▒реНрдпрд╛ рдХреЛрдгрддреНрдпрд╛рд╣реА рдЧреЛрд╖реНрдЯреАрд╕рд╛рдареА "replace" рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ рдЕрд╕реЗ рдЧреГрд╣реАрдд рдзрд░рдгреЗ тАФ database, disk, bucket
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ plan рд╕рд╛рдард╡рд╛, рд╡рд╛рдЪрд╛, рдиреЗрдордХрд╛ рддреЛрдЪ plan apply рдХрд░рд╛:
terraform plan -out=tfplan # the plan, saved
terraform show tfplan # read it again, as text
terraform show -json tfplan > plan.json # for tools: policy, cost, comments (lesson 11)
terraform apply tfplan # applies THIS plan тАФ no new diff, no "yes" prompt
AWS provider рдХрдбреВрди рдЦрд▒реНрдпрд╛ plan рдордзреАрд▓ рдПрдХ replace (ami рдмрджрд▓рд▓реНрдпрд╛рд╕ рдирд╡рд╛ instance рд▓рд╛рдЧрддреЛ;
instance_type рдЬрд╛рдЧреАрдЪ рдмрджрд▓реВ рд╢рдХрддреЛ):
# aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
~ ami = "ami-0aaa..." -> "ami-0bbb..." # forces replacement
lifecycle block рдиреЗ replacement рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рд╛:
resource "aws_instance" "web" {
ami = var.ami
instance_type = "t3.small"
lifecycle {
create_before_destroy = true # build the new one first, then remove the old one
prevent_destroy = false # set true on things that must never be destroyed by a plan
}
}
terraform plan -replace=aws_instance.web рдореБрджреНрджрд╛рдо replace рдШрдбрд╡рддреЗ (рдмрд┐рдШрдбрд▓реЗрд▓реНрдпрд╛
server рд╕рд╛рдареА), рдЖрдгрд┐ terraform destroy state рдордзреАрд▓ рд╕рд░реНрд╡ рдХрд╛рд╣реА рдХрд╛рдвреВрди рдЯрд╛рдХрдгреНрдпрд╛рдЪрд╛ plan рдХрд░рддреЗ.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: "
-/+рдЖрдгрд┐-рдУрд│реА рдореЛрдЬрд╛" рд╣реЗ рдкреНрд░рддреНрдпреЗрдХ review рдЪрд╛ рднрд╛рдЧ рдмрдирд╡рд╛. Data рдареЗрд╡рдгрд╛рд▒реНрдпрд╛ databases рдЖрдгрд┐ buckets рд╡рд░prevent_destroy = trueрд▓рд╛рд╡рд╛, рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдВрдирд╛ destroy рдХрд░рдгрд╛рд░рд╛ plan рддреНрдпрд╛рдРрд╡рдЬреА fail рд╣реЛрдИрд▓.
тПня╕П рдкреБрдвреЗ
рдПрдХ lab рд╕реЛрдкреА рдЖрд╣реЗ. рдЕрдиреЗрдХ рдЧрд╛рд╡рд╛рдВрд╕рд╛рдареА, рдереЛрдбреНрдпрд╛ рд╡реЗрдЧрд│реНрдпрд╛ рдЖрдХрд╛рд░рд╛рдВрдЪреНрдпрд╛ рдЕрдиреЗрдХ labs рд╕рд╛рдареА variables, outputs рдЖрдгрд┐ loops рд▓рд╛рдЧрддрд╛рдд.
git checkout lesson-04-variables-loops