ЁЯУТ рдзрдбрд╛ 05 тАФ State: рдЬрд╛рдЧреЗрдЪреА рдиреЛрдВрджрд╡рд╣реА
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: рдзрдбрд╛ 05 / 12 ┬╖ рдорд╛рдЧреЗ: lesson-04-variables-loops ┬╖ рдкреБрдвреЗ: lesson-06-dependency-graph
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ04, рдЖрдгрд┐ рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рдзрдбрд╛ 01 рдкрд╛рд╕реВрди рдареЗрд╡рдд рдЖрд▓реЗрд▓реА рд╡рд╣реА: state, рдореНрд╣рдгрдЬреЗрдЪ
рдЬрд╛рдЧреЗрдЪреА рдиреЛрдВрджрд╡рд╣реА. рдЖрд░рд╛рдЦрдбреНрдпрд╛рддреАрд▓ рдкреНрд░рддреНрдпреЗрдХ address рд╕рд╛рдареА рддреА рдЦрд▒реНрдпрд╛ object рдЪрд╛ id рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ
рд╢реЗрд╡рдЯрдЪреЗ рдорд╛рд╣реАрдд рдЕрд╕рд▓реЗрд▓реЗ attributes рдиреЛрдВрджрд╡рддреЗ. рддрд┐рдЪреНрдпрд╛рд╢рд┐рд╡рд╛рдп рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░рд╛рд▓рд╛ "рдирд╡реА lab рдмрд╛рдВрдзрд╛" рдЖрдгрд┐
"lab рдЖрдзреАрдЪ рдЖрд╣реЗ" рдпрд╛рдВрддреАрд▓ рдлрд░рдХ рдХрд│реВ рд╢рдХрдд рдирд╛рд╣реА. рдиреЛрдВрджрд╡рд╣реАрдд secrets рд╕рд╛рдзреНрдпрд╛ рдЕрдХреНрд╖рд░рд╛рдд рд╕реБрджреНрдзрд╛
рдЕрд╕рддрд╛рдд. iac/demo.py рдордзреАрд▓ state(); iac/engine.py рдордзреАрд▓ new_state(), refresh()
рдЖрдгрд┐ apply().
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдмрд╛рдВрдзрдХрд╛рдо рдХрд╛рд░реНрдпрд╛рд▓рдп рдПрдХ рдореЛрдареЗ рдкреБрд╕реНрддрдХ рдареЗрд╡рддреЗ: рдЬрд╛рдЧреЗрдЪреА рдиреЛрдВрджрд╡рд╣реА. ЁЯУТ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯреАрд╕рд╛рдареА рдПрдХ рдУрд│:
school_room.labтЖТ room-01 ┬╖ chem-lab ┬╖ floor 2 ┬╖ 30 seatsschool_locker.aтЖТ locker-01 ┬╖ combination 6872
рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рдирд╡рд╛ рдЖрд░рд╛рдЦрдбрд╛ рдШреЗрдКрди рдкрд░рдд рдпреЗрддреЗ рддреЗрд╡реНрд╣рд╛ рддреА рд╕рд░реНрд╡рд╛рдд рдЖрдзреА рдиреЛрдВрджрд╡рд╣реА рдЙрдШрдбрддреЗ. "рдЖрд░рд╛рдЦрдбрд╛ рдореНрд╣рдгрддреЛ lab. рдиреЛрдВрджрд╡рд╣реА рдореНрд╣рдгрддреЗ lab рдореНрд╣рдгрдЬреЗ room-01. рдЪрд▓рд╛, room-01 рдкрд╛рд╣реВрди рдпреЗрдК." рдпрд╛рд╡рд░реВрдирдЪ рддрд┐рд▓рд╛ рдХрд│рддреЗ рдХреА lab рдЖрдзреАрдЪ рдмрд╛рдВрдзрд▓реЗрд▓реА рдЖрд╣реЗ.
рдПрдХреЗ рджрд┐рд╡рд╢реА рдиреЛрдВрджрд╡рд╣реА рдирджреАрдд рдкрдбрддреЗ. ЁЯМК рдХрдВрддреНрд░рд╛рдЯрджрд╛рд░ рдЖрд░рд╛рдЦрдбрд╛ рдЙрдШрдбрддреЗ, рдПрдХ рд░рд┐рдХрд╛рдореА рдиреЛрдВрджрд╡рд╣реА рдЙрдШрдбрддреЗ, рдЖрдгрд┐ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ: "рдиреЛрдВрджрд╡рд╣реАрдд lab рдирд╛рд╣реА? рдордЧ рдорд▓рд╛ рдПрдХ рдмрд╛рдВрдзрд╛рдпрд▓рд╛рдЪ рд╣рд╡реА!" рддреА рдкрд╣рд┐рд▓реАрдЪреНрдпрд╛ рд╢реЗрдЬрд╛рд░реА рджреБрд╕рд░реА chem-lab рдмрд╛рдВрдзрддреЗ. рдЖрддрд╛ рджреЛрди рдЭрд╛рд▓реНрдпрд╛.
рдЖрдгрд┐ locker рдЪреА рддреА рдУрд│ рдкреБрдиреНрд╣рд╛ рдкрд╛рд╣рд╛. Combination рддрд┐рдереЗрдЪ рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЖрд╣реЗ. рдЬреЛ рдХреЛрдгреА рдиреЛрдВрджрд╡рд╣реА рд╡рд╛рдЪреВ рд╢рдХрддреЛ рддреЛ locker рдЙрдШрдбреВ рд╢рдХрддреЛ. ЁЯФУ
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
plans["ЁЯУЬ plans<br/>school_room.lab"] -->|"which object?"| reg["ЁЯУТ register (state)<br/>school_room.lab тЖТ room-01<br/>serial 1 ┬╖ lineage campus-3f9a<br/>combination 6872 (plain text!)"]
reg -->|"read room-01"| campus["ЁЯПл campus<br/>room-01"]
lost["ЁЯМК register lost"] -->|"plan"| dup["Plan: 5 to add<br/>тЖТ 2 chem-labs"]
ЁЯЧ║я╕П рд░реЗрдЦрд╛рдЯрд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/terraform/lesson-diagrams.html#l05
тЭУ рдХрд╛рдп
- State тАФ рдкреНрд░рддреНрдпреЗрдХ apply рдирдВрддрд░ Terraform рд▓рд┐рд╣рд┐рддреЗ рддреЛ рдПрдХ JSON document. рддреЛ config рдордзреАрд▓ рдкреНрд░рддреНрдпреЗрдХ
address (
aws_instance.web) рдПрдХрд╛ рдЦрд▒реНрдпрд╛ object рд╢реА (i-0abcтАж) рдЬреЛрдбрддреЛ рдЖрдгрд┐ object рдЪреЗ рд╢реЗрд╡рдЯрдЪреЗ рдкрд╛рд╣рд┐рд▓реЗрд▓реЗ attributes рд╕рд╛рдард╡рддреЛ. Default рдиреЗ рддреА рд╕реНрдерд╛рдирд┐рдХ fileterraform.tfstateрдЕрд╕рддреЗ. - рдЕрд╢реА рдЬреЛрдбрдгреА рдХрд╛ рд▓рд╛рдЧрддреЗ тАФ рдмрд╣реБрддреЗрдХ cloud APIs "рдХреЛрдгрддрд╛ instance рдореНрд╣рдгрдЬреЗ
aws_instance.web?" рдпрд╛рдЪреЗ рдЙрддреНрддрд░ рджреЗрдК рд╢рдХрдд рдирд╛рд╣реАрдд. рдирд╛рд╡реЗ рдЖрдгрд┐ tags unique рдирд╕рддрд╛рдд рдХрд┐рдВрд╡рд╛ рдиреЗрд╣рдореА рдирд╕рддрд╛рдд. State рд╣реАрдЪ рдЬреЛрдбрдгреА рдЖрд╣реЗ. - Serial тАФ рдмрджрд▓рд╛рдВрд╕рд╣ state рд▓рд┐рд╣рд┐рд▓реА рдХреА рджрд░ рд╡реЗрд│реА рд╡рд╛рдврдгрд╛рд░рд╛ counter. Lab 0 рдкрд╛рд╕реВрди рд╕реБрд░реВ рд╣реЛрддреЗ рдЖрдгрд┐ рдХрд╛рд╣реАрддрд░реА рдмрджрд▓рдгрд╛рд▒реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ apply рд▓рд╛ 1 рд╡рд╛рдврд╡рддреЗ.
- Lineage тАФ state рдкрд╣рд┐рд▓реНрдпрд╛рдВрджрд╛ рддрдпрд╛рд░ рд╣реЛрддрд╛рдирд╛ рддрд┐рд▓рд╛ рджрд┐рд▓реЗрд▓рд╛ id, рдореНрд╣рдгрдЬреЗ Terraform рдПрдХ state рджреБрд╕рд▒реНрдпрд╛ рдЕрд╕рдВрдмрдВрдзрд┐рдд state рд╡рд░ overwrite рдХрд░рдгреНрдпрд╛рд╕ рдирдХрд╛рд░ рджреЗрдК рд╢рдХрддреЗ.
- State рдордзреАрд▓ sensitive data тАФ рдкреНрд░рддреНрдпреЗрдХ attribute рд╕рд╛рдард╡рд▓рд╛ рдЬрд╛рддреЛ, passwords, private
keys рдЖрдгрд┐ generated secrets рд╕реБрджреНрдзрд╛.
sensitive = trueрдПрдЦрд╛рджреЗ рдореВрд▓реНрдп рдлрдХреНрдд plan рдЖрдгрд┐ output рджрд╛рдЦрд╡рддрд╛рдирд╛ рд▓рдкрд╡рддреЗ. State file рдордзреНрдпреЗ рддреЗ рддрд░реАрд╣реА рд╕рд╛рдзреНрдпрд╛ рдЕрдХреНрд╖рд░рд╛рдд рдЕрд╕рддреЗ. - рдЦрд░рд╛ format рд╡рд┐рд░реБрджреНрдз lab тАФ рдЦрд░реА state (format version 4)
resourcesрд▓рд╛{mode, type, name, provider, instances: [{attributes, dependencies}]}рдЪреНрдпрд╛ array рдореНрд╣рдгреВрди рджрд╛рдЦрд╡рддреЗ. Lab рд╕рдкрд╛рдЯ mapaddress тЖТ {type, id, attrs, deps}рд╡рд╛рдкрд░рддреЗ. рдХрд▓реНрдкрдирд╛ рддреАрдЪ, рдЖрдХрд╛рд░ рд╕реЛрдкрд╛.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг рдиреЛрдВрджрд╡рд╣реАрдореБрд│реЗрдЪ plans incremental рд╣реЛрддрд╛рдд. рддреА рд╣рд░рд╡рд▓реА рддрд░ рдкреБрдврдЪрд╛ plan рд╕рдЧрд│реЗ рдкреБрдиреНрд╣рд╛ рддрдпрд╛рд░ рдХрд░реВ рдкрд╛рд╣рддреЛ тАФ рдЪрд╛рдВрдЧрд▓реНрдпрд╛рдд рдЪрд╛рдВрдЧрд▓реЗ duplicates, рд╡рд╛рдИрдЯрд╛рдд рд╡рд╛рдИрдЯ рдирд╛рд╡рд╛рдВрдЪреЗ рд╕рдВрдШрд░реНрд╖ рдЖрдгрд┐ fail рдЭрд╛рд▓реЗрд▓реЗ applies. рддреА рдмрд┐рдШрдбрд▓реА рддрд░ addresses рдЪреБрдХреАрдЪреНрдпрд╛ objects рдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рддрд╛рдд. рддреА рдмрд╛рд╣реЗрд░ рдлреБрдЯрд▓реА рддрд░ рддрд┐рдЪреНрдпрд╛рддреАрд▓ рдкреНрд░рддреНрдпреЗрдХ secret рд╕реБрджреНрдзрд╛ рдлреБрдЯрддреЗ. рдореНрд╣рдгреВрдирдЪ state рдХрдзреАрдЪ git рдордзреНрдпреЗ commit рдХреЗрд▓реА рдЬрд╛рдд рдирд╛рд╣реА, versioning рдЕрд╕рд▓реЗрд▓реНрдпрд╛ encrypted remote store рдордзреНрдпреЗ рд░рд╛рд╣рддреЗ (рдзрдбрд╛ 08), рдЖрдгрд┐ рд╢рдХреНрдп рддрд┐рддрдХреНрдпрд╛ рдХрдореА рд▓реЛрдХ рд╡ jobs рддреА рд╡рд╛рдЪрддрд╛рдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
iac/engine.py рдордзреАрд▓ new_state()
version, serial, lineage, resources рдЖрдгрд┐ outputs рдЕрд╕рд▓реЗрд▓реА рд░рд┐рдХрд╛рдореА рдиреЛрдВрджрд╡рд╣реА рдмрдирд╡рддреЗ. plan() рдЪреА рд╕реБрд░реБрд╡рд╛рдд
refresh() рдиреЗ рд╣реЛрддреЗ, рдЬреЗ campus рдордзреВрди рдкреНрд░рддреНрдпреЗрдХ id рд╡рд╛рдЪрддреЗ. apply() рдкреНрд░рддреНрдпреЗрдХ object рдЪрд╛ id,
attributes рдЖрдгрд┐ dependencies рдиреЛрдВрджрд╡рд╣реАрдд рд▓рд┐рд╣рд┐рддреЗ, outputs рддреНрдпрд╛рдВрдЪреНрдпрд╛ sensitive
flag рд╕рд╣ рд╕рд╛рдард╡рддреЗ, рдЖрдгрд┐ рдХрд╛рд╣реАрд╣реА рдмрджрд▓рд▓реЗ рддрд░ serial рдордзреНрдпреЗ 1 рд╡рд╛рдврд╡рддреЗ. show_outputs() sensitive outputs рд╕рд╛рдареА
<sensitive> print рдХрд░рддреЗ тАФ рдЖрдгрд┐ рдореВрд▓реНрдп state["outputs"] рдордзреНрдпреЗ рддрд╕реЗрдЪ рд░рд╛рд╣рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 iac/demo.py state
python3 - <<'EOF'
import sys; sys.path.insert(0, "iac")
from cloud import FakeCloud
from engine import plan, apply
cloud, st = FakeCloud(), None
for seats in (30, 30, 40, 50):
st, _, msg = apply(plan({"resource": {"school_room": {"lab": {"name": "lab", "seats": seats}}}}, st, cloud), cloud)
print(f"seats {seats} тЖТ {msg} ┬╖ serial {st['serial']}")
print("state list:", list(st["resources"]))
print("state show:", st["resources"]["school_room.lab"]["attrs"])
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
state рдЕрд╕реЗ print рдХрд░рддреЗ:
output lab_id = "room-01"
output code_a = <sensitive>
тФАтФА the register (state): version 4 ┬╖ serial 1 ┬╖ lineage campus-3f9a ┬╖ 5 resources
search the state for 'combination' тЖТ ['school_locker.a: 6872', 'school_locker.b: 4434', 'school_locker.c: 4123']
тФАтФА the register is lost; plan with an empty one тЖТ Plan: 5 to add, 0 to change, 0 to destroy.
after apply the campus has 2 rooms named ['chem-lab'] and 10 objects тАФ duplicates, not the same campus
рддреБрдордЪрд╛ snippet рдЕрд╕реЗ print рдХрд░рддреЛ:
seats 30 тЖТ Apply complete! Resources: 1 added, 0 changed, 0 destroyed. ┬╖ serial 1
seats 30 тЖТ Apply complete! Resources: 0 added, 0 changed, 0 destroyed. ┬╖ serial 1
seats 40 тЖТ Apply complete! Resources: 0 added, 1 changed, 0 destroyed. ┬╖ serial 2
seats 50 тЖТ Apply complete! Resources: 0 added, 1 changed, 0 destroyed. ┬╖ serial 3
state list: ['school_room.lab']
state show: {'name': 'lab', 'floor': 1, 'seats': 50, 'tags': {}, 'id': 'room-01'}
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
Output рдиреЗ code_a рд▓рдкрд╡рд▓реЗ, рдкрдг рдиреЛрдВрджрд╡рд╣реАрдд рд╕рд╛рдзрд╛ рд╢реЛрдз рдШреЗрддрд▓реНрдпрд╛рд╡рд░ рддрд┐рдиреНрд╣реА lockers рдЪреА
combinations рд╕рд╛рдкрдбрд▓реА. рдиреЛрдВрджрд╡рд╣реА рдЧреЗрд▓реНрдпрд╛рд╡рд░ рддреНрдпрд╛рдЪ рдЖрд░рд╛рдЦрдбреНрдпрд╛рдиреЗ 5 to add рдЕрд╕рд╛ plan рдХреЗрд▓рд╛ рдЖрдгрд┐
рд╕рдЧрд│реНрдпрд╛рдЪреА рджреБрд╕рд░реА рдкреНрд░рдд рдмрд╛рдВрдзрд▓реА: 10 objects, рджреЛрди chem-labs. рдЖрдгрд┐ serial рдлрдХреНрдд рдХрд╛рд╣реАрддрд░реА рдмрджрд▓рд▓реЗ
рддрд░рдЪ рдкреБрдвреЗ рд╕рд░рдХрддреЛ тАФ 30 seats рд╕рд╣ рджреБрд╕рд▒реНрдпрд╛ apply рдиреЗ рддреЛ 1 рд╡рд░рдЪ рдареЗрд╡рд▓рд╛.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
terraform.tfstategit рдордзреНрдпреЗ commit рдХрд░рдгреЗ (.gitignoreрдордзреНрдпреЗ*.tfstate*рдЬреЛрдбрд╛)- secret state рдмрд╛рд╣реЗрд░ рдареЗрд╡рдгреНрдпрд╛рд╕рд╛рдареА
sensitive = trueрд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рдгреЗ - state JSON рд╣рд╛рддрд╛рдиреЗ edit рдХрд░рдгреЗ тАФ
terraform statecommands,moved,importрдЖрдгрд┐removedblocks рд╡рд╛рдкрд░рд╛ - рдПрдХрдореЗрд╡ рдкреНрд░рдд laptop рд╡рд░ рдареЗрд╡рдгреЗ тАФ versioning рдирд╛рд╣реА, backup рдирд╛рд╣реА, sharing рдирд╛рд╣реА (рдзрдбрд╛ 08)
- "рдлрдХреНрдд plan рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕рд╛рдареА" рдкреНрд░рддреНрдпреЗрдХ developer рд▓рд╛ prod state рд╡рд╛рдЪрдгреНрдпрд╛рдЪрд╛ access рджреЗрдгреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ рдиреЛрдВрджрд╡рд╣реА editor рдиреЗ рдирд╛рд╣реА, CLI рдиреЗ рдкрд╛рд╣рд╛:
terraform state list # every address in the state
terraform state show aws_s3_bucket.timetables
terraform state pull > backup.tfstate # a copy of the current remote state
terraform show -json | jq '.values.root_module.resources | length'
рдиреЛрдВрджрд╡рд╣реА рд╕реБрд░рдХреНрд╖рд┐рддрдкрдгреЗ рдмрджрд▓рдгреЗ:
# forget an object without destroying it (Terraform 1.7+)
removed {
from = aws_s3_bucket.old_reports
lifecycle { destroy = false }
}
Secrets state рдмрд╛рд╣реЗрд░ рдареЗрд╡рдгреЗ, рдХрд┐рдВрд╡рд╛ state рдордзреНрдпреЗ рдЕрдзрд┐рдХ рд╕реБрд░рдХреНрд╖рд┐рдд рдареЗрд╡рдгреЗ:
- apply рдЪреНрдпрд╛ рд╡реЗрд│реА secrets secret manager рдордзреВрди (AWS Secrets Manager, Vault) рд╡рд╛рдЪрд╛ рдЖрдгрд┐ state рдЪреНрдпрд╛ storage рд▓рд╛ рдХрдбрдХ access рдЖрдгрд┐ encryption at rest рджреНрдпрд╛ (рдзрдбрд╛ 08);
- ephemeral values рдЖрдгрд┐ resources (Terraform 1.10+) рдЖрдгрд┐ write-only arguments (Terraform 1.11+, рдЬрд┐рдереЗ provider рддреНрдпрд╛рдВрдирд╛ support рдХрд░рддреЛ) рдХрдзреАрдЪ state рдордзреНрдпреЗ рд╕рд╛рдард╡рд▓реЗ рдЬрд╛рдд рдирд╛рд╣реАрдд;
- OpenTofu (1.7+) рд╕рдВрдкреВрд░реНрдг state file рд╕рд╛рдард╡рдгреНрдпрд╛рдЖрдзреА client рд╡рд░рдЪ encrypt рдХрд░реВ рд╢рдХрддреЗ.
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: state рд▓рд╛ secret рд╕рдордЬрд╛. рдкреНрд░рддреНрдпреЗрдХ state file рдХреБрдареЗ рдЖрд╣реЗ, рддреА рдХреЛрдг рд╡рд╛рдЪреВ рд╢рдХрддреЗ, рддреА encrypted рдЖрдгрд┐ versioned рдЖрд╣реЗ, рдЖрдгрд┐ рддрд┐рдЪреА рдХреЛрдгрддреАрд╣реА рдкреНрд░рдд git рдордзреНрдпреЗ рдХрд┐рдВрд╡рд╛ laptops рд╡рд░ рдирд╛рд╣реА, рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рдорд╛рд╣реАрдд рдЕрд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ.
тПня╕П рдкреБрдвреЗ
рдиреЛрдВрджрд╡рд╣реА dependencies рд╕реБрджреНрдзрд╛ рдиреЛрдВрджрд╡рддреЗ тАФ gate рд▓рд╛ lab рдЪрд╛ id рд▓рд╛рдЧрддреЛ. рдкреБрдвреЗ: dependency graph, рдЬреЛ рдХреНрд░рдо рдард░рд╡рддреЛ рдЖрдгрд┐ рдПрдХрд╛рдЪ рд╡реЗрд│реА рдХрд╛рдп рдмрд╛рдВрдзрддрд╛ рдпреЗрддреЗ рддреЗ рдард░рд╡рддреЛ.
git checkout lesson-06-dependency-graph