<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Lali</title><author><name>Lali</name></author><id>https://teletype.in/atom/lalimi</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/lalimi?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/lalimi?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-23T23:08:07.259Z</updated><entry><id>lalimi:C1mzBjYP8NO</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/C1mzBjYP8NO?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Як продавати цифрові продукти в Україні: повний гайд 2026</title><published>2026-04-09T19:00:48.238Z</published><updated>2026-04-09T19:00:48.238Z</updated><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/8b/39/8b394ba5-40ea-477c-9236-80b0a069b480.png&quot;&gt;Цифровий продукт — це будь-який контент, який покупець отримує у вигляді файлу або доступу: електронна книга, відеокурс, Notion-шаблон, пресет для Lightroom, гайд у PDF, пензлі для Procreate.</summary><content type="html">
  &lt;h2 id=&quot;bQ5q&quot;&gt;Що таке цифровий продукт і чому це вигідно&lt;/h2&gt;
  &lt;p id=&quot;Anms&quot;&gt;Цифровий продукт — це будь-який контент, який покупець отримує у вигляді файлу або доступу: електронна книга, відеокурс, Notion-шаблон, пресет для Lightroom, гайд у PDF, пензлі для Procreate.&lt;/p&gt;
  &lt;p id=&quot;P1YC&quot;&gt;Головна перевага над фізичними товарами — &lt;strong&gt;нульова собівартість кожного наступного продажу&lt;/strong&gt;. Ви створюєте продукт один раз, а продаєте його необмежену кількість разів. Немає склadu, доставки, залишків.&lt;/p&gt;
  &lt;p id=&quot;NbP5&quot;&gt;У 2026 році ринок цифрових продуктів в Україні активно зростає. За даними глобальних досліджень, ринок e-learning щорічно збільшується на 15–20%. Українські автори — дизайнери, нутриціологи, SMM-спеціалісти, коучі — все частіше монетизують свою експертизу саме через цифровий контент.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;a1Zf&quot;&gt;Що можна продавати: конкретні приклади&lt;/h2&gt;
  &lt;p id=&quot;9TLe&quot;&gt;&lt;strong&gt;Освіта та експертиза:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;8rOY&quot;&gt;
    &lt;li id=&quot;wZrP&quot;&gt;Відеокурси та вебінари&lt;/li&gt;
    &lt;li id=&quot;bsBl&quot;&gt;PDF-гайди та чек-листи&lt;/li&gt;
    &lt;li id=&quot;9nca&quot;&gt;Воркбуки та практичні завдання&lt;/li&gt;
    &lt;li id=&quot;eSvP&quot;&gt;Закриті Telegram-канали з навчальними матеріалами&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;GVsX&quot;&gt;&lt;strong&gt;Дизайн та творчість:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;zlsY&quot;&gt;
    &lt;li id=&quot;5J49&quot;&gt;Шаблони для Notion, Figma, Canva, Excel&lt;/li&gt;
    &lt;li id=&quot;oZ8I&quot;&gt;Пресети для Lightroom та Capture One&lt;/li&gt;
    &lt;li id=&quot;jPYT&quot;&gt;Пензлі та текстури для Procreate та Photoshop&lt;/li&gt;
    &lt;li id=&quot;4yEw&quot;&gt;Стоковий цифровий арт та 3D-моделі&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;NkZm&quot;&gt;&lt;strong&gt;Бізнес та автоматизація:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;cOwb&quot;&gt;
    &lt;li id=&quot;kBwP&quot;&gt;Готові скрипти для продажів&lt;/li&gt;
    &lt;li id=&quot;Bc0n&quot;&gt;Таблиці фінансового обліку&lt;/li&gt;
    &lt;li id=&quot;QkLR&quot;&gt;Медіаплани та контент-стратегії&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Xofg&quot;&gt;Де продавати цифрові продукти в Україні&lt;/h2&gt;
  &lt;p id=&quot;amhx&quot;&gt;Це найважливіше питання. Розберемо варіанти.&lt;/p&gt;
  &lt;h3 id=&quot;e3RI&quot;&gt;Варіант 1: &amp;quot;На картку через Telegram&amp;quot;&lt;/h3&gt;
  &lt;p id=&quot;11Pp&quot;&gt;Найпоширеніший спосіб серед початківців. Покупець переказує гроші, автор вручну надсилає файл.&lt;/p&gt;
  &lt;p id=&quot;YMeJ&quot;&gt;&lt;strong&gt;Проблеми:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;JWvH&quot;&gt;
    &lt;li id=&quot;0Mms&quot;&gt;Прийом оплат на особисту картку за товари є порушенням податкового законодавства при регулярному характері&lt;/li&gt;
    &lt;li id=&quot;sEVV&quot;&gt;Немає автоматизації — кожен продаж вимагає вашого часу&lt;/li&gt;
    &lt;li id=&quot;AR3h&quot;&gt;Неможливо масштабуватися&lt;/li&gt;
    &lt;li id=&quot;UQaD&quot;&gt;Немає аналітики, статистики, повторних продажів&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;mubI&quot;&gt;Варіант 2: Іноземні платформи (Gumroad, Patreon, Stanstore)&lt;/h3&gt;
  &lt;p id=&quot;LCmy&quot;&gt;Здавалося б, зручне рішення. Але для українських авторів — суцільний головний біль.&lt;/p&gt;
  &lt;p id=&quot;ZGQe&quot;&gt;&lt;strong&gt;Реальні проблеми:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;EKQ7&quot;&gt;
    &lt;li id=&quot;cTvM&quot;&gt;Gumroad вимагає Payoneer або PayPal для виводу — обидва погано або зовсім не працюють з українськими ФОП&lt;/li&gt;
    &lt;li id=&quot;PdkW&quot;&gt;Подвійна конвертація: долар → гривня через посередника — це додаткові 2–4% втрат&lt;/li&gt;
    &lt;li id=&quot;MEWn&quot;&gt;Блокування виплат без пояснень — масова проблема 2022–2024 років&lt;/li&gt;
    &lt;li id=&quot;L26v&quot;&gt;Покупці в Україні часто не можуть оплатити через іноземний еквайринг українськими картками&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;kTWX&quot;&gt;Варіант 3: Українська платформа BlackSea&lt;/h3&gt;
  &lt;p id=&quot;lmNq&quot;&gt;&lt;a href=&quot;https://blacksea.click&quot; target=&quot;_blank&quot;&gt;BlackSea&lt;/a&gt; — перший спеціалізований маркетплейс цифрових продуктів в Україні.&lt;/p&gt;
  &lt;p id=&quot;rabi&quot;&gt;&lt;strong&gt;Ключові переваги:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;jyTS&quot;&gt;
    &lt;li id=&quot;Tlf6&quot;&gt;Гроші надходять &lt;strong&gt;напряму на ваш рахунок ФОП&lt;/strong&gt; без посередників&lt;/li&gt;
    &lt;li id=&quot;weLT&quot;&gt;Покупці платять зручно: Monobank, PrivatBank, Apple Pay, Google Pay&lt;/li&gt;
    &lt;li id=&quot;4G88&quot;&gt;Комісія &lt;strong&gt;10%&lt;/strong&gt; від продажу — і більше нічого (жодних підписок, плати за зберігання файлів або вивід коштів)&lt;/li&gt;
    &lt;li id=&quot;FYhW&quot;&gt;Платформа автоматично надсилає файл покупцеві одразу після оплати&lt;/li&gt;
    &lt;li id=&quot;5DOu&quot;&gt;Підтримує як ФОП, так і фізичних осіб&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;NWew&quot;&gt;Як легально продавати: питання ФОП та податків&lt;/h2&gt;
  &lt;p id=&quot;ijYX&quot;&gt;Це питання зупиняє багатьох авторів. Насправді все простіше, ніж здається.&lt;/p&gt;
  &lt;h3 id=&quot;mdBj&quot;&gt;Хто може продавати цифрові продукти?&lt;/h3&gt;
  &lt;p id=&quot;N6Mk&quot;&gt;&lt;strong&gt;ФОП (фізична особа-підприємець)&lt;/strong&gt; — найзручніший варіант. Для продажу цифрових продуктів підходить ФОП 2-ї або 3-ї групи спрощеної системи оподаткування. Ставка — 5% від доходу для 3-ї групи.&lt;/p&gt;
  &lt;p id=&quot;JWkw&quot;&gt;&lt;strong&gt;Фізична особа&lt;/strong&gt; — технічно можливо, але при регулярному доході потрібно сплачувати ПДФО (18%) та військовий збір (5%). Якщо ви серйозно плануєте монетизацію, реєстрація ФОП — правильний крок.&lt;/p&gt;
  &lt;h3 id=&quot;yZts&quot;&gt;Як відбувається оподаткування через BlackSea?&lt;/h3&gt;
  &lt;p id=&quot;zKap&quot;&gt;При роботі через платформу з агентською схемою платформа виступає агентом. Ваш оподатковуваний дохід — сума, що надходить на ваш рахунок після вирахування комісії. Платформа надає всі необхідні документи для звітності.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;8Yxx&quot;&gt;Покроковий план: як почати продавати&lt;/h2&gt;
  &lt;p id=&quot;Ilez&quot;&gt;&lt;strong&gt;Крок 1. Визначте свій продукт&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;N0MT&quot;&gt;Запитайте себе: яке питання ваша аудиторія ставить найчастіше? Відповідь на це питання у зручному форматі (PDF, відео, шаблон) — це і є ваш перший цифровий продукт.&lt;/p&gt;
  &lt;p id=&quot;AzeZ&quot;&gt;Не намагайтеся зробити &amp;quot;ідеальний&amp;quot; великий курс одразу. Почніть з малого: гайд на 10–15 сторінок або чек-лист вирішать конкретну проблему і коштуватимуть 150–500 грн.&lt;/p&gt;
  &lt;p id=&quot;2dRV&quot;&gt;&lt;strong&gt;Крок 2. Встановіть ціну&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;fo4M&quot;&gt;Розповсюджена помилка — занижувати ціну. Цифровий продукт вирішує реальну проблему, і це коштує грошей. Орієнтири для українського ринку:&lt;/p&gt;
  &lt;ul id=&quot;dUeF&quot;&gt;
    &lt;li id=&quot;Qhzz&quot;&gt;Чек-лист / короткий гайд: 100–300 грн&lt;/li&gt;
    &lt;li id=&quot;vXET&quot;&gt;Детальний гайд / воркбук: 300–800 грн&lt;/li&gt;
    &lt;li id=&quot;oY6b&quot;&gt;Шаблони (Notion, Figma): 200–600 грн&lt;/li&gt;
    &lt;li id=&quot;z00m&quot;&gt;Міні-курс (3–5 відео): 500–1500 грн&lt;/li&gt;
    &lt;li id=&quot;7Gxs&quot;&gt;Повноцінний курс: 1500–5000+ грн&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;YcaK&quot;&gt;&lt;strong&gt;Крок 3. Зареєструйтеся на платформі&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;nynd&quot;&gt;Реєстрація на BlackSea займає кілька хвилин. Завантажте свій продукт, заповніть опис, встановіть ціну — і ваша сторінка продажу готова. Посилання можна одразу розміщувати в Instagram Bio, Telegram-каналі або YouTube.&lt;/p&gt;
  &lt;p id=&quot;V2Ro&quot;&gt;&lt;strong&gt;Крок 4. Просування&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;ioro&quot;&gt;Для першого продажу не потрібна велика аудиторія. Достатньо 200–300 підписників у будь-якій соцмережі. Розкажіть про свій продукт у сторіс, напишіть пост-кейс, покажіть, яку проблему він вирішує — і перші продажі не змусять чекати.&lt;/p&gt;
  &lt;p id=&quot;NvOZ&quot;&gt;&lt;strong&gt;Крок 5. Масштабування&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;RrVV&quot;&gt;Отримавши перші відгуки, вдосконалюйте продукт і додавайте нові. Авторам із BlackSea доступний каталог маркетплейсу — ваш продукт побачать покупці, які самостійно шукають контент у вашій ніші (з комісією 15%).&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;NrOt&quot;&gt;Поширені питання (FAQ)&lt;/h2&gt;
  &lt;p id=&quot;ZNrU&quot;&gt;&lt;strong&gt;Чи можна продавати без ФОП?&lt;/strong&gt; Так, BlackSea працює з фізичними особами. Але якщо ви плануєте стабільний дохід, реєстрація ФОП 3-ї групи захистить від зайвих питань з боку податкової.&lt;/p&gt;
  &lt;p id=&quot;946z&quot;&gt;&lt;strong&gt;Як покупець отримує товар?&lt;/strong&gt; Автоматично на пошту одразу після підтвердження оплати. Ваша участь не потрібна.&lt;/p&gt;
  &lt;p id=&quot;pAgB&quot;&gt;&lt;strong&gt;Що якщо мій продукт скопіюють і поширять безкоштовно?&lt;/strong&gt; Повністю захиститися неможливо, але правильне ціноутворення і регулярне оновлення контенту роблять &amp;quot;злив&amp;quot; менш критичним. Нові покупці завжди купуватимуть актуальну версію.&lt;/p&gt;
  &lt;p id=&quot;Z9aQ&quot;&gt;&lt;strong&gt;Чи є мінімальна сума для виводу коштів?&lt;/strong&gt; На BlackSea виплати надходять безпосередньо на рахунок автора без значних затримок.&lt;/p&gt;
  &lt;p id=&quot;FBVK&quot;&gt;&lt;strong&gt;Скільки часу займає налаштування?&lt;/strong&gt; Реально — від 30 хвилин до кількох годин залежно від складності продукту. Платформа не вимагає технічних знань.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;PiLQ&quot;&gt;Висновок&lt;/h2&gt;
  &lt;p id=&quot;bWWH&quot;&gt;Продавати цифрові продукти в Україні у 2026 році — реально, легально і без зайвих технічних складнощів. Головне — обрати правильний інструмент, який бере на себе всю операційну роботу: прийом платежів, зберігання файлів, видачу покупцям і аналітику.&lt;/p&gt;
  &lt;p id=&quot;aw0o&quot;&gt;Якщо ви хочете почати без зайвого головного болю — &lt;a href=&quot;https://blacksea.click&quot; target=&quot;_blank&quot;&gt;зареєструйтесь на BlackSea&lt;/a&gt; і опублікуйте перший продукт сьогодні.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;jvmi&quot;&gt;&lt;em&gt;Стаття оновлена у квітні 2026 року.&lt;/em&gt;&lt;/p&gt;

</content></entry><entry><id>lalimi:-j4eLqUcDJj</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/-j4eLqUcDJj?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Як заробляти онлайн в Україні у 2026: покроковий гайд для авторів</title><published>2026-03-16T12:55:35.674Z</published><updated>2026-03-16T12:55:35.674Z</updated><summary type="html">Ринок онлайн-заробітку в Україні більше не є нішевою темою. Щороку тисячі людей — дизайнери, коучи, педагоги, маркетологи, фотографи — шукають відповідь на одне просте запитання: як перетворити свої знання або навички на стабільний дохід в інтернеті? Ця стаття — не про швидке збагачення. Це про реальні моделі, які працюють саме в українських реаліях.</summary><content type="html">
  &lt;p id=&quot;Z2tk&quot;&gt;Ринок онлайн-заробітку в Україні більше не є нішевою темою. Щороку тисячі людей — дизайнери, коучи, педагоги, маркетологи, фотографи — шукають відповідь на одне просте запитання: як перетворити свої знання або навички на стабільний дохід в інтернеті? Ця стаття — не про швидке збагачення. Це про реальні моделі, які працюють саме в українських реаліях.&lt;/p&gt;
  &lt;h2 id=&quot;etjf&quot;&gt;&lt;strong&gt;Що означає заробляти онлайн у 2026 році&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;uDfm&quot;&gt;Онлайн-заробіток у 2026 — це не обов&amp;#x27;язково фріланс і не обов&amp;#x27;язково блогерство. Найстійкіша модель сьогодні — пасивний дохід через цифрові продукти: одного разу створюєш, продаєш нескінченно. Саме тому монетизація контенту та цифрові продукти стали головним трендом серед українських авторів.&lt;/p&gt;
  &lt;p id=&quot;qLKi&quot;&gt;Є кілька базових моделей онлайн-заробітку, кожна з яких підходить різним людям залежно від досвіду та ресурсів.&lt;/p&gt;
  &lt;h3 id=&quot;EnCs&quot;&gt;&lt;strong&gt;1. Онлайн-курси та навчальні матеріали&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;0okQ&quot;&gt;Якщо ти знаєш щось краще за інших — це вже продукт. Онлайн-курс може бути записаним відео, серією PDF-уроків, або навіть текстовим гайдом. Головне — конкретний результат для покупця. Найчастіше питають: з чого почати? Відповідь: з однієї болючої проблеми твоєї аудиторії.&lt;/p&gt;
  &lt;h3 id=&quot;xTMn&quot;&gt;&lt;strong&gt;2. Шаблони, пресети та цифрові файли&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;wogf&quot;&gt;Canva-шаблони, Notion-бази, Lightroom-пресети, Figma-компоненти — все це продається. Причому без записів, без вебінарів і без великої аудиторії. Дизайнер один раз робить шаблон — і він може продаватись роками. Це і є пасивний дохід у найчистішому вигляді.&lt;/p&gt;
  &lt;h3 id=&quot;Fk7E&quot;&gt;&lt;strong&gt;3. Консультації та менторство&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;ptV3&quot;&gt;Якщо у тебе є практичний досвід — консультації є найшвидшим способом монетизувати його онлайн. Перші продажі зазвичай йдуть саме через цей формат, бо немає порогу входу: не потрібно нічого створювати наперед.&lt;/p&gt;
  &lt;h3 id=&quot;3q3c&quot;&gt;&lt;strong&gt;4. Доступ до спільноти або закритого контенту&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;IaW8&quot;&gt;Підписна модель набирає популярність і в Україні. Це може бути закритий Telegram-канал, курс з регулярним оновленням, або база знань для вузької ніші.&lt;/p&gt;
  &lt;h2 id=&quot;AnTT&quot;&gt;&lt;strong&gt;Як створити онлайн продукт: 5 кроків для початківців&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;jxbP&quot;&gt;Одна з найпоширеніших помилок — намагатись зробити ідеальний продукт перш ніж продати хоч один. Реальність: кращий перший продукт — це той, що ти вже можеш продати цього тижня.&lt;/p&gt;
  &lt;ul id=&quot;vune&quot;&gt;
    &lt;li id=&quot;KXMf&quot;&gt;Визнач одну конкретну проблему своєї аудиторії — не тему, а проблему&lt;/li&gt;
    &lt;li id=&quot;G68h&quot;&gt;Вибери найпростіший формат: PDF-гайд, шаблон або запис консультації&lt;/li&gt;
    &lt;li id=&quot;ALAP&quot;&gt;Поставь ціну — навіть символічну. Безкоштовне не вчить продавати&lt;/li&gt;
    &lt;li id=&quot;2m7B&quot;&gt;Вибери платформу для продажу з автодоставкою файлу покупцю&lt;/li&gt;
    &lt;li id=&quot;dERB&quot;&gt;Отримай перший відгук і покращ продукт на основі реального досвіду&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;Dabw&quot;&gt;&lt;strong&gt;Пасивний дохід в інтернеті: міф чи реальність для українців?&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;ZKlb&quot;&gt;Слово «пасивний» часто вводить в оману. Пасивний дохід не означає «без роботи» — він означає «без постійної присутності». Ти вкладаєш зусилля один раз при створенні продукту, а потім система продажів працює без тебе.&lt;/p&gt;
  &lt;p id=&quot;iiY3&quot;&gt;В Україні є кілька специфічних бар&amp;#x27;єрів: складнощі з отриманням міжнародних платежів, питання ФОП-оподаткування, відсутність зручних локальних інструментів продажу. Саме тому для українських авторів критично важливо вибирати платформи, які вирішують ці проблеми нативно — з гривневими платежами, локальними платіжними системами та відповідністю українському законодавству.&lt;/p&gt;
  &lt;h2 id=&quot;KXMo&quot;&gt;&lt;strong&gt;Монетизація контенту: коли аудиторія — не обов&amp;#x27;язкова умова&lt;/strong&gt;&lt;/h2&gt;
  &lt;p id=&quot;acGw&quot;&gt;Популярний міф: «спочатку набери 10 000 підписників, потім монетизуй». Практика показує інше. Автори з мікро-аудиторією у 500–1000 реальних читачів часто заробляють більше, ніж блогери з десятками тисяч підписників. Ключ — точне потрапляння продукту в потребу конкретної людини.&lt;/p&gt;
  &lt;p id=&quot;ec4m&quot;&gt;Монетизація контенту в Україні у 2025 — це не реклама і не донати. Це цифрові продукти: курси, шаблони, гайди, консультації. І найзручніший спосіб їх продавати — через спеціалізований маркетплейс, де вже є інфраструктура для прийому платежів, доставки файлів та юридичного оформлення.&lt;/p&gt;
  &lt;p id=&quot;pioE&quot;&gt;&lt;a href=&quot;https://blacksea.click/&quot; target=&quot;_blank&quot;&gt;→ Почніть &lt;/a&gt;&lt;strong&gt;продавати свій перший цифровий продукт на BlackSea — безкоштовна реєстрація за 5 хвилин&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;mBip&quot;&gt;&lt;strong&gt;Висновок&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;obSc&quot;&gt;Заробляти онлайн в Україні реально — і у 2026 році для цього є більше інструментів, ніж будь-коли. Найстійкіша стратегія: одна аудиторія, одна проблема, один цифровий продукт, одна платформа для продажу. Починай з малого — і масштабуй те, що вже продається.&lt;/p&gt;

</content></entry><entry><id>lalimi:dCHY23K2TsU</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/dCHY23K2TsU?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Как Kuse AI «взломал» Threads: разбор матричной стратегии и пошаговый план, как повторить это для своего стартапа</title><published>2025-08-18T06:25:32.421Z</published><updated>2025-08-18T06:36:35.869Z</updated><summary type="html">Представьте: прокручиваете ленту Threads и снова видите пост «10 мощных AI‑инструментов для работы». И снова среди ChatGPT, Canva и Notion — Kuse AI. День за днём, у разных авторов, на разных языках. Кажется, будто весь рынок уже решил: Kuse — must‑have.</summary><content type="html">
  &lt;p id=&quot;ZSdD&quot;&gt;За последние полгода в сети Threads регулярно появлялись посты, упоминающие сервис Kuse AI. Эти публикации часто создавались несколькими аккаунтами, и в них почти всегда присутствовала только Kuse. Чтобы понять, как такой “матричный” маркетинг помогает продвигать стартап, были проанализированы доступные посты (около 10 публикаций) из разных аккаунтов на Threads: @ai.tools.learn, @buildinhq, @ai.ezhacker, @ai.academy_, @kenchoi.kc и официального аккаунта @kusehq. С помощью браузерных инструментов была собрана информация о контенте, которая систематизирована ниже.&lt;/p&gt;
  &lt;p id=&quot;9tw6&quot;&gt;Ссылки на источники указаны в тексте в виде цитат.&lt;/p&gt;
  &lt;figure id=&quot;nTP8&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/50/c6/50c67dec-6e51-452f-a405-c8668bac8289.jpeg&quot; width=&quot;528&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;jMFn&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;8ooY&quot;&gt;&lt;/h2&gt;
  &lt;p id=&quot;yoS2&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;8AX9&quot;&gt;Почему один продукт упоминают все — и как это меняет сознание аудитории&lt;/h2&gt;
  &lt;p id=&quot;Auy6&quot;&gt;Маркетинг в соцсетях — это игра повторений. Когда один и тот же бренд «случайно» встречается в каруселях полезных инструментов, кейсах и туториалах в разных лентах и от разных авторов, мозг делает вывод: «Если об этом говорят повсюду, значит, это стоит внимания».&lt;/p&gt;
  &lt;p id=&quot;cHCV&quot;&gt;Kuse AI добился именно этого эффекта: узнаваемость через «естественную» многократность в независимых каналах. Не агрессивная реклама, а будто органическая рекомендация экспертов.&lt;/p&gt;
  &lt;p id=&quot;ak4y&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;x8YE&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;kB0J&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;2&quot;&gt;Боль аудитории: контент есть, но охваты и доверие не растут&lt;/h2&gt;
  &lt;ul id=&quot;kD99&quot;&gt;
    &lt;li id=&quot;c3ZR&quot;&gt;Один бренд‑аккаунт тонет в шумах.&lt;/li&gt;
    &lt;li id=&quot;cCv8&quot;&gt;Реклама дорожает, конверсия падает.&lt;/li&gt;
    &lt;li id=&quot;QxHz&quot;&gt;«Пост от лица компании» воспринимается как продажа, а не как помощь.&lt;/li&gt;
    &lt;li id=&quot;TZTO&quot;&gt;Алгоритм любит сохранения, репосты и дискуссии — но большинству постов нечем зацепить.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;UU74&quot;&gt;Вывод: нужно присутствовать шире и умнее, чем «одна страница — одна подача».&lt;/p&gt;
  &lt;p id=&quot;vpie&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;HSKq&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;3bVy&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;3&quot;&gt;Почему стандартные решения не срабатывают&lt;/h2&gt;
  &lt;ul id=&quot;siqs&quot;&gt;
    &lt;li id=&quot;ut1n&quot;&gt;Закупить рекламу? Быстро проедает бюджет, выгорает аудитория, растёт цена клика.&lt;/li&gt;
    &lt;li id=&quot;TT70&quot;&gt;Попросить блогеров? Одноразовые интеграции без системности не строят узнаваемость.&lt;/li&gt;
    &lt;li id=&quot;0x3F&quot;&gt;Писать «полезный контент» на одном канале? Хорошо, но медленно и с ограниченным охватом.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;pP9r&quot;&gt;Нужен способ масштабировать органику без «пахоты в никуда» и без бесконечных согласований.&lt;/p&gt;
  &lt;p id=&quot;1SWH&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;MnUm&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Njlw&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;4&quot;&gt;Инсайт: сеть профильных аккаунтов + три формата контента = эффект домино&lt;/h2&gt;
  &lt;p id=&quot;k8As&quot;&gt;Из анализа постов на Threads за последние полгода (около 10 публикаций из разных аккаунтов, включая @ai.tools.learn, @buildinhq, @ai.ezhacker, @ai.academy_, @kenchoi.kc и @kusehq) заметны повторяющиеся паттерны:&lt;/p&gt;
  &lt;ul id=&quot;j1c9&quot;&gt;
    &lt;li id=&quot;fss4&quot;&gt;Формат «топ‑N инструментов» с призывом «сохранить» — взрывает охваты: высокие save/share по умолчанию.&lt;/li&gt;
    &lt;li id=&quot;CZD4&quot;&gt;Кейсы под конкретные боли сегментов (студенты, преподаватели): «5 минут — и готов DSE‑экзамен в PDF». Практичность → регистрация.&lt;/li&gt;
    &lt;li id=&quot;IszR&quot;&gt;Официальный аккаунт докручивает позиционирование: «почему Kuse», визуальный интерфейс, контекст, мультимодальность.&lt;/li&gt;
    &lt;li id=&quot;3QJ7&quot;&gt;Межъязыковая диверсификация: англ./китайский; одинаковая структура подачи — разная локализация.&lt;/li&gt;
    &lt;li id=&quot;iSvn&quot;&gt;Взаимодействие между аккаунтами создаёт «эффект живого сообщества», а не рекламной сетки.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;GXlt&quot;&gt;Ключ: не один громкий канал, а согласованная сеть носителей смысла. Матричная подача — как музыкальная тема, которую подхватывают разные инструменты.&lt;/p&gt;
  &lt;figure id=&quot;1VG5&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4f/27/4f270329-36a3-46a9-94df-5de93bf91b2c.png&quot; width=&quot;462&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;EGq3&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7b/ba/7bbac153-dc15-4469-8d3a-91219e09cdec.png&quot; width=&quot;1028&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;fJLB&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/54/ec/54ec0505-66e0-4406-bac2-fa50bc3de549.png&quot; width=&quot;1024&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;mnuN&quot; class=&quot;m_column&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/82/c9/82c988d4-8086-4940-bdcf-8c8119a43230.png&quot; width=&quot;1024&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Sp4K&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;zxiI&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;5&quot;&gt;Конструктор матричной стратегии для вашего стартапа&lt;/h2&gt;
  &lt;p id=&quot;kuLM&quot;&gt;Ниже — пошагово, что и как делать. Это работает и в Threads, и в Telegram, и в X/LinkedIn.&lt;/p&gt;
  &lt;h3 id=&quot;BbNw&quot;&gt;Шаг 1. Разбейте аудиторию на кластеры&lt;/h3&gt;
  &lt;ul id=&quot;0rid&quot;&gt;
    &lt;li id=&quot;BfYX&quot;&gt;Студенты и преподаватели&lt;/li&gt;
    &lt;li id=&quot;08tA&quot;&gt;SMM/контент‑менеджеры&lt;/li&gt;
    &lt;li id=&quot;M8V3&quot;&gt;Продакт‑менеджеры/операторы бизнес‑процессов&lt;/li&gt;
    &lt;li id=&quot;exI6&quot;&gt;Фаундеры/малый бизнес&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;SQGS&quot;&gt;Для каждого — свой язык, проблемы и формат доказательства.&lt;/p&gt;
  &lt;h3 id=&quot;euiY&quot;&gt;Шаг 2. Заводим 3–6 профильных аккаунтов&lt;/h3&gt;
  &lt;ul id=&quot;xtTv&quot;&gt;
    &lt;li id=&quot;epLr&quot;&gt;Тематические «дайджесты инструментов» (как бы независимые кураторы)&lt;/li&gt;
    &lt;li id=&quot;FT6M&quot;&gt;Нишевые «практики» (кейсы «как решить X за 5 минут»)&lt;/li&gt;
    &lt;li id=&quot;MRtv&quot;&gt;Официальный бренд‑аккаунт (стратегия, фичи, road‑map, milestone’ы)&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;OqXO&quot;&gt;Важно: стиль дружелюбного эксперта, а не «рекламной листовки». Никакого спама.&lt;/p&gt;
  &lt;h3 id=&quot;Xtrk&quot;&gt;Шаг 3. Три опорных формата контента&lt;/h3&gt;
  &lt;ol id=&quot;jYEF&quot;&gt;
    &lt;li id=&quot;YpsC&quot;&gt;Топ‑N инструментов с призывом «Save/Share»&lt;/li&gt;
    &lt;li id=&quot;hdBH&quot;&gt;Пошаговые туториалы/кейсы на боль сегмента&lt;/li&gt;
    &lt;li id=&quot;hOEq&quot;&gt;Позиционирующие треды от бренда: «почему мы → чем отличаемся → где выигрываем»&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h3 id=&quot;cMg0&quot;&gt;Шаг 4. Ритм и перекрёстная поддержка&lt;/h3&gt;
  &lt;ul id=&quot;QzWf&quot;&gt;
    &lt;li id=&quot;3Al8&quot;&gt;3–4 поста в неделю по сети с разнотипными форматами.&lt;/li&gt;
    &lt;li id=&quot;m74P&quot;&gt;Взаимные упоминания, ответы, продолжения («разбор вопросов из вирусного поста»).&lt;/li&gt;
    &lt;li id=&quot;0xWQ&quot;&gt;Синхронизированные CTA (единая ссылка/линк‑хаб).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;JV1X&quot;&gt;Шаг 5. Измеряем только то, что влияет на рост&lt;/h3&gt;
  &lt;ul id=&quot;qt6u&quot;&gt;
    &lt;li id=&quot;uaKx&quot;&gt;Save/Share Rate у «топов».&lt;/li&gt;
    &lt;li id=&quot;pMYr&quot;&gt;CTR/Sign‑ups у кейсов.&lt;/li&gt;
    &lt;li id=&quot;BpWd&quot;&gt;LTV/Retention по каналам (какие аккаунты приводят «долгоиграющих»).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;B9Jh&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;UQyY&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;IYha&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;6&quot;&gt;Как производить такой контент быстро и качественно&lt;/h2&gt;
  &lt;p id=&quot;Tha7&quot;&gt;Матричная стратегия упирается в один узкий горлышко: скорость и стабильность производства. Здесь вступают в игру AI‑инструменты, которые закрывают разные уровни контент‑воронки:&lt;/p&gt;
  &lt;ul id=&quot;XDhJ&quot;&gt;
    &lt;li id=&quot;8wJt&quot;&gt;Идеи и структуру — генерируем промпт‑инжинирингом под GPT‑5.&lt;/li&gt;
    &lt;li id=&quot;XwiN&quot;&gt;Визуал для каруселей и тредов — синтез по готовым стилям.&lt;/li&gt;
    &lt;li id=&quot;FvWL&quot;&gt;Видео‑демо, кейсы и анонсы — скрипт → сцен‑план → рендер через видео‑AI.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;m4iF&quot;&gt;Ниже — готовая связка инструментов, которыми я лично пользуюсь и которые доступно собраны в продуктах «под ключ».&lt;/p&gt;
  &lt;p id=&quot;eeTr&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;sa3D&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;pT6v&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;7&quot;&gt;Инструменты, которые экономят месяцы и делают контент предсказуемо сильным&lt;/h2&gt;
  &lt;p id=&quot;C6H0&quot;&gt;В этой системе каждый продукт — модуль большого «контент‑двигателя». Их можно использовать по отдельности, но максимальный эффект — в связке.&lt;/p&gt;
  &lt;ol id=&quot;dg0W&quot;&gt;
    &lt;li id=&quot;VomG&quot;&gt;Гайд по промптам для GPT‑5: точные ответы без лишних итераций&lt;br /&gt; &lt;a href=&quot;https://lalirun.gumroad.com/l/PromptOptimizationCookbook&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/PromptOptimizationCookbook&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;rjaY&quot;&gt;Что решает:&lt;/p&gt;
  &lt;ul id=&quot;tgEK&quot;&gt;
    &lt;li id=&quot;firj&quot;&gt;Боль «много воды и мало сути», «постоянно переспрашивать ИИ».&lt;/li&gt;
    &lt;li id=&quot;4wiD&quot;&gt;Дает конструкцию промптов, которые возвращают сразу продаваемый текст: хук, доказательства, CTA, тред‑структуры.&lt;/li&gt;
    &lt;li id=&quot;QFYM&quot;&gt;Специальные промпты для «топ‑N», «гайдов за 5 минут», «разборов кейсов», «ответов на возражения».&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;RuIG&quot;&gt;Где применять:&lt;/p&gt;
  &lt;ul id=&quot;n76N&quot;&gt;
    &lt;li id=&quot;K3Mr&quot;&gt;Threads‑треды, Telegram‑лента, email‑лиды, лендинги.&lt;/li&gt;
    &lt;li id=&quot;uO38&quot;&gt;Подготовка сценариев для видео/вебинаров.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ol id=&quot;cVio&quot;&gt;
    &lt;li id=&quot;sNMR&quot;&gt;Veo 3: Visual Command Protocol (VCP) — революционная технология создания AI‑видео&lt;br /&gt;&lt;a href=&quot;https://lalirun.gumroad.com/l/CommandProtocol&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/CommandProtocol&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;tAQj&quot;&gt;Что решает:&lt;/p&gt;
  &lt;ul id=&quot;CdFq&quot;&gt;
    &lt;li id=&quot;EEm6&quot;&gt;Быстрое производство кинематографичных, «продающих» видео под треды/сторис/лендинги.&lt;/li&gt;
    &lt;li id=&quot;ELIX&quot;&gt;Пошаговый протокол команд: от идеи → сториборда → сцен‑плана → камерных команд → финального рендера.&lt;/li&gt;
    &lt;li id=&quot;X6Wu&quot;&gt;50+ шаблонов на любые ниши: демо‑продукта, кейс‑истории, туториалы, тизеры.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;IZXh&quot;&gt;Где применять:&lt;/p&gt;
  &lt;ul id=&quot;SjLp&quot;&gt;
    &lt;li id=&quot;wmjP&quot;&gt;Видео‑кейсы «как за 5 минут решить задачу» (идеально для матричной стратегии).&lt;/li&gt;
    &lt;li id=&quot;dQbd&quot;&gt;«Вирусные» анонсы функционала, сравнения «до/после», тизеры запуска.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;ol id=&quot;rJuU&quot;&gt;
    &lt;li id=&quot;RteP&quot;&gt;AI‑Agent Guide — как построить собственных контент‑агентов&lt;br /&gt; &lt;a href=&quot;https://lalirun.gumroad.com/l/ai-agent-guide&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/ai-agent-guide&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;vwAx&quot;&gt;Что решает:&lt;/p&gt;
  &lt;ul id=&quot;ZEUj&quot;&gt;
    &lt;li id=&quot;lcn9&quot;&gt;Автоматизацию: агент сам выбирает тему (по рандому или по слоту календаря), тянет актуальные факты, собирает структуру, подставляет UTM и публикует в нужные каналы.&lt;/li&gt;
    &lt;li id=&quot;Dn8b&quot;&gt;Сценарии для разных форматов: «топ‑N», «гайд 5 шагов», «разбор боли», «кейсы с метриками».&lt;/li&gt;
    &lt;li id=&quot;9USK&quot;&gt;Подключение к CMS/ноушен‑базе, контроль качества, шаблоны проверки «без воды».&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;RqSd&quot;&gt;Где применять:&lt;/p&gt;
  &lt;ul id=&quot;g4rs&quot;&gt;
    &lt;li id=&quot;8zff&quot;&gt;Масштабирование сети аккаунтов без роста штата.&lt;/li&gt;
    &lt;li id=&quot;Z0ut&quot;&gt;Регулярный выпуск контента с единым тоном и CTA.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;N5aN&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;E4U9&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;mYNB&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;8------14&quot;&gt;Практика: как это запустить за 14 дней&lt;/h2&gt;
  &lt;p id=&quot;x9Ti&quot;&gt;Ниже — реальный план, которым можно руководствоваться.&lt;/p&gt;
  &lt;p id=&quot;dz3A&quot;&gt;Дни 1–3&lt;/p&gt;
  &lt;ul id=&quot;RCn1&quot;&gt;
    &lt;li id=&quot;pFJU&quot;&gt;Определяем 3–4 кластера аудитории и «болезненные задачи» (по 2 на кластер).&lt;/li&gt;
    &lt;li id=&quot;8kb1&quot;&gt;Настраиваем шаблоны промптов из Prompt Optimization Cookbook под каждый кластер.&lt;/li&gt;
    &lt;li id=&quot;7rjx&quot;&gt;Готовим 12–16 постов: 6 «топ‑N», 6 мини‑кейсов, 2 позиционирующих треда.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;dbYS&quot;&gt;Дни 4–6&lt;/p&gt;
  &lt;ul id=&quot;EiJd&quot;&gt;
    &lt;li id=&quot;mcvD&quot;&gt;Поднимаем 3–5 профильных аккаунтов в Threads.&lt;/li&gt;
    &lt;li id=&quot;tS5b&quot;&gt;Подключаем AI‑агентов: темы, источники, расписание, формат вывода.&lt;/li&gt;
    &lt;li id=&quot;w95g&quot;&gt;Готовим визуальные карусели (единый стиль), делаем 2 коротких видео по VCP.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;2rQm&quot;&gt;Дни 7–10&lt;/p&gt;
  &lt;ul id=&quot;K5qC&quot;&gt;
    &lt;li id=&quot;l4bp&quot;&gt;Публикуем по сетке:&lt;/li&gt;
    &lt;ul id=&quot;Rd7P&quot;&gt;
      &lt;li id=&quot;94CJ&quot;&gt;Пн/Ср/Пт — «топ‑N» с CTA «Save/Share».&lt;/li&gt;
      &lt;li id=&quot;hjGr&quot;&gt;Вт/Чт — туториалы/кейсы с CTA «Try now».&lt;/li&gt;
      &lt;li id=&quot;ZC4o&quot;&gt;Сб — позиционирующий тред от бренда.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;V6Nu&quot;&gt;В тредах аккаунты «подхватывают» друг друга: ответы, дополнения, уточнения.&lt;/li&gt;
    &lt;li id=&quot;cpyz&quot;&gt;Параллельно — Telegram‑репосты: «3 инсайта за неделю» с ссылками.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;jSNp&quot;&gt;Дни 11–14&lt;/p&gt;
  &lt;ul id=&quot;U6vF&quot;&gt;
    &lt;li id=&quot;uYE4&quot;&gt;Аналитика: какие форматы дали больше Save/Share/CTR.&lt;/li&gt;
    &lt;li id=&quot;Z6Do&quot;&gt;Ротация постов в новых языках (локализация).&lt;/li&gt;
    &lt;li id=&quot;Vf8l&quot;&gt;Видео‑дубляж: тот же кейс — короткое видео по VCP с выдержкой 30–45 секунд.&lt;/li&gt;
    &lt;li id=&quot;yTct&quot;&gt;Первый оффер: «только сегодня гайд/шаблоны со скидкой», «бонус — чек‑лист».&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;lr9o&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;i241&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;THyf&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;9&quot;&gt;Модель контента под матрицу: примеры, которые можно вставить в прод&lt;/h2&gt;
  &lt;p id=&quot;h5aI&quot;&gt;Пример 1: Топ‑пост для сохранений&lt;br /&gt; Заголовок: 10 AI‑инструментов, которые реально экономят 10 часов в неделю&lt;br /&gt; Структура: 10 пунктов по 1–2 строки, призыв «Save и вернись к этому вечером».&lt;br /&gt; CTA: «Если нужны готовые промпты под эти инструменты — гайд по GPT‑5 в профиле».&lt;/p&gt;
  &lt;p id=&quot;zjBC&quot;&gt;Пример 2: Туториал «5 минут — готово»&lt;br /&gt; «Как за 5 минут собрать экзамен по шаблону и выгрузить в PDF»&lt;br /&gt; Шаги: 1) приложить шаблон 2) команда X 3) проверка структуры 4) экспорт&lt;br /&gt; CTA: «Сохранить на потом» + ссылка «шаблон команд — в гайде VCP».&lt;/p&gt;
  &lt;p id=&quot;Jw66&quot;&gt;Пример 3: Позиционирующий тред&lt;br /&gt; «Почему мы отказались от линейного чата и перешли к визуальному рабочему полю: меньше контекста — меньше шума — быстрее результат».&lt;br /&gt; CTA: «Полная методика и готовые сценарии — в AI‑Agent Guide».&lt;/p&gt;
  &lt;p id=&quot;q4X4&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;10&quot;&gt;&lt;/h2&gt;
  &lt;h2 id=&quot;k8vO&quot;&gt;Риски и как их обойти&lt;/h2&gt;
  &lt;ul id=&quot;jk7p&quot;&gt;
    &lt;li id=&quot;s4dd&quot;&gt;«Нас обвинят в сетке фейков». Выводите пользу на первое место: реальные кейсы, микро‑инструкции, ответы на вопросы.&lt;/li&gt;
    &lt;li id=&quot;zhNA&quot;&gt;«Контент будет однообразным». Ротируйте форматы: списки, кейсы, сравнения, «миф/факт», short‑видео.&lt;/li&gt;
    &lt;li id=&quot;4cfd&quot;&gt;«Сложно держать качество». Стандартизируйте промпты и чек‑листы проверки. Агентами — публикуйте черновики, финальный штрих — человеком.&lt;/li&gt;
    &lt;li id=&quot;5P9D&quot;&gt;«Нет мощности для видео». VCP даёт сцен‑план и командный протокол — 80% времени экономится на пре‑продакшне.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;aZfu&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;oJGO&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;11----3060&quot;&gt;Что произойдёт через 30–60 дней при такой стратегии&lt;/h2&gt;
  &lt;ul id=&quot;yYAU&quot;&gt;
    &lt;li id=&quot;0gXs&quot;&gt;Ваш бренд начинают «видеть везде» — и это ощущается органично.&lt;/li&gt;
    &lt;li id=&quot;xr9V&quot;&gt;Сообщество отвечает не на один пост, а на тему — её продолжают другие аккаунты.&lt;/li&gt;
    &lt;li id=&quot;9k6s&quot;&gt;Переходы на лендинг растут за счёт сохранений и рекомендаций.&lt;/li&gt;
    &lt;li id=&quot;Ebj2&quot;&gt;Кейсы дают не лайки, а регистрацию/триал, потому что закрывают конкретную боль «здесь и сейчас».&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;rnjV&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;12--cta&quot;&gt;&lt;/h2&gt;
  &lt;h2 id=&quot;B0U2&quot;&gt;Cоберите свою матрицу уже сегодня&lt;/h2&gt;
  &lt;p id=&quot;DIXl&quot;&gt;Если хочется перестать «стрелять вслепую» и построить систему публикаций, которая работает на узнаваемость и продажи, начните с базового набора:&lt;/p&gt;
  &lt;p id=&quot;Tcc7&quot;&gt;Products&lt;/p&gt;
  &lt;ol id=&quot;GhiN&quot;&gt;
    &lt;li id=&quot;bI8h&quot;&gt;Гайд по промптам для GPT‑5: точные ответы без лишних итераций&lt;br /&gt;  &lt;a href=&quot;https://lalirun.gumroad.com/l/PromptOptimizationCookbook&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/PromptOptimizationCookbook&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;FpXi&quot;&gt;Veo 3: Visual Command Protocol (VCP) — революционная технология создания AI‑видео&lt;br /&gt;  &lt;a href=&quot;https://lalirun.gumroad.com/l/CommandProtocol&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/CommandProtocol&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;QQgE&quot;&gt;AI‑Agent Guide — как собрать и запустить контент‑агентов&lt;br /&gt; &lt;a href=&quot;https://lalirun.gumroad.com/l/ai-agent-guide&quot; target=&quot;_blank&quot;&gt;https://lalirun.gumroad.com/l/ai-agent-guide&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Etv6&quot;&gt;Эта тройка закрывает весь цикл: текст → визуал/видео → автоматизация. Под ваш тон, ваши каналы и вашу цель.&lt;/p&gt;
  &lt;p id=&quot;hs48&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;pO4P&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;deJw&quot;&gt;Финальная мысль&lt;/h2&gt;
  &lt;p id=&quot;diWq&quot;&gt;Алгоритмы меняются. Привычки людей — тоже. Неподвижным остаётся одно: победа у тех, кто умеет приходить к аудитории с пользой — часто, разными голосами, в правильный момент.&lt;/p&gt;
  &lt;p id=&quot;ufvf&quot;&gt;Kuse AI показал, что «матрица» побеждает «одиночный голос». Ваша задача — собрать свою и включить её на максимум.&lt;/p&gt;
  &lt;p id=&quot;0dKU&quot;&gt;Готов обсудить вашу сферу и предложить первую матрицу контента под ключ. В каком сегменте вы работаете? Напишите в комментариях нишу и продукт — предложу 3 формата постов на ближайшую неделю.&lt;/p&gt;

</content></entry><entry><id>lalimi:7lEaFsJiTTl</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/7lEaFsJiTTl?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>CapCut слил — OpenCut спас. Как установить?</title><published>2025-07-11T14:34:36.204Z</published><updated>2025-07-11T14:34:36.204Z</updated><summary type="html">CapCut, конечно, красиво монтирует, но с 12 июня 2025 начал красиво и забирать себе права на твои видео, лицо и голос. Даже если это просто черновик. Даже если ты ничего не публиковал.</summary><content type="html">
  &lt;hr /&gt;
  &lt;p id=&quot;HAGJ&quot;&gt;CapCut, конечно, красиво монтирует, но с 12 июня 2025 начал красиво и &lt;strong&gt;забирать себе права&lt;/strong&gt; на твои видео, лицо и голос. Даже если это просто черновик. Даже если ты ничего не публиковал.&lt;/p&gt;
  &lt;p id=&quot;HPRk&quot;&gt;Ну окей, подумали open-source ребята — и запилили &lt;strong&gt;OpenCut&lt;/strong&gt;. Бесплатный аналог CapCut, где &lt;strong&gt;всё хранится только на твоём компе&lt;/strong&gt;, без рекламы и “вечных лицензий”.&lt;/p&gt;
  &lt;p id=&quot;G2QG&quot;&gt;🎬 Уже 8.4K звёзд на GitHub. Проект живёт, обновляется и всё больше становится похож на нормальную монтажку.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;Xxxs&quot;&gt;&lt;strong&gt;Хочешь попробовать? Вот как установить (максимально просто):&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;eUb2&quot;&gt;📍 &lt;em&gt;Для macOS (MacBook)&lt;/em&gt;&lt;/p&gt;
  &lt;ul id=&quot;ykxU&quot;&gt;
    &lt;li id=&quot;j1C0&quot;&gt;Установи &lt;strong&gt;Git&lt;/strong&gt;: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;ePOP&quot;&gt;&lt;code&gt;xcode-select --install &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;qlsq&quot;&gt;
    &lt;li id=&quot;Mhc3&quot;&gt;Скачай &lt;strong&gt;Docker Desktop&lt;/strong&gt;:&lt;br /&gt; &lt;a href=&quot;https://www.docker.com/products/docker-desktop&quot; target=&quot;_blank&quot;&gt;docker.com/products/docker-desktop&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;58RD&quot;&gt;Установи bun:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;t2mS&quot;&gt;&lt;code&gt;curl -fsSL &lt;a href=&quot;https://bun.sh/install&quot; target=&quot;_blank&quot;&gt;https://bun.sh/install&lt;/a&gt; | bash&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;4tC5&quot;&gt;&lt;code&gt;exec /bin/zsh&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;
  &lt;ul id=&quot;LxsB&quot;&gt;
    &lt;li id=&quot;sal1&quot;&gt;Клонируй проект: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;MIOX&quot;&gt;&lt;code&gt;git clone https://github.com/OpenCut-app/OpenCut.git &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;eBBb&quot;&gt;&lt;code&gt;cd OpenCut &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;aEOV&quot;&gt;
    &lt;li id=&quot;ag61&quot;&gt;Запусти сервисы: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;NjNc&quot;&gt;&lt;code&gt;docker-compose up -d &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;kooq&quot;&gt;
    &lt;li id=&quot;EGdb&quot;&gt;Подготовь настройки:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;9HFP&quot;&gt; &lt;code&gt;cd apps/web &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;eF7s&quot;&gt;&lt;code&gt;cp .env.example .env.local &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;Quff&quot;&gt;
    &lt;li id=&quot;ceM3&quot;&gt;Установи зависимости: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;HqgY&quot;&gt;&lt;code&gt;bun install &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;A6DD&quot;&gt;
    &lt;li id=&quot;afX1&quot;&gt;Подключи базу: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;IETd&quot;&gt;&lt;code&gt;bun run db:push:local &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;u96o&quot;&gt;
    &lt;li id=&quot;zcIV&quot;&gt;Запусти: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;HC0K&quot;&gt;&lt;code&gt;bun run dev &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;CJur&quot;&gt;Открой в браузере: &lt;strong&gt;&lt;a href=&quot;http://localhost:3000/&quot; target=&quot;_blank&quot;&gt;http://localhost:3000&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;yysI&quot;&gt;👀 Если хочешь такую же инструкцию для &lt;strong&gt;Windows&lt;/strong&gt; — пиши, скину отдельно.&lt;/p&gt;
  &lt;p id=&quot;AYcF&quot;&gt;А ещё могу сделать PDF или короткое видео, если хочешь сохранить. Напомни, и соберу 💾&lt;/p&gt;

</content></entry><entry><id>lalimi:b3j7SW8WLt0</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/b3j7SW8WLt0?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Вот инструкция для Windows — максимально просто и понятно 💻👇</title><published>2025-07-11T14:27:09.786Z</published><updated>2025-07-11T14:27:09.786Z</updated><summary type="html">Как установить OpenCut на Windows</summary><content type="html">
  &lt;p id=&quot;o4d3&quot;&gt;&lt;strong&gt;Как установить OpenCut на Windows&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;tDUK&quot;&gt;OpenCut — это open-source альтернатива CapCut, которая:&lt;br /&gt; ✅ не сохраняет твои видео в облако&lt;br /&gt; ✅ не присваивает права на твой контент&lt;br /&gt; ✅ работает локально — всё только у тебя на компе&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;yNTd&quot;&gt;🔧 Что нужно заранее:&lt;/h3&gt;
  &lt;ol id=&quot;Kihu&quot;&gt;
    &lt;li id=&quot;oRoj&quot;&gt;&lt;strong&gt;Git for Windows&lt;/strong&gt;&lt;br /&gt; ➤ Скачай: &lt;a href=&quot;https://git-scm.com/downloads&quot; target=&quot;_blank&quot;&gt;https://git-scm.com/downloads&lt;/a&gt;&lt;br /&gt; Во время установки поставь галочку “Git Bash” — пригодится.&lt;/li&gt;
    &lt;li id=&quot;vPUh&quot;&gt;&lt;strong&gt;Docker Desktop&lt;/strong&gt;&lt;br /&gt; ➤ Скачай: &lt;a href=&quot;https://www.docker.com/products/docker-desktop&quot; target=&quot;_blank&quot;&gt;https://www.docker.com/products/docker-desktop&lt;/a&gt;&lt;br /&gt; Во время установки включи поддержку &lt;strong&gt;WSL2&lt;/strong&gt; (если попросит) и &lt;strong&gt;запусти Docker&lt;/strong&gt;.&lt;/li&gt;
    &lt;li id=&quot;16by&quot;&gt;&lt;strong&gt;Bun (вместо npm)&lt;/strong&gt;&lt;br /&gt; ➤ Открой Git Bash (не PowerShell, не CMD) и вставь: &lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;sqLc&quot;&gt;&lt;code&gt;curl -fsSL https://bun.sh/install | bash exec bash &lt;/code&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;w8f3&quot;&gt;📦 Установка OpenCut:&lt;/h3&gt;
  &lt;ul id=&quot;GgGw&quot;&gt;
    &lt;li id=&quot;eLwc&quot;&gt;Клонируй проект: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;c1fO&quot;&gt;&lt;code&gt;git clone https://github.com/OpenCut-app/OpenCut.git &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;LHqW&quot;&gt;&lt;code&gt;cd OpenCut &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;4JHa&quot;&gt;
    &lt;li id=&quot;raQG&quot;&gt;Запусти бэкенд: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;f2aI&quot;&gt;&lt;code&gt;docker-compose up -d &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;pLkK&quot;&gt;
    &lt;li id=&quot;HBw7&quot;&gt;Перейди в папку фронтенда: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;li2M&quot;&gt;&lt;code&gt;cd apps/web &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;4vlG&quot;&gt;&lt;code&gt;cp .env.example .env.local &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;lXrN&quot;&gt;
    &lt;li id=&quot;sa5J&quot;&gt;Установи зависимости: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;9eIz&quot;&gt;&lt;code&gt;bun install &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;4wVR&quot;&gt;
    &lt;li id=&quot;3SEY&quot;&gt;Прокинь базу: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;wfy3&quot;&gt;&lt;code&gt;bun run db:push:local &lt;/code&gt;&lt;/p&gt;
  &lt;ul id=&quot;duuO&quot;&gt;
    &lt;li id=&quot;qcgy&quot;&gt;Запусти фронтенд: &lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;9Q5B&quot;&gt;&lt;code&gt;bun run dev &lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;72ih&quot;&gt;Открывай: 👉 &lt;a href=&quot;http://localhost:3000/&quot; target=&quot;_blank&quot;&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;
  &lt;hr /&gt;

</content></entry><entry><id>lalimi:Sgixz_QtYlX</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/Sgixz_QtYlX?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Модуль 11: DevSecOps — Безопасность в DevOps</title><published>2025-06-11T11:15:54.164Z</published><updated>2025-06-11T11:15:54.164Z</updated><summary type="html">Курс DevOps для новичков 2025</summary><content type="html">
  &lt;p id=&quot;11-devsecops----devops&quot;&gt;&lt;em&gt;Курс DevOps для новичков 2025&lt;/em&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;devsecops&quot;&gt;🔒 Что такое DevSecOps?&lt;/h2&gt;
  &lt;p id=&quot;FOSs&quot;&gt;&lt;strong&gt;DevSecOps&lt;/strong&gt; — это эволюция DevOps, которая интегрирует &lt;strong&gt;безопасность на каждом этапе&lt;/strong&gt; разработки и эксплуатации. Вместо того чтобы думать о безопасности в конце, DevSecOps делает её частью повседневного процесса разработки.&lt;/p&gt;
  &lt;p id=&quot;y5Et&quot;&gt;По данным исследований 2025 года, более &lt;strong&gt;85% инцидентов безопасности&lt;/strong&gt; связаны с неправильной конфигурацией компонентов и недостаточной защитой в CI/CD пайплайнах. DevSecOps решает эти проблемы через автоматизацию проверок безопасности.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;shift-left-security&quot;&gt;🎯 Принцип &amp;quot;Shift Left Security&amp;quot;&lt;/h2&gt;
  &lt;p id=&quot;lySw&quot;&gt;&lt;strong&gt;Shift Left&lt;/strong&gt; означает перенос проверок безопасности &lt;strong&gt;как можно раньше&lt;/strong&gt; в цикле разработки:&lt;/p&gt;
  &lt;ul id=&quot;XMTU&quot;&gt;
    &lt;li id=&quot;MN4k&quot;&gt;Анализ кода на этапе написания&lt;/li&gt;
    &lt;li id=&quot;krBP&quot;&gt;Автоматические проверки при commit&lt;/li&gt;
    &lt;li id=&quot;snn9&quot;&gt;Сканирование зависимостей при сборке&lt;/li&gt;
    &lt;li id=&quot;xqGl&quot;&gt;Тестирование безопасности в CI/CD&lt;/li&gt;
    &lt;li id=&quot;hv1R&quot;&gt;Мониторинг безопасности в продакшне&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;gY88&quot;&gt;Преимущества Shift Left&lt;/h2&gt;
  &lt;p id=&quot;Xfh6&quot;&gt;&lt;strong&gt;Снижение затрат&lt;/strong&gt; — исправление уязвимостей на раннем этапе в 100 раз дешевле&lt;br /&gt; &lt;strong&gt;Быстрая обратная связь&lt;/strong&gt; — разработчики получают уведомления о проблемах сразу&lt;br /&gt; &lt;strong&gt;Повышение качества&lt;/strong&gt; — безопасность становится частью культуры разработки&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;llWQ&quot;&gt;⚠️ Основные угрозы безопасности&lt;/h2&gt;
  &lt;h2 id=&quot;kgq6&quot;&gt;OWASP Top 10 — критичные уязвимости 2025&lt;/h2&gt;
  &lt;ol id=&quot;OBVL&quot;&gt;
    &lt;li id=&quot;D1hn&quot;&gt;&lt;strong&gt;Broken Access Control&lt;/strong&gt; — нарушения контроля доступа&lt;/li&gt;
    &lt;li id=&quot;JsYf&quot;&gt;&lt;strong&gt;Cryptographic Failures&lt;/strong&gt; — криптографические сбои&lt;/li&gt;
    &lt;li id=&quot;joyE&quot;&gt;&lt;strong&gt;Injection&lt;/strong&gt; — SQL, NoSQL, OS injection атаки&lt;/li&gt;
    &lt;li id=&quot;ZpF2&quot;&gt;&lt;strong&gt;Insecure Design&lt;/strong&gt; — небезопасный дизайн приложения&lt;/li&gt;
    &lt;li id=&quot;Wj8Q&quot;&gt;&lt;strong&gt;Security Misconfiguration&lt;/strong&gt; — неправильная конфигурация&lt;/li&gt;
    &lt;li id=&quot;jvud&quot;&gt;&lt;strong&gt;Vulnerable Components&lt;/strong&gt; — уязвимые компоненты&lt;/li&gt;
    &lt;li id=&quot;uPyz&quot;&gt;&lt;strong&gt;Authentication Failures&lt;/strong&gt; — сбои аутентификации&lt;/li&gt;
    &lt;li id=&quot;Fbko&quot;&gt;&lt;strong&gt;Software Integrity Failures&lt;/strong&gt; — нарушения целостности ПО&lt;/li&gt;
    &lt;li id=&quot;1AAD&quot;&gt;&lt;strong&gt;Logging Failures&lt;/strong&gt; — недостаточное логирование&lt;/li&gt;
    &lt;li id=&quot;g0M4&quot;&gt;&lt;strong&gt;Server-Side Request Forgery&lt;/strong&gt; — SSRF атаки&lt;/li&gt;
  &lt;/ol&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;cicd&quot;&gt;🔐 Безопасность в CI/CD пайплайне&lt;/h2&gt;
  &lt;h2 id=&quot;i7IO&quot;&gt;Многоуровневая защита пайплайна&lt;/h2&gt;
  &lt;pre id=&quot;H3p4&quot;&gt;# .github/workflows/security.yml
name: Security Checks

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  security-scan:
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    # 1. Сканирование секретов в коде
    - name: Scan for secrets
      uses: trufflesecurity/trufflehog@main
      with:
        path: ./
        base: ${{ github.event.repository.default_branch }}
        head: HEAD

    # 2. Статический анализ кода (SAST)
    - name: Run CodeQL Analysis
      uses: github/codeql-action/init@v2
      with:
        languages: javascript, python

    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

    # 3. Сканирование зависимостей (SCA)
    - name: Run Snyk to check vulnerabilities
      uses: snyk/actions/node@master
      env:
        SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      with:
        args: --severity-threshold=high

    # 4. Проверка Docker образа
    - name: Build Docker image
      run: docker build -t myapp:${{ github.sha }} .

    - name: Scan Docker image with Trivy
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: &amp;#x27;myapp:${{ github.sha }}&amp;#x27;
        format: &amp;#x27;sarif&amp;#x27;
        output: &amp;#x27;trivy-results.sarif&amp;#x27;

    - name: Upload Trivy results
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: &amp;#x27;trivy-results.sarif&amp;#x27;

    # 5. Проверка Infrastructure as Code
    - name: Run Checkov on Terraform
      uses: bridgecrewio/checkov-action@master
      with:
        directory: terraform/
        framework: terraform
        output_format: sarif
        output_file_path: checkov-report.sarif

    - name: Upload Checkov results
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: checkov-report.sarif
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;VzsT&quot;&gt;🔑 Управление секретами&lt;/h2&gt;
  &lt;h2 id=&quot;sjFL&quot;&gt;Никогда не храните секреты в коде!&lt;/h2&gt;
  &lt;p id=&quot;n16z&quot;&gt;&lt;strong&gt;Проблемы хранения секретов в коде:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;vEK1&quot;&gt;
    &lt;li id=&quot;lPLY&quot;&gt;Утечка через публичные репозитории&lt;/li&gt;
    &lt;li id=&quot;e6gL&quot;&gt;Доступ к секретам всех разработчиков&lt;/li&gt;
    &lt;li id=&quot;wbxh&quot;&gt;Сложность ротации паролей&lt;/li&gt;
    &lt;li id=&quot;cmi2&quot;&gt;Отсутствие аудита доступа&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;lLyE&quot;&gt;HashiCorp Vault — централизованное управление&lt;/h2&gt;
  &lt;pre id=&quot;eK9v&quot; data-lang=&quot;bash&quot;&gt;# Установка Vault
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

# Запуск Vault в dev режиме (только для обучения!)
vault server -dev

# Сохранение секрета
vault kv put secret/myapp/db \
    password=&amp;quot;super-secret-password&amp;quot; \
    username=&amp;quot;dbuser&amp;quot;

# Получение секрета
vault kv get secret/myapp/db

# Получение только пароля
vault kv get -field=password secret/myapp/db
&lt;/pre&gt;
  &lt;h2 id=&quot;Rgfi&quot;&gt;Интеграция Vault с приложениями&lt;/h2&gt;
  &lt;pre id=&quot;zJ2q&quot; data-lang=&quot;python&quot;&gt;# Python приложение с Vault
import hvac
import os

def get_db_credentials():
    # Подключение к Vault
    client = hvac.Client(
        url=os.getenv(&amp;#x27;VAULT_URL&amp;#x27;, &amp;#x27;http://localhost:8200&amp;#x27;),
        token=os.getenv(&amp;#x27;VAULT_TOKEN&amp;#x27;)
    )
    
    # Получение секретов
    response = client.secrets.kv.v2.read_secret_version(
        path=&amp;#x27;myapp/db&amp;#x27;
    )
    
    credentials = response[&amp;#x27;data&amp;#x27;][&amp;#x27;data&amp;#x27;]
    return credentials[&amp;#x27;username&amp;#x27;], credentials[&amp;#x27;password&amp;#x27;]

# Использование в приложении
username, password = get_db_credentials()
db_url = f&amp;quot;postgresql://{username}:{password}@localhost:5432/myapp&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;wIMW&quot;&gt;Kubernetes Secrets&lt;/h2&gt;
  &lt;pre id=&quot;wGQs&quot;&gt;# k8s-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
data:
  database-password: &amp;lt;base64-encoded-password&amp;gt;
  api-key: &amp;lt;base64-encoded-api-key&amp;gt;
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secure-app
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: database-password
        - name: API_KEY
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: api-key
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;OcoA&quot;&gt;🛡️ Сканирование контейнеров&lt;/h2&gt;
  &lt;h2 id=&quot;9eWv&quot;&gt;Безопасный Dockerfile&lt;/h2&gt;
  &lt;pre id=&quot;fHQo&quot;&gt;# Используем минимальный базовый образ
FROM node:18-alpine

# Обновляем пакеты для устранения уязвимостей
RUN apk update &amp;amp;&amp;amp; apk upgrade &amp;amp;&amp;amp; \
    apk add --no-cache dumb-init &amp;amp;&amp;amp; \
    rm -rf /var/cache/apk/*

# Создаем непривилегированного пользователя
RUN addgroup -g 1001 -S nodejs &amp;amp;&amp;amp; \
    adduser -S nextjs -u 1001

# Устанавливаем рабочую директорию
WORKDIR /app

# Копируем только файлы зависимостей для кэширования
COPY package*.json ./

# Устанавливаем только production зависимости
RUN npm ci --only=production &amp;amp;&amp;amp; \
    npm cache clean --force &amp;amp;&amp;amp; \
    npm audit fix

# Копируем исходный код
COPY --chown=nextjs:nodejs . .

# Удаляем ненужные файлы
RUN rm -rf .git .gitignore README.md

# Переключаемся на непривилегированного пользователя
USER nextjs

# Используем init процесс для правильной обработки сигналов
ENTRYPOINT [&amp;quot;dumb-init&amp;quot;, &amp;quot;--&amp;quot;]

# Указываем команду запуска
CMD [&amp;quot;npm&amp;quot;, &amp;quot;start&amp;quot;]

# Открываем только необходимый порт
EXPOSE 3000

# Добавляем health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Добавляем метки для трекинга
LABEL org.opencontainers.image.source=&amp;quot;https://github.com/user/repo&amp;quot;
LABEL org.opencontainers.image.version=&amp;quot;1.0.0&amp;quot;
LABEL org.opencontainers.image.created=&amp;quot;2025-06-11&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;a0Yt&quot;&gt;Автоматическое сканирование с Trivy&lt;/h2&gt;
  &lt;pre id=&quot;JaVo&quot; data-lang=&quot;bash&quot;&gt;# Сканирование локального образа
trivy image myapp:latest

# Сканирование с выводом только критических уязвимостей
trivy image --severity HIGH,CRITICAL myapp:latest

# Сканирование с сохранением в файл
trivy image --format json --output results.json myapp:latest

# Сканирование файловой системы
trivy fs .

# Сканирование Kubernetes манифестов
trivy config k8s/

# Сканирование Terraform файлов
trivy config terraform/
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;PmVn&quot;&gt;🛠️ Практические задания&lt;/h2&gt;
  &lt;h2 id=&quot;7UnE&quot;&gt;Задание 11.1: Настройка security scanning в CI/CD&lt;/h2&gt;
  &lt;pre id=&quot;c8i0&quot; data-lang=&quot;bash&quot;&gt;# 1. Создание проекта с уязвимостями для демонстрации
mkdir devsecops-demo
cd devsecops-demo

# 2. Создание package.json с уязвимыми зависимостями
cat &amp;gt; package.json &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
{
  &amp;quot;name&amp;quot;: &amp;quot;devsecops-demo&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;express&amp;quot;: &amp;quot;4.16.0&amp;quot;,
    &amp;quot;lodash&amp;quot;: &amp;quot;4.17.4&amp;quot;,
    &amp;quot;moment&amp;quot;: &amp;quot;2.19.0&amp;quot;
  }
}
EOF

# 3. Создание простого приложения
cat &amp;gt; app.js &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
const express = require(&amp;#x27;express&amp;#x27;);
const _ = require(&amp;#x27;lodash&amp;#x27;);
const moment = require(&amp;#x27;moment&amp;#x27;);

const app = express();
app.use(express.json());

// Уязвимый endpoint (SQL injection)
app.get(&amp;#x27;/user/:id&amp;#x27;, (req, res) =&amp;gt; {
  const query = &amp;#x60;SELECT * FROM users WHERE id = ${req.params.id}&amp;#x60;;
  // Это уязвимо к SQL injection!
  res.json({ query, message: &amp;#x27;This is vulnerable!&amp;#x27; });
});

// Секрет в коде (плохая практика)
const API_KEY = &amp;quot;sk-1234567890abcdef&amp;quot;;
const DB_PASSWORD = &amp;quot;password123&amp;quot;;

app.listen(3000, () =&amp;gt; {
  console.log(&amp;#x27;Server running on port 3000&amp;#x27;);
});
EOF

# 4. Создание GitHub Actions workflow (используйте пример выше)
mkdir -p .github/workflows
# Скопируйте security.yml из примера выше
&lt;/pre&gt;
  &lt;h2 id=&quot;Gq2t&quot;&gt;Задание 11.2: Установка и настройка Vault&lt;/h2&gt;
  &lt;pre id=&quot;rBve&quot; data-lang=&quot;bash&quot;&gt;# 1. Установка Vault
wget https://releases.hashicorp.com/vault/1.15.0/vault_1.15.0_linux_amd64.zip
unzip vault_1.15.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

# 2. Создание конфигурации Vault
cat &amp;gt; vault-config.hcl &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
storage &amp;quot;file&amp;quot; {
  path = &amp;quot;./vault-data&amp;quot;
}

listener &amp;quot;tcp&amp;quot; {
  address = &amp;quot;127.0.0.1:8200&amp;quot;
  tls_disable = true
}

ui = true
EOF

# 3. Инициализация Vault
vault server -config=vault-config.hcl &amp;amp;
export VAULT_ADDR=&amp;#x27;http://127.0.0.1:8200&amp;#x27;

# Инициализация (сохраните ключи!)
vault operator init

# Разблокировка Vault (используйте 3 ключа из вывода init)
vault operator unseal &amp;lt;key1&amp;gt;
vault operator unseal &amp;lt;key2&amp;gt;
vault operator unseal &amp;lt;key3&amp;gt;

# 4. Настройка секретов приложения
vault auth &amp;lt;root-token&amp;gt;

# Включение KV секретов
vault secrets enable -path=secret kv-v2

# Сохранение секретов
vault kv put secret/myapp/database \
    username=&amp;quot;dbuser&amp;quot; \
    password=&amp;quot;secure-password-123&amp;quot;

vault kv put secret/myapp/api \
    key=&amp;quot;sk-secure-api-key-456&amp;quot; \
    url=&amp;quot;https://api.example.com&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;SCuz&quot;&gt;Задание 11.3: Сканирование безопасности&lt;/h2&gt;
  &lt;pre id=&quot;hlw7&quot; data-lang=&quot;bash&quot;&gt;# 1. Установка инструментов сканирования
# Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# TruffleHog для поиска секретов
pip install truffleHog

# 2. Сканирование проекта
# Поиск секретов в Git истории
truffleHog --regex --entropy=False .

# Сканирование зависимостей
npm audit

# Сканирование Docker образа
docker build -t vulnerable-app .
trivy image vulnerable-app

# 3. Создание отчета безопасности
cat &amp;gt; security-scan.sh &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
#!/bin/bash

echo &amp;quot;=== Security Scan Report ===&amp;quot;
echo &amp;quot;Date: $(date)&amp;quot;
echo

echo &amp;quot;=== Dependency Vulnerabilities ===&amp;quot;
npm audit --json &amp;gt; npm-audit.json
cat npm-audit.json | jq &amp;#x27;.vulnerabilities | length&amp;#x27;

echo &amp;quot;=== Secret Scanning ===&amp;quot;
truffleHog --regex --entropy=False . &amp;gt; secrets-report.txt
cat secrets-report.txt

echo &amp;quot;=== Container Scanning ===&amp;quot;
trivy image --format json vulnerable-app &amp;gt; container-scan.json
cat container-scan.json | jq &amp;#x27;.Results[].Vulnerabilities | length&amp;#x27;
EOF

chmod +x security-scan.sh
./security-scan.sh
&lt;/pre&gt;
  &lt;h2 id=&quot;UFBv&quot;&gt;Задание 11.4: Network Security в Kubernetes&lt;/h2&gt;
  &lt;pre id=&quot;Z2B8&quot;&gt;# network-policies.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: frontend-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 8080
  - to: []  # DNS разрешение
    ports:
    - protocol: UDP
      port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-netpol
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;8R54&quot;&gt;🔍 Мониторинг безопасности&lt;/h2&gt;
  &lt;h2 id=&quot;C55e&quot;&gt;Falco для обнаружения аномалий&lt;/h2&gt;
  &lt;pre id=&quot;b4OU&quot;&gt;# falco-deployment.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: falco
  namespace: falco-system
spec:
  selector:
    matchLabels:
      app: falco
  template:
    metadata:
      labels:
        app: falco
    spec:
      serviceAccount: falco
      hostNetwork: true
      hostPID: true
      containers:
      - name: falco
        image: falcosecurity/falco:latest
        securityContext:
          privileged: true
        args:
          - /usr/bin/falco
          - --cri=/run/containerd/containerd.sock
          - --k8s-api=https://kubernetes.default:443
        volumeMounts:
        - name: dev
          mountPath: /host/dev
        - name: proc
          mountPath: /host/proc
        - name: boot
          mountPath: /host/boot
        - name: lib-modules
          mountPath: /host/lib/modules
        - name: usr
          mountPath: /host/usr
        - name: etc
          mountPath: /host/etc
      volumes:
      - name: dev
        hostPath:
          path: /dev
      - name: proc
        hostPath:
          path: /proc
      - name: boot
        hostPath:
          path: /boot
      - name: lib-modules
        hostPath:
          path: /lib/modules
      - name: usr
        hostPath:
          path: /usr
      - name: etc
        hostPath:
          path: /etc
&lt;/pre&gt;
  &lt;h2 id=&quot;2EYv&quot;&gt;Пользовательские правила Falco&lt;/h2&gt;
  &lt;pre id=&quot;Unnr&quot;&gt;# custom-rules.yaml
- rule: Suspicious Network Activity
  desc: Detect suspicious network connections
  condition: &amp;gt;
    spawned_process and
    proc.name in (nc, ncat, netcat) and
    not proc.args contains &amp;quot;-l&amp;quot;
  output: &amp;gt;
    Suspicious network activity detected
    (user=%user.name command=%proc.cmdline container=%container.name)
  priority: WARNING

- rule: Unauthorized File Access
  desc: Detect access to sensitive files
  condition: &amp;gt;
    open_read and
    fd.name in (/etc/passwd, /etc/shadow, /etc/hosts) and
    not proc.name in (systemd, sshd)
  output: &amp;gt;
    Unauthorized access to sensitive file
    (user=%user.name file=%fd.name proc=%proc.name container=%container.name)
  priority: CRITICAL
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;compliance&quot;&gt;📊 Compliance и аудит&lt;/h2&gt;
  &lt;h2 id=&quot;790t&quot;&gt;CIS Kubernetes Benchmark&lt;/h2&gt;
  &lt;pre id=&quot;xGND&quot; data-lang=&quot;bash&quot;&gt;# Установка kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml

# Просмотр результатов
kubectl logs job.batch/kube-bench

# Сохранение отчета
kubectl logs job.batch/kube-bench &amp;gt; cis-benchmark-report.txt

# Проверка соответствия с kube-score
kubectl score deployment.yaml
&lt;/pre&gt;
  &lt;h2 id=&quot;l7tP&quot;&gt;Policy as Code с Open Policy Agent&lt;/h2&gt;
  &lt;pre id=&quot;JYEV&quot;&gt;# security-policies.rego
package kubernetes.security

# Запрет запуска контейнеров от root
deny[msg] {
    input.kind == &amp;quot;Pod&amp;quot;
    input.spec.securityContext.runAsUser == 0
    msg := &amp;quot;Containers must not run as root user&amp;quot;
}

# Обязательное использование read-only root filesystem
deny[msg] {
    input.kind == &amp;quot;Pod&amp;quot;
    container := input.spec.containers[_]
    not container.securityContext.readOnlyRootFilesystem
    msg := sprintf(&amp;quot;Container %s must have read-only root filesystem&amp;quot;, [container.name])
}

# Запрет privileged контейнеров
deny[msg] {
    input.kind == &amp;quot;Pod&amp;quot;
    container := input.spec.containers[_]
    container.securityContext.privileged == true
    msg := sprintf(&amp;quot;Container %s cannot run in privileged mode&amp;quot;, [container.name])
}

# Обязательные resource limits
deny[msg] {
    input.kind == &amp;quot;Pod&amp;quot;
    container := input.spec.containers[_]
    not container.resources.limits.memory
    msg := sprintf(&amp;quot;Container %s must have memory limits&amp;quot;, [container.name])
}

# Запрет использования latest тегов
deny[msg] {
    input.kind == &amp;quot;Pod&amp;quot;
    container := input.spec.containers[_]
    endswith(container.image, &amp;quot;:latest&amp;quot;)
    msg := sprintf(&amp;quot;Container %s must not use &amp;#x27;latest&amp;#x27; tag&amp;quot;, [container.name])
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Bzb7&quot;&gt;📖 Полезные ресурсы&lt;/h2&gt;
  &lt;ul id=&quot;8d0B&quot;&gt;
    &lt;li id=&quot;xxOD&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://owasp.org/www-project-devsecops-guideline/&quot; target=&quot;_blank&quot;&gt;OWASP DevSecOps Guideline&lt;/a&gt;&lt;/strong&gt; — практики безопасности в DevOps&lt;/li&gt;
    &lt;li id=&quot;hkrC&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.nist.gov/cyberframework&quot; target=&quot;_blank&quot;&gt;NIST Cybersecurity Framework&lt;/a&gt;&lt;/strong&gt; — стандарты кибербезопасности&lt;/li&gt;
    &lt;li id=&quot;bFSz&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.cisecurity.org/controls/&quot; target=&quot;_blank&quot;&gt;CIS Controls&lt;/a&gt;&lt;/strong&gt; — критичные контроли безопасности&lt;/li&gt;
    &lt;li id=&quot;2A9J&quot;&gt;&lt;strong&gt;YouTube:&lt;/strong&gt; &amp;quot;DevSecOps: безопасность в CI/CD&amp;quot; — практические видеоуроки&lt;/li&gt;
    &lt;li id=&quot;k2er&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/TaptuIT/awesome-devsecops&quot; target=&quot;_blank&quot;&gt;Awesome DevSecOps&lt;/a&gt;&lt;/strong&gt; — коллекция инструментов и ресурсов&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;S4wc&quot;&gt;✅ Чек-лист модуля&lt;/h2&gt;
  &lt;ul id=&quot;Qz4p&quot;&gt;
    &lt;li id=&quot;ycMp&quot;&gt;Понимаю принципы DevSecOps и Shift Left Security&lt;/li&gt;
    &lt;li id=&quot;7Y7c&quot;&gt;Настроил автоматическое сканирование безопасности в CI/CD&lt;/li&gt;
    &lt;li id=&quot;pkDZ&quot;&gt;Интегрировал проверку секретов с TruffleHog&lt;/li&gt;
    &lt;li id=&quot;uI4d&quot;&gt;Добавил сканирование зависимостей с Snyk&lt;/li&gt;
    &lt;li id=&quot;ucZr&quot;&gt;Настроил сканирование Docker образов с Trivy&lt;/li&gt;
    &lt;li id=&quot;rked&quot;&gt;Установил и настроил HashiCorp Vault&lt;/li&gt;
    &lt;li id=&quot;q7pv&quot;&gt;Создал безопасные Dockerfile согласно best practices&lt;/li&gt;
    &lt;li id=&quot;8Odv&quot;&gt;Настроил Network Policies в Kubernetes&lt;/li&gt;
    &lt;li id=&quot;yMpX&quot;&gt;Изучил мониторинг безопасности с Falco&lt;/li&gt;
    &lt;li id=&quot;pyQc&quot;&gt;Понимаю основы compliance и Policy as Code&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h2 id=&quot;IzTn&quot;&gt;🚀 Что дальше?&lt;/h2&gt;
    &lt;p id=&quot;4TUQ&quot;&gt;После освоения DevSecOps переходите к &lt;strong&gt;Финальному проекту&lt;/strong&gt;, где объедините все изученные навыки для создания полноценной DevOps инфраструктуры с интегрированной безопасностью.&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>lalimi:dXRooxklNcr</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/dXRooxklNcr?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Модуль 10: Облачные платформы для DevOps</title><published>2025-06-11T11:12:24.931Z</published><updated>2025-06-11T11:12:24.931Z</updated><summary type="html">Курс DevOps для новичков 2025</summary><content type="html">
  &lt;p id=&quot;10----devops&quot;&gt;&lt;em&gt;Курс DevOps для новичков 2025&lt;/em&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;twL4&quot;&gt;☁️ Зачем изучать облачные платформы?&lt;/h2&gt;
  &lt;p id=&quot;w0LS&quot;&gt;&lt;strong&gt;Облако&lt;/strong&gt; — это не просто чужие компьютеры. Это глобальная инфраструктура с автоматическим масштабированием, managed сервисами и pay-as-you-use моделью. Современные компании мигрируют в облако для снижения затрат, повышения гибкости и ускорения разработки.&lt;/p&gt;
  &lt;p id=&quot;yKrS&quot;&gt;По данным исследований 2025 года, более &lt;strong&gt;94% предприятий&lt;/strong&gt; используют облачные сервисы, а &lt;strong&gt;83% рабочих нагрузок&lt;/strong&gt; работают в облаке. Знание облачных платформ стало обязательным навыком для DevOps-инженеров.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;UFHk&quot;&gt;🏆 Большая тройка облачных провайдеров&lt;/h2&gt;
  &lt;h2 id=&quot;9cN9&quot;&gt;Amazon Web Services (AWS)&lt;/h2&gt;
  &lt;p id=&quot;yYpD&quot;&gt;&lt;strong&gt;Лидер рынка&lt;/strong&gt; с самой широкой экосистемой сервисов (более 200 сервисов). Первопроходец в области облачных вычислений.&lt;/p&gt;
  &lt;h2 id=&quot;4Ube&quot;&gt;Microsoft Azure&lt;/h2&gt;
  &lt;p id=&quot;Xaxe&quot;&gt;Отличная &lt;strong&gt;интеграция с корпоративными продуктами&lt;/strong&gt; Microsoft. Сильные позиции в hybrid cloud решениях.&lt;/p&gt;
  &lt;h2 id=&quot;vakG&quot;&gt;Google Cloud Platform (GCP)&lt;/h2&gt;
  &lt;p id=&quot;IDOo&quot;&gt;Сильные позиции в &lt;strong&gt;машинном обучении и анализе данных&lt;/strong&gt;. Инновационные решения для контейнеров и Kubernetes.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;ZlaH&quot;&gt;🔧 Основные сервисы облачных платформ&lt;/h2&gt;
  &lt;h2 id=&quot;aTHJ&quot;&gt;Вычислительные ресурсы&lt;/h2&gt;
  &lt;p id=&quot;YJyt&quot;&gt;&lt;strong&gt;Виртуальные машины:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;Pikh&quot;&gt;
    &lt;li id=&quot;R4lr&quot;&gt;&lt;strong&gt;AWS EC2&lt;/strong&gt; — Elastic Compute Cloud&lt;/li&gt;
    &lt;li id=&quot;jPZg&quot;&gt;&lt;strong&gt;Azure Virtual Machines&lt;/strong&gt; — виртуальные машины Azure&lt;/li&gt;
    &lt;li id=&quot;wEla&quot;&gt;&lt;strong&gt;GCP Compute Engine&lt;/strong&gt; — вычислительные экземпляры&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;KdZL&quot;&gt;&lt;strong&gt;Serverless вычисления:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;KBjz&quot;&gt;
    &lt;li id=&quot;Ag8x&quot;&gt;&lt;strong&gt;AWS Lambda&lt;/strong&gt; — выполнение кода без серверов&lt;/li&gt;
    &lt;li id=&quot;cBEd&quot;&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt; — событийно-ориентированные функции&lt;/li&gt;
    &lt;li id=&quot;1JA0&quot;&gt;&lt;strong&gt;Google Cloud Functions&lt;/strong&gt; — легковесные функции&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;h4IC&quot;&gt;&lt;strong&gt;Контейнерные сервисы:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;u4JC&quot;&gt;
    &lt;li id=&quot;EgO0&quot;&gt;&lt;strong&gt;AWS ECS/EKS&lt;/strong&gt; — управляемые контейнеры и Kubernetes&lt;/li&gt;
    &lt;li id=&quot;YkAQ&quot;&gt;&lt;strong&gt;Azure AKS&lt;/strong&gt; — Azure Kubernetes Service&lt;/li&gt;
    &lt;li id=&quot;rSAM&quot;&gt;&lt;strong&gt;GCP GKE&lt;/strong&gt; — Google Kubernetes Engine&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;Jbsg&quot;&gt;Хранение данных&lt;/h2&gt;
  &lt;p id=&quot;Gt8i&quot;&gt;&lt;strong&gt;Объектное хранилище:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;B1u6&quot;&gt;
    &lt;li id=&quot;47ng&quot;&gt;&lt;strong&gt;AWS S3&lt;/strong&gt; — Simple Storage Service&lt;/li&gt;
    &lt;li id=&quot;ThFQ&quot;&gt;&lt;strong&gt;Azure Blob Storage&lt;/strong&gt; — хранилище больших объектов&lt;/li&gt;
    &lt;li id=&quot;2YYa&quot;&gt;&lt;strong&gt;GCP Cloud Storage&lt;/strong&gt; — объектное хранилище Google&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;oNee&quot;&gt;&lt;strong&gt;Базы данных:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;kd3W&quot;&gt;
    &lt;li id=&quot;u28z&quot;&gt;&lt;strong&gt;AWS RDS&lt;/strong&gt; — реляционные базы данных&lt;/li&gt;
    &lt;li id=&quot;BasP&quot;&gt;&lt;strong&gt;Azure SQL Database&lt;/strong&gt; — управляемый SQL Server&lt;/li&gt;
    &lt;li id=&quot;pFG0&quot;&gt;&lt;strong&gt;GCP Cloud SQL&lt;/strong&gt; — управляемые БД&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;XX2X&quot;&gt;Сетевые сервисы&lt;/h2&gt;
  &lt;p id=&quot;s1Eq&quot;&gt;&lt;strong&gt;Виртуальные сети:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;rQnc&quot;&gt;
    &lt;li id=&quot;GcuK&quot;&gt;&lt;strong&gt;AWS VPC&lt;/strong&gt; — Virtual Private Cloud&lt;/li&gt;
    &lt;li id=&quot;3JRv&quot;&gt;&lt;strong&gt;Azure Virtual Network&lt;/strong&gt; — виртуальные сети Azure&lt;/li&gt;
    &lt;li id=&quot;aaU7&quot;&gt;&lt;strong&gt;GCP VPC&lt;/strong&gt; — Virtual Private Cloud Google&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;agHp&quot;&gt;&lt;strong&gt;CDN и доставка контента:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;RsIB&quot;&gt;
    &lt;li id=&quot;RvV9&quot;&gt;&lt;strong&gt;AWS CloudFront&lt;/strong&gt; — глобальная сеть доставки контента&lt;/li&gt;
    &lt;li id=&quot;QjHJ&quot;&gt;&lt;strong&gt;Azure CDN&lt;/strong&gt; — сеть доставки контента Microsoft&lt;/li&gt;
    &lt;li id=&quot;h9sD&quot;&gt;&lt;strong&gt;GCP Cloud CDN&lt;/strong&gt; — CDN от Google&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;aws&quot;&gt;🛠️ Практика с AWS&lt;/h2&gt;
  &lt;h2 id=&quot;6pq0&quot;&gt;Настройка AWS CLI&lt;/h2&gt;
  &lt;pre id=&quot;TLe5&quot; data-lang=&quot;bash&quot;&gt;# Установка AWS CLI v2
curl &amp;quot;https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip&amp;quot; -o &amp;quot;awscliv2.zip&amp;quot;
unzip awscliv2.zip
sudo ./aws/install

# Проверка установки
aws --version

# Настройка credentials (нужен AWS аккаунт)
aws configure
# AWS Access Key ID: [ваш ключ]
# AWS Secret Access Key: [ваш секретный ключ]
# Default region name: us-west-2
# Default output format: json
&lt;/pre&gt;
  &lt;h2 id=&quot;8LhB&quot;&gt;Создание EC2 инстанса&lt;/h2&gt;
  &lt;pre id=&quot;VSzK&quot; data-lang=&quot;bash&quot;&gt;# Создание ключевой пары
aws ec2 create-key-pair \
    --key-name devops-course-key \
    --query &amp;#x27;KeyMaterial&amp;#x27; \
    --output text &amp;gt; devops-course-key.pem

chmod 400 devops-course-key.pem

# Создание security group
aws ec2 create-security-group \
    --group-name devops-sg \
    --description &amp;quot;Security group for DevOps course&amp;quot;

# Получение ID security group
SG_ID=$(aws ec2 describe-security-groups \
    --group-names devops-sg \
    --query &amp;#x27;SecurityGroups[0].GroupId&amp;#x27; \
    --output text)

# Разрешение SSH доступа
aws ec2 authorize-security-group-ingress \
    --group-id $SG_ID \
    --protocol tcp \
    --port 22 \
    --cidr 0.0.0.0/0

# Разрешение HTTP доступа
aws ec2 authorize-security-group-ingress \
    --group-id $SG_ID \
    --protocol tcp \
    --port 80 \
    --cidr 0.0.0.0/0

# Запуск EC2 инстанса
aws ec2 run-instances \
    --image-id ami-0c02fb55956c7d316 \
    --count 1 \
    --instance-type t2.micro \
    --key-name devops-course-key \
    --security-group-ids $SG_ID \
    --tag-specifications &amp;#x27;ResourceType=instance,Tags=[{Key=Name,Value=DevOps-Course-Server}]&amp;#x27;
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;h1Y0&quot;&gt;🛠️ Практические задания&lt;/h2&gt;
  &lt;h2 id=&quot;mVMw&quot;&gt;Задание 10.1: Развертывание веб-приложения в AWS&lt;/h2&gt;
  &lt;pre id=&quot;NwxO&quot; data-lang=&quot;bash&quot;&gt;# 1. Получение публичного IP созданного инстанса
INSTANCE_ID=$(aws ec2 describe-instances \
    --filters &amp;quot;Name=tag:Name,Values=DevOps-Course-Server&amp;quot; \
    --query &amp;#x27;Reservations[0].Instances[0].InstanceId&amp;#x27; \
    --output text)

PUBLIC_IP=$(aws ec2 describe-instances \
    --instance-ids $INSTANCE_ID \
    --query &amp;#x27;Reservations[0].Instances[0].PublicIpAddress&amp;#x27; \
    --output text)

echo &amp;quot;Instance IP: $PUBLIC_IP&amp;quot;

# 2. Подключение к серверу
ssh -i devops-course-key.pem ubuntu@$PUBLIC_IP

# 3. Установка Docker на сервере
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker ubuntu

# 4. Запуск простого веб-приложения
docker run -d --name web-app -p 80:80 nginx:alpine

# 5. Проверка работы
curl http://$PUBLIC_IP
&lt;/pre&gt;
  &lt;h2 id=&quot;0s33&quot;&gt;Задание 10.2: Создание S3 bucket и загрузка файлов&lt;/h2&gt;
  &lt;pre id=&quot;grXm&quot; data-lang=&quot;bash&quot;&gt;# Создание уникального имени bucket
BUCKET_NAME=&amp;quot;devops-course-$(date +%s)&amp;quot;

# Создание S3 bucket
aws s3 mb s3://$BUCKET_NAME

# Создание тестового файла
echo &amp;quot;Hello from DevOps course!&amp;quot; &amp;gt; test-file.txt

# Загрузка файла в S3
aws s3 cp test-file.txt s3://$BUCKET_NAME/

# Просмотр содержимого bucket
aws s3 ls s3://$BUCKET_NAME/

# Создание статического веб-сайта
cat &amp;gt; index.html &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;DevOps Course - S3 Static Website&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to DevOps Course!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This website is hosted on AWS S3&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Deployed at: &amp;lt;span id=&amp;quot;timestamp&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;script&amp;gt;
        document.getElementById(&amp;#x27;timestamp&amp;#x27;).textContent = new Date().toLocaleString();
    &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
EOF

# Загрузка веб-сайта
aws s3 cp index.html s3://$BUCKET_NAME/ --acl public-read

# Настройка статического хостинга
aws s3 website s3://$BUCKET_NAME/ \
    --index-document index.html \
    --error-document error.html

echo &amp;quot;Website URL: http://$BUCKET_NAME.s3-website-us-west-2.amazonaws.com&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;5c6w&quot;&gt;Задание 10.3: Serverless функция с AWS Lambda&lt;/h2&gt;
  &lt;pre id=&quot;8qdJ&quot; data-lang=&quot;python&quot;&gt;# lambda_function.py
import json
import boto3
from datetime import datetime

def lambda_handler(event, context):
    &amp;quot;&amp;quot;&amp;quot;
    AWS Lambda функция для обработки HTTP запросов
    &amp;quot;&amp;quot;&amp;quot;
    
    # Логирование входящего события
    print(f&amp;quot;Received event: {json.dumps(event)}&amp;quot;)
    
    # Получение параметров из запроса
    http_method = event.get(&amp;#x27;httpMethod&amp;#x27;, &amp;#x27;GET&amp;#x27;)
    path = event.get(&amp;#x27;path&amp;#x27;, &amp;#x27;/&amp;#x27;)
    query_params = event.get(&amp;#x27;queryStringParameters&amp;#x27;) or {}
    
    # Обработка различных путей
    if path == &amp;#x27;/health&amp;#x27;:
        return {
            &amp;#x27;statusCode&amp;#x27;: 200,
            &amp;#x27;headers&amp;#x27;: {
                &amp;#x27;Content-Type&amp;#x27;: &amp;#x27;application/json&amp;#x27;,
                &amp;#x27;Access-Control-Allow-Origin&amp;#x27;: &amp;#x27;*&amp;#x27;
            },
            &amp;#x27;body&amp;#x27;: json.dumps({
                &amp;#x27;status&amp;#x27;: &amp;#x27;healthy&amp;#x27;,
                &amp;#x27;timestamp&amp;#x27;: datetime.utcnow().isoformat(),
                &amp;#x27;version&amp;#x27;: &amp;#x27;1.0.0&amp;#x27;
            })
        }
    
    elif path == &amp;#x27;/info&amp;#x27; and http_method == &amp;#x27;GET&amp;#x27;:
        return {
            &amp;#x27;statusCode&amp;#x27;: 200,
            &amp;#x27;headers&amp;#x27;: {
                &amp;#x27;Content-Type&amp;#x27;: &amp;#x27;application/json&amp;#x27;,
                &amp;#x27;Access-Control-Allow-Origin&amp;#x27;: &amp;#x27;*&amp;#x27;
            },
            &amp;#x27;body&amp;#x27;: json.dumps({
                &amp;#x27;message&amp;#x27;: &amp;#x27;DevOps Course Lambda Function&amp;#x27;,
                &amp;#x27;timestamp&amp;#x27;: datetime.utcnow().isoformat(),
                &amp;#x27;method&amp;#x27;: http_method,
                &amp;#x27;query_params&amp;#x27;: query_params
            })
        }
    
    else:
        return {
            &amp;#x27;statusCode&amp;#x27;: 404,
            &amp;#x27;headers&amp;#x27;: {
                &amp;#x27;Content-Type&amp;#x27;: &amp;#x27;application/json&amp;#x27;,
                &amp;#x27;Access-Control-Allow-Origin&amp;#x27;: &amp;#x27;*&amp;#x27;
            },
            &amp;#x27;body&amp;#x27;: json.dumps({
                &amp;#x27;error&amp;#x27;: &amp;#x27;Not Found&amp;#x27;,
                &amp;#x27;path&amp;#x27;: path,
                &amp;#x27;method&amp;#x27;: http_method
            })
        }
&lt;/pre&gt;
  &lt;pre id=&quot;Hkif&quot; data-lang=&quot;bash&quot;&gt;# Создание Lambda функции
zip lambda_function.zip lambda_function.py

# Создание роли для Lambda
aws iam create-role \
    --role-name lambda-execution-role \
    --assume-role-policy-document &amp;#x27;{
        &amp;quot;Version&amp;quot;: &amp;quot;2012-10-17&amp;quot;,
        &amp;quot;Statement&amp;quot;: [
            {
                &amp;quot;Effect&amp;quot;: &amp;quot;Allow&amp;quot;,
                &amp;quot;Principal&amp;quot;: {
                    &amp;quot;Service&amp;quot;: &amp;quot;lambda.amazonaws.com&amp;quot;
                },
                &amp;quot;Action&amp;quot;: &amp;quot;sts:AssumeRole&amp;quot;
            }
        ]
    }&amp;#x27;

# Присоединение политики
aws iam attach-role-policy \
    --role-name lambda-execution-role \
    --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

# Создание Lambda функции
aws lambda create-function \
    --function-name devops-course-function \
    --runtime python3.9 \
    --role arn:aws:iam::ACCOUNT-ID:role/lambda-execution-role \
    --handler lambda_function.lambda_handler \
    --zip-file fileb://lambda_function.zip

# Тестирование функции
aws lambda invoke \
    --function-name devops-course-function \
    --payload &amp;#x27;{&amp;quot;httpMethod&amp;quot;: &amp;quot;GET&amp;quot;, &amp;quot;path&amp;quot;: &amp;quot;/health&amp;quot;}&amp;#x27; \
    response.json

cat response.json
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform&quot;&gt;🔧 Terraform для облачной инфраструктуры&lt;/h2&gt;
  &lt;h2 id=&quot;S7nS&quot;&gt;AWS инфраструктура с Terraform&lt;/h2&gt;
  &lt;pre id=&quot;92pM&quot;&gt;# main.tf
terraform {
  required_providers {
    aws = {
      source  = &amp;quot;hashicorp/aws&amp;quot;
      version = &amp;quot;~&amp;gt; 5.0&amp;quot;
    }
  }
}

provider &amp;quot;aws&amp;quot; {
  region = var.aws_region
}

# VPC
resource &amp;quot;aws_vpc&amp;quot; &amp;quot;main&amp;quot; {
  cidr_block           = &amp;quot;10.0.0.0/16&amp;quot;
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = &amp;quot;devops-course-vpc&amp;quot;
  }
}

# Internet Gateway
resource &amp;quot;aws_internet_gateway&amp;quot; &amp;quot;main&amp;quot; {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = &amp;quot;devops-course-igw&amp;quot;
  }
}

# Public Subnet
resource &amp;quot;aws_subnet&amp;quot; &amp;quot;public&amp;quot; {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = &amp;quot;10.0.1.0/24&amp;quot;
  availability_zone       = &amp;quot;${var.aws_region}a&amp;quot;
  map_public_ip_on_launch = true

  tags = {
    Name = &amp;quot;devops-course-public-subnet&amp;quot;
  }
}

# Route Table
resource &amp;quot;aws_route_table&amp;quot; &amp;quot;public&amp;quot; {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = &amp;quot;0.0.0.0/0&amp;quot;
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = &amp;quot;devops-course-public-rt&amp;quot;
  }
}

resource &amp;quot;aws_route_table_association&amp;quot; &amp;quot;public&amp;quot; {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# Security Group
resource &amp;quot;aws_security_group&amp;quot; &amp;quot;web&amp;quot; {
  name_prefix = &amp;quot;devops-course-web-&amp;quot;
  vpc_id      = aws_vpc.main.id

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = &amp;quot;-1&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  tags = {
    Name = &amp;quot;devops-course-web-sg&amp;quot;
  }
}

# Application Load Balancer
resource &amp;quot;aws_lb&amp;quot; &amp;quot;main&amp;quot; {
  name               = &amp;quot;devops-course-alb&amp;quot;
  internal           = false
  load_balancer_type = &amp;quot;application&amp;quot;
  security_groups    = [aws_security_group.web.id]
  subnets            = [aws_subnet.public.id, aws_subnet.public2.id]

  enable_deletion_protection = false

  tags = {
    Name = &amp;quot;devops-course-alb&amp;quot;
  }
}

# Auto Scaling Group
resource &amp;quot;aws_launch_template&amp;quot; &amp;quot;web&amp;quot; {
  name_prefix   = &amp;quot;devops-course-&amp;quot;
  image_id      = data.aws_ami.ubuntu.id
  instance_type = var.instance_type

  vpc_security_group_ids = [aws_security_group.web.id]

  user_data = base64encode(templatefile(&amp;quot;${path.module}/user_data.sh&amp;quot;, {
    app_name = &amp;quot;devops-course&amp;quot;
  }))

  tag_specifications {
    resource_type = &amp;quot;instance&amp;quot;
    tags = {
      Name = &amp;quot;devops-course-web-server&amp;quot;
    }
  }
}

resource &amp;quot;aws_autoscaling_group&amp;quot; &amp;quot;web&amp;quot; {
  name                = &amp;quot;devops-course-asg&amp;quot;
  vpc_zone_identifier = [aws_subnet.public.id]
  target_group_arns   = [aws_lb_target_group.web.arn]
  health_check_type   = &amp;quot;ELB&amp;quot;
  
  min_size         = 1
  max_size         = 3
  desired_capacity = 2

  launch_template {
    id      = aws_launch_template.web.id
    version = &amp;quot;$Latest&amp;quot;
  }

  tag {
    key                 = &amp;quot;Name&amp;quot;
    value               = &amp;quot;devops-course-asg-instance&amp;quot;
    propagate_at_launch = true
  }
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;EXBS&quot;&gt;💰 Управление затратами в облаке&lt;/h2&gt;
  &lt;h2 id=&quot;4gjr&quot;&gt;AWS Cost Management&lt;/h2&gt;
  &lt;pre id=&quot;jCu6&quot; data-lang=&quot;bash&quot;&gt;# Просмотр текущих затрат
aws ce get-cost-and-usage \
    --time-period Start=2025-01-01,End=2025-01-31 \
    --granularity MONTHLY \
    --metrics BlendedCost

# Создание бюджета
cat &amp;gt; budget.json &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
{
  &amp;quot;BudgetName&amp;quot;: &amp;quot;DevOps-Course-Budget&amp;quot;,
  &amp;quot;BudgetLimit&amp;quot;: {
    &amp;quot;Amount&amp;quot;: &amp;quot;50&amp;quot;,
    &amp;quot;Unit&amp;quot;: &amp;quot;USD&amp;quot;
  },
  &amp;quot;TimeUnit&amp;quot;: &amp;quot;MONTHLY&amp;quot;,
  &amp;quot;CostFilters&amp;quot;: {
    &amp;quot;TagKey&amp;quot;: [&amp;quot;Project&amp;quot;],
    &amp;quot;TagValue&amp;quot;: [&amp;quot;DevOps-Course&amp;quot;]
  },
  &amp;quot;BudgetType&amp;quot;: &amp;quot;COST&amp;quot;
}
EOF

aws budgets create-budget \
    --account-id $(aws sts get-caller-identity --query Account --output text) \
    --budget file://budget.json
&lt;/pre&gt;
  &lt;h2 id=&quot;wmWE&quot;&gt;Оптимизация затрат&lt;/h2&gt;
  &lt;p id=&quot;VUf3&quot;&gt;&lt;strong&gt;Лучшие практики:&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;TWXq&quot;&gt;
    &lt;li id=&quot;Q6T5&quot;&gt;Используйте &lt;strong&gt;Reserved Instances&lt;/strong&gt; для долгосрочных нагрузок&lt;/li&gt;
    &lt;li id=&quot;ssFj&quot;&gt;Настройте &lt;strong&gt;Auto Scaling&lt;/strong&gt; для динамического масштабирования&lt;/li&gt;
    &lt;li id=&quot;chev&quot;&gt;Регулярно проверяйте &lt;strong&gt;неиспользуемые ресурсы&lt;/strong&gt;&lt;/li&gt;
    &lt;li id=&quot;m2g0&quot;&gt;Используйте &lt;strong&gt;Spot Instances&lt;/strong&gt; для некритичных задач&lt;/li&gt;
    &lt;li id=&quot;PqUZ&quot;&gt;Настройте &lt;strong&gt;lifecycle policies&lt;/strong&gt; для S3&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;iURi&quot;&gt;🔒 Безопасность в облаке&lt;/h2&gt;
  &lt;h2 id=&quot;5OzU&quot;&gt;Основные принципы&lt;/h2&gt;
  &lt;p id=&quot;xtJW&quot;&gt;&lt;strong&gt;Shared Responsibility Model&lt;/strong&gt; — модель разделенной ответственности:&lt;/p&gt;
  &lt;ul id=&quot;Fd4i&quot;&gt;
    &lt;li id=&quot;Mk5D&quot;&gt;&lt;strong&gt;Облачный провайдер&lt;/strong&gt; отвечает за безопасность облака&lt;/li&gt;
    &lt;li id=&quot;YyTQ&quot;&gt;&lt;strong&gt;Клиент&lt;/strong&gt; отвечает за безопасность в облаке&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;tDaA&quot;&gt;IAM (Identity and Access Management)&lt;/h2&gt;
  &lt;pre id=&quot;9ZCy&quot;&gt;json
{
  &amp;quot;Version&amp;quot;: &amp;quot;2012-10-17&amp;quot;,
  &amp;quot;Statement&amp;quot;: [
    {
      &amp;quot;Effect&amp;quot;: &amp;quot;Allow&amp;quot;,
      &amp;quot;Action&amp;quot;: [
        &amp;quot;s3:GetObject&amp;quot;,
        &amp;quot;s3:PutObject&amp;quot;
      ],
      &amp;quot;Resource&amp;quot;: &amp;quot;arn:aws:s3:::devops-course-bucket/*&amp;quot;
    },
    {
      &amp;quot;Effect&amp;quot;: &amp;quot;Allow&amp;quot;,
      &amp;quot;Action&amp;quot;: [
        &amp;quot;logs:CreateLogGroup&amp;quot;,
        &amp;quot;logs:CreateLogStream&amp;quot;,
        &amp;quot;logs:PutLogEvents&amp;quot;
      ],
      &amp;quot;Resource&amp;quot;: &amp;quot;arn:aws:logs:*:*:*&amp;quot;
    }
  ]
}
&lt;/pre&gt;
  &lt;h2 id=&quot;dK23&quot;&gt;Лучшие практики безопасности&lt;/h2&gt;
  &lt;ul id=&quot;TPj5&quot;&gt;
    &lt;li id=&quot;g8K5&quot;&gt;&lt;strong&gt;Принцип минимальных привилегий&lt;/strong&gt; — предоставляйте только необходимые права&lt;/li&gt;
    &lt;li id=&quot;xNno&quot;&gt;&lt;strong&gt;Multi-Factor Authentication&lt;/strong&gt; — включите 2FA для всех аккаунтов&lt;/li&gt;
    &lt;li id=&quot;cGwA&quot;&gt;&lt;strong&gt;Шифрование данных&lt;/strong&gt; — в покое и при передаче&lt;/li&gt;
    &lt;li id=&quot;RqSG&quot;&gt;&lt;strong&gt;Регулярный аудит&lt;/strong&gt; — проверяйте права доступа и логи&lt;/li&gt;
    &lt;li id=&quot;rZEh&quot;&gt;&lt;strong&gt;Сетевая сегментация&lt;/strong&gt; — используйте VPC и security groups&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Ehjv&quot;&gt;📖 Полезные ресурсы&lt;/h2&gt;
  &lt;ul id=&quot;OTf9&quot;&gt;
    &lt;li id=&quot;N781&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/free/&quot; target=&quot;_blank&quot;&gt;AWS Free Tier&lt;/a&gt;&lt;/strong&gt; — бесплатные ресурсы для изучения AWS&lt;/li&gt;
    &lt;li id=&quot;eVWw&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://azure.microsoft.com/free/&quot; target=&quot;_blank&quot;&gt;Azure Free Account&lt;/a&gt;&lt;/strong&gt; — $200 кредитов для новых пользователей&lt;/li&gt;
    &lt;li id=&quot;0F1O&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://cloud.google.com/free/&quot; target=&quot;_blank&quot;&gt;Google Cloud Free Tier&lt;/a&gt;&lt;/strong&gt; — $300 кредитов и Always Free ресурсы&lt;/li&gt;
    &lt;li id=&quot;leL5&quot;&gt;&lt;strong&gt;YouTube:&lt;/strong&gt; &amp;quot;AWS для DevOps инженеров&amp;quot; — практические видеоуроки&lt;/li&gt;
    &lt;li id=&quot;cfuV&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.microsoft.com/azure/architecture/&quot; target=&quot;_blank&quot;&gt;Cloud Architecture Center&lt;/a&gt;&lt;/strong&gt; — паттерны облачной архитектуры&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;ih9o&quot;&gt;✅ Чек-лист модуля&lt;/h2&gt;
  &lt;ul id=&quot;IKdZ&quot;&gt;
    &lt;li id=&quot;gA9O&quot;&gt;Понимаю основные концепции облачных вычислений&lt;/li&gt;
    &lt;li id=&quot;XePJ&quot;&gt;Изучил основные сервисы AWS/Azure/GCP&lt;/li&gt;
    &lt;li id=&quot;7Tnx&quot;&gt;Настроил AWS CLI и создал первые ресурсы&lt;/li&gt;
    &lt;li id=&quot;13Ib&quot;&gt;Развернул веб-приложение в облаке&lt;/li&gt;
    &lt;li id=&quot;TWMf&quot;&gt;Создал S3 bucket и настроил статический хостинг&lt;/li&gt;
    &lt;li id=&quot;p88m&quot;&gt;Написал и развернул Lambda функцию&lt;/li&gt;
    &lt;li id=&quot;GEB4&quot;&gt;Использовал Terraform для создания облачной инфраструктуры&lt;/li&gt;
    &lt;li id=&quot;Y7BP&quot;&gt;Настроил мониторинг затрат и бюджеты&lt;/li&gt;
    &lt;li id=&quot;j5ai&quot;&gt;Изучил основы безопасности в облаке&lt;/li&gt;
    &lt;li id=&quot;LEzO&quot;&gt;Понимаю принципы выбора облачного провайдера&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h2 id=&quot;ijrv&quot;&gt;🚀 Что дальше?&lt;/h2&gt;
    &lt;p id=&quot;55AZ&quot;&gt;После освоения облачных платформ переходите к &lt;strong&gt;Модулю 11: DevSecOps — Безопасность в DevOps&lt;/strong&gt; для изучения интеграции безопасности в процессы разработки и эксплуатации.&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>lalimi:IAFqUAdUrt5</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/IAFqUAdUrt5?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Модуль 9: Мониторинг и наблюдаемость в DevOps</title><published>2025-06-11T11:08:41.908Z</published><updated>2025-06-11T11:08:41.908Z</updated><summary type="html">Курс DevOps для новичков 2025</summary><content type="html">
  &lt;p id=&quot;9-----devops&quot;&gt;&lt;em&gt;Курс DevOps для новичков 2025&lt;/em&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;5MTc&quot;&gt;📊 Зачем нужен мониторинг?&lt;/h2&gt;
  &lt;p id=&quot;ub93&quot;&gt;&lt;strong&gt;Мониторинг&lt;/strong&gt; — это процесс непрерывного наблюдения за состоянием системы, сбора метрик и генерации предупреждений. Без мониторинга вы узнаете о проблемах только когда пользователи начнут жаловаться. Это как водить машину с закрытыми глазами — опасно и безответственно.&lt;/p&gt;
  &lt;p id=&quot;Y7mW&quot;&gt;По данным исследований 2025 года, &lt;strong&gt;87% компаний&lt;/strong&gt; с зрелыми практиками мониторинга обнаруживают проблемы до того, как они повлияют на пользователей&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;. Prometheus и Grafana стали стандартом де-факто для мониторинга в DevOps — как нож и вилка, вместе они делают мониторинг инфраструктуры и приложений простым и наглядным&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;Yp45&quot;&gt;🎯 Четыре золотых сигнала мониторинга&lt;/h2&gt;
  &lt;p id=&quot;IyeH&quot;&gt;Google SRE определила четыре ключевые метрики, которые должен отслеживать любой сервис:&lt;/p&gt;
  &lt;h2 id=&quot;e16A&quot;&gt;1. Latency (Задержка)&lt;/h2&gt;
  &lt;p id=&quot;3yFz&quot;&gt;Время ответа на запросы. Критично для пользовательского опыта.&lt;/p&gt;
  &lt;h2 id=&quot;Dr8n&quot;&gt;2. Traffic (Трафик)&lt;/h2&gt;
  &lt;p id=&quot;Uhe0&quot;&gt;Количество запросов в секунду. Показывает нагрузку на систему.&lt;/p&gt;
  &lt;h2 id=&quot;s9Lk&quot;&gt;3. Errors (Ошибки)&lt;/h2&gt;
  &lt;p id=&quot;J7BX&quot;&gt;Процент неуспешных запросов. Индикатор качества сервиса.&lt;/p&gt;
  &lt;h2 id=&quot;Lql4&quot;&gt;4. Saturation (Насыщенность)&lt;/h2&gt;
  &lt;p id=&quot;pv9r&quot;&gt;Использование ресурсов (CPU, память, диск). Предупреждает о приближении к лимитам.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;prometheus&quot;&gt;🔥 Prometheus — сердце мониторинга&lt;/h2&gt;
  &lt;p id=&quot;LY4M&quot;&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; — open-source система мониторинга, которая собирает метрики, хранит их в виде временных рядов и предоставляет мощный язык запросов PromQL&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;. Это движок мониторинга, который сам опрашивает сервисы, собирает данные и сохраняет их в своей базе&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;.&lt;/p&gt;
  &lt;h2 id=&quot;HuuL&quot;&gt;Архитектура Prometheus&lt;/h2&gt;
  &lt;p id=&quot;U1G0&quot;&gt;&lt;strong&gt;Prometheus Server&lt;/strong&gt; — основной компонент, который:&lt;/p&gt;
  &lt;ul id=&quot;RpLC&quot;&gt;
    &lt;li id=&quot;tUO8&quot;&gt;Собирает метрики с целевых систем (pull-модель)&lt;/li&gt;
    &lt;li id=&quot;gHzp&quot;&gt;Хранит данные в формате временных рядов&lt;/li&gt;
    &lt;li id=&quot;H00i&quot;&gt;Предоставляет HTTP API для запросов&lt;/li&gt;
    &lt;li id=&quot;w9nc&quot;&gt;Оценивает правила алертов&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;tn7t&quot;&gt;&lt;strong&gt;Exporters&lt;/strong&gt; — программы, которые собирают метрики:&lt;/p&gt;
  &lt;ul id=&quot;PcOT&quot;&gt;
    &lt;li id=&quot;A3wS&quot;&gt;&lt;strong&gt;Node Exporter&lt;/strong&gt; — метрики ОС Linux&lt;/li&gt;
    &lt;li id=&quot;oxrc&quot;&gt;&lt;strong&gt;cAdvisor&lt;/strong&gt; — метрики Docker контейнеров&lt;/li&gt;
    &lt;li id=&quot;zdLQ&quot;&gt;&lt;strong&gt;MySQL Exporter&lt;/strong&gt; — метрики базы данных&lt;/li&gt;
    &lt;li id=&quot;thpA&quot;&gt;&lt;strong&gt;Blackbox Exporter&lt;/strong&gt; — проверка доступности сервисов&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;7Wrn&quot;&gt;&lt;strong&gt;Alertmanager&lt;/strong&gt; — компонент для управления алертами и уведомлениями&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;KUHz&quot;&gt;⚙️ Установка стека мониторинга&lt;/h2&gt;
  &lt;h2 id=&quot;FOwj&quot;&gt;Docker Compose для полного стека&lt;/h2&gt;
  &lt;pre id=&quot;9Gmv&quot;&gt;# docker-compose.yml
version: &amp;#x27;3.8&amp;#x27;

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - &amp;quot;9090:9090&amp;quot;
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus/rules:/etc/prometheus/rules
      - prometheus_data:/prometheus
    command:
      - &amp;#x27;--config.file=/etc/prometheus/prometheus.yml&amp;#x27;
      - &amp;#x27;--storage.tsdb.path=/prometheus&amp;#x27;
      - &amp;#x27;--web.console.libraries=/etc/prometheus/console_libraries&amp;#x27;
      - &amp;#x27;--web.console.templates=/etc/prometheus/consoles&amp;#x27;
      - &amp;#x27;--storage.tsdb.retention.time=200h&amp;#x27;
      - &amp;#x27;--web.enable-lifecycle&amp;#x27;
      - &amp;#x27;--web.enable-admin-api&amp;#x27;
    restart: unless-stopped

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - &amp;quot;3000:3000&amp;quot;
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin123
      - GF_USERS_ALLOW_SIGN_UP=false
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    ports:
      - &amp;quot;9100:9100&amp;quot;
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - &amp;#x27;--path.procfs=/host/proc&amp;#x27;
      - &amp;#x27;--path.rootfs=/rootfs&amp;#x27;
      - &amp;#x27;--path.sysfs=/host/sys&amp;#x27;
      - &amp;#x27;--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)&amp;#x27;
    restart: unless-stopped

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    ports:
      - &amp;quot;8080:8080&amp;quot;
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    privileged: true
    restart: unless-stopped

  alertmanager:
    image: prom/alertmanager:latest
    container_name: alertmanager
    ports:
      - &amp;quot;9093:9093&amp;quot;
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml
    restart: unless-stopped

volumes:
  prometheus_data:
  grafana_data:
&lt;/pre&gt;
  &lt;h2 id=&quot;B1QD&quot;&gt;Конфигурация Prometheus&lt;/h2&gt;
  &lt;pre id=&quot;nISY&quot;&gt;# prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - &amp;quot;rules/*.yml&amp;quot;

scrape_configs:
  - job_name: &amp;#x27;prometheus&amp;#x27;
    static_configs:
      - targets: [&amp;#x27;localhost:9090&amp;#x27;]

  - job_name: &amp;#x27;node-exporter&amp;#x27;
    static_configs:
      - targets: [&amp;#x27;node-exporter:9100&amp;#x27;]

  - job_name: &amp;#x27;cadvisor&amp;#x27;
    static_configs:
      - targets: [&amp;#x27;cadvisor:8080&amp;#x27;]

  - job_name: &amp;#x27;my-app&amp;#x27;
    static_configs:
      - targets: [&amp;#x27;my-app:3000&amp;#x27;]
    metrics_path: &amp;#x27;/metrics&amp;#x27;
    scrape_interval: 5s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;promql&quot;&gt;📈 Основы PromQL&lt;/h2&gt;
  &lt;p id=&quot;7Stq&quot;&gt;PromQL — язык запросов Prometheus для анализа метрик:&lt;/p&gt;
  &lt;h2 id=&quot;bLGZ&quot;&gt;Базовые запросы&lt;/h2&gt;
  &lt;pre id=&quot;P1ej&quot;&gt;# Текущее значение метрики
up

# Фильтрация по лейблам
up{job=&amp;quot;node-exporter&amp;quot;}

# Арифметические операции
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes

# Процент использования памяти
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

# Загрузка CPU за последние 5 минут
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=&amp;quot;idle&amp;quot;}[5m])) * 100)
&lt;/pre&gt;
  &lt;h2 id=&quot;aSOo&quot;&gt;Функции времени&lt;/h2&gt;
  &lt;pre id=&quot;MR7R&quot;&gt;# Количество запросов в секунду
rate(http_requests_total[5m])

# Увеличение за период
increase(http_requests_total[1h])

# 95-й процентиль времени ответа
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# Среднее значение за период
avg_over_time(cpu_usage[10m])
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;6wCr&quot;&gt;🛠️ Практические задания&lt;/h2&gt;
  &lt;h2 id=&quot;upek&quot;&gt;Задание 9.1: Запуск стека мониторинга&lt;/h2&gt;
  &lt;pre id=&quot;oGp1&quot; data-lang=&quot;bash&quot;&gt;# 1. Создание структуры проекта
mkdir monitoring-stack
cd monitoring-stack
mkdir -p prometheus/rules grafana/provisioning alertmanager

# 2. Создание docker-compose.yml (используйте пример выше)

# 3. Запуск стека
docker-compose up -d

# 4. Проверка сервисов
curl http://localhost:9090/targets    # Prometheus targets
curl http://localhost:3000           # Grafana (admin/admin123)
curl http://localhost:9100/metrics   # Node Exporter metrics
&lt;/pre&gt;
  &lt;h2 id=&quot;osoa&quot;&gt;Задание 9.2: Мониторинг приложения&lt;/h2&gt;
  &lt;pre id=&quot;BS8q&quot; data-lang=&quot;javascript&quot;&gt;// app.js - Node.js приложение с метриками
const express = require(&amp;#x27;express&amp;#x27;);
const promClient = require(&amp;#x27;prom-client&amp;#x27;);

const app = express();
const port = process.env.PORT || 3000;

// Создание реестра метрик
const register = new promClient.Registry();

// Счетчик запросов
const httpRequestsTotal = new promClient.Counter({
  name: &amp;#x27;http_requests_total&amp;#x27;,
  help: &amp;#x27;Total number of HTTP requests&amp;#x27;,
  labelNames: [&amp;#x27;method&amp;#x27;, &amp;#x27;route&amp;#x27;, &amp;#x27;status_code&amp;#x27;],
  registers: [register]
});

// Гистограмма времени ответа
const httpRequestDuration = new promClient.Histogram({
  name: &amp;#x27;http_request_duration_seconds&amp;#x27;,
  help: &amp;#x27;Duration of HTTP requests in seconds&amp;#x27;,
  labelNames: [&amp;#x27;method&amp;#x27;, &amp;#x27;route&amp;#x27;, &amp;#x27;status_code&amp;#x27;],
  buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10],
  registers: [register]
});

// Gauge для активных подключений
const activeConnections = new promClient.Gauge({
  name: &amp;#x27;active_connections&amp;#x27;,
  help: &amp;#x27;Number of active connections&amp;#x27;,
  registers: [register]
});

// Middleware для сбора метрик
app.use((req, res, next) =&amp;gt; {
  const start = Date.now();
  
  res.on(&amp;#x27;finish&amp;#x27;, () =&amp;gt; {
    const duration = (Date.now() - start) / 1000;
    const route = req.route?.path || req.path;
    
    httpRequestsTotal
      .labels(req.method, route, res.statusCode.toString())
      .inc();
    
    httpRequestDuration
      .labels(req.method, route, res.statusCode.toString())
      .observe(duration);
  });
  
  next();
});

// Эндпоинт для метрик
app.get(&amp;#x27;/metrics&amp;#x27;, async (req, res) =&amp;gt; {
  res.set(&amp;#x27;Content-Type&amp;#x27;, register.contentType);
  res.end(await register.metrics());
});

// API эндпоинты
app.get(&amp;#x27;/&amp;#x27;, (req, res) =&amp;gt; {
  res.json({ 
    message: &amp;#x27;Hello Monitoring!&amp;#x27;,
    timestamp: new Date().toISOString()
  });
});

app.get(&amp;#x27;/health&amp;#x27;, (req, res) =&amp;gt; {
  res.json({ status: &amp;#x27;healthy&amp;#x27; });
});

app.get(&amp;#x27;/api/users&amp;#x27;, (req, res) =&amp;gt; {
  // Симуляция времени обработки
  setTimeout(() =&amp;gt; {
    res.json({ users: [&amp;#x27;Alice&amp;#x27;, &amp;#x27;Bob&amp;#x27;, &amp;#x27;Charlie&amp;#x27;] });
  }, Math.random() * 100);
});

app.listen(port, () =&amp;gt; {
  console.log(&amp;#x60;Server running on port ${port}&amp;#x60;);
});
&lt;/pre&gt;
  &lt;h2 id=&quot;hBlw&quot;&gt;Задание 9.3: Настройка алертов&lt;/h2&gt;
  &lt;pre id=&quot;b3v2&quot;&gt;# prometheus/rules/alerts.yml
groups:
  - name: system.rules
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: &amp;quot;Instance {{ $labels.instance }} down&amp;quot;
          description: &amp;quot;{{ $labels.instance }} has been down for more than 1 minute.&amp;quot;

      - alert: HighCPUUsage
        expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=&amp;quot;idle&amp;quot;}[5m])) * 100) &amp;gt; 80
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: &amp;quot;High CPU usage on {{ $labels.instance }}&amp;quot;
          description: &amp;quot;CPU usage is above 80% for more than 2 minutes.&amp;quot;

      - alert: HighMemoryUsage
        expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 &amp;gt; 90
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: &amp;quot;High memory usage on {{ $labels.instance }}&amp;quot;
          description: &amp;quot;Memory usage is above 90% for more than 2 minutes.&amp;quot;

      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes{mountpoint=&amp;quot;/&amp;quot;} / node_filesystem_size_bytes{mountpoint=&amp;quot;/&amp;quot;}) * 100 &amp;lt; 10
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: &amp;quot;Low disk space on {{ $labels.instance }}&amp;quot;
          description: &amp;quot;Disk space is below 10% on {{ $labels.instance }}.&amp;quot;

      - alert: HighErrorRate
        expr: rate(http_requests_total{status_code=~&amp;quot;5..&amp;quot;}[5m]) / rate(http_requests_total[5m]) &amp;gt; 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: &amp;quot;High error rate detected&amp;quot;
          description: &amp;quot;Error rate is above 10% for more than 5 minutes.&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;caez&quot;&gt;Конфигурация Alertmanager&lt;/h2&gt;
  &lt;pre id=&quot;46hm&quot;&gt;# alertmanager/alertmanager.yml
global:
  smtp_smarthost: &amp;#x27;localhost:587&amp;#x27;
  smtp_from: &amp;#x27;alerts@company.com&amp;#x27;

route:
  group_by: [&amp;#x27;alertname&amp;#x27;]
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: &amp;#x27;web.hook&amp;#x27;

receivers:
- name: &amp;#x27;web.hook&amp;#x27;
  email_configs:
  - to: &amp;#x27;admin@company.com&amp;#x27;
    subject: &amp;#x27;Alert: {{ .GroupLabels.alertname }}&amp;#x27;
    body: |
      {{ range .Alerts }}
      Alert: {{ .Annotations.summary }}
      Description: {{ .Annotations.description }}
      {{ end }}
  
  slack_configs:
  - api_url: &amp;#x27;YOUR_SLACK_WEBHOOK_URL&amp;#x27;
    channel: &amp;#x27;#alerts&amp;#x27;
    title: &amp;#x27;Alert: {{ .GroupLabels.alertname }}&amp;#x27;
    text: |
      {{ range .Alerts }}
      {{ .Annotations.summary }}
      {{ .Annotations.description }}
      {{ end }}

inhibit_rules:
  - source_match:
      severity: &amp;#x27;critical&amp;#x27;
    target_match:
      severity: &amp;#x27;warning&amp;#x27;
    equal: [&amp;#x27;alertname&amp;#x27;, &amp;#x27;dev&amp;#x27;, &amp;#x27;instance&amp;#x27;]
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;grafana&quot;&gt;📊 Grafana — визуализация данных&lt;/h2&gt;
  &lt;h2 id=&quot;NW4i&quot;&gt;Создание дашборда&lt;/h2&gt;
  &lt;pre id=&quot;w7BL&quot;&gt;json
# grafana/provisioning/dashboards/system-overview.json
{
  &amp;quot;dashboard&amp;quot;: {
    &amp;quot;title&amp;quot;: &amp;quot;System Overview&amp;quot;,
    &amp;quot;tags&amp;quot;: [&amp;quot;system&amp;quot;, &amp;quot;monitoring&amp;quot;],
    &amp;quot;panels&amp;quot;: [
      {
        &amp;quot;title&amp;quot;: &amp;quot;CPU Usage&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;stat&amp;quot;,
        &amp;quot;targets&amp;quot;: [
          {
            &amp;quot;expr&amp;quot;: &amp;quot;100 - (avg(irate(node_cpu_seconds_total{mode=\&amp;quot;idle\&amp;quot;}[5m])) * 100)&amp;quot;,
            &amp;quot;legendFormat&amp;quot;: &amp;quot;CPU Usage %&amp;quot;
          }
        ],
        &amp;quot;fieldConfig&amp;quot;: {
          &amp;quot;defaults&amp;quot;: {
            &amp;quot;unit&amp;quot;: &amp;quot;percent&amp;quot;,
            &amp;quot;thresholds&amp;quot;: {
              &amp;quot;steps&amp;quot;: [
                {&amp;quot;color&amp;quot;: &amp;quot;green&amp;quot;, &amp;quot;value&amp;quot;: null},
                {&amp;quot;color&amp;quot;: &amp;quot;yellow&amp;quot;, &amp;quot;value&amp;quot;: 70},
                {&amp;quot;color&amp;quot;: &amp;quot;red&amp;quot;, &amp;quot;value&amp;quot;: 90}
              ]
            }
          }
        }
      },
      {
        &amp;quot;title&amp;quot;: &amp;quot;Memory Usage&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;timeseries&amp;quot;,
        &amp;quot;targets&amp;quot;: [
          {
            &amp;quot;expr&amp;quot;: &amp;quot;(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100&amp;quot;,
            &amp;quot;legendFormat&amp;quot;: &amp;quot;Memory Usage %&amp;quot;
          }
        ]
      },
      {
        &amp;quot;title&amp;quot;: &amp;quot;HTTP Requests Rate&amp;quot;,
        &amp;quot;type&amp;quot;: &amp;quot;timeseries&amp;quot;,
        &amp;quot;targets&amp;quot;: [
          {
            &amp;quot;expr&amp;quot;: &amp;quot;rate(http_requests_total[5m])&amp;quot;,
            &amp;quot;legendFormat&amp;quot;: &amp;quot;{{ method }} {{ route }}&amp;quot;
          }
        ]
      }
    ]
  }
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;elk-stack&quot;&gt;🔍 Логирование с ELK Stack&lt;/h2&gt;
  &lt;h2 id=&quot;RIoL&quot;&gt;Docker Compose для ELK&lt;/h2&gt;
  &lt;pre id=&quot;7vrE&quot;&gt;# elk-stack.yml
version: &amp;#x27;3.8&amp;#x27;
services:
  elasticsearch:
    image: elasticsearch:8.11.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - &amp;quot;ES_JAVA_OPTS=-Xms512m -Xmx512m&amp;quot;
    ports:
      - &amp;quot;9200:9200&amp;quot;
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data

  kibana:
    image: kibana:8.11.0
    ports:
      - &amp;quot;5601:5601&amp;quot;
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch

  logstash:
    image: logstash:8.11.0
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline
    ports:
      - &amp;quot;5000:5000&amp;quot;
    depends_on:
      - elasticsearch

volumes:
  elasticsearch_data:
&lt;/pre&gt;
  &lt;h2 id=&quot;ZZdB&quot;&gt;Конфигурация Logstash&lt;/h2&gt;
  &lt;pre id=&quot;Caag&quot; data-lang=&quot;ruby&quot;&gt;ruby
# logstash/pipeline/logstash.conf
input {
  beats {
    port =&amp;gt; 5044
  }
  
  tcp {
    port =&amp;gt; 5000
    codec =&amp;gt; json
  }
}

filter {
  if [fields][service] == &amp;quot;nginx&amp;quot; {
    grok {
      match =&amp;gt; { &amp;quot;message&amp;quot; =&amp;gt; &amp;quot;%{NGINXACCESS}&amp;quot; }
    }
    
    date {
      match =&amp;gt; [ &amp;quot;timestamp&amp;quot;, &amp;quot;dd/MMM/yyyy:HH:mm:ss Z&amp;quot; ]
    }
  }
}

output {
  elasticsearch {
    hosts =&amp;gt; [&amp;quot;elasticsearch:9200&amp;quot;]
    index =&amp;gt; &amp;quot;logs-%{+YYYY.MM.dd}&amp;quot;
  }
  
  stdout {
    codec =&amp;gt; rubydebug
  }
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;H6Vg&quot;&gt;📖 Полезные ресурсы&lt;/h2&gt;
  &lt;ul id=&quot;NDXg&quot;&gt;
    &lt;li id=&quot;DeuX&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://prometheus.io/docs/&quot; target=&quot;_blank&quot;&gt;Prometheus Documentation&lt;/a&gt;&lt;/strong&gt; — официальная документация&lt;/li&gt;
    &lt;li id=&quot;gcbZ&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://grafana.com/docs/&quot; target=&quot;_blank&quot;&gt;Grafana Documentation&lt;/a&gt;&lt;/strong&gt; — руководство по Grafana&lt;/li&gt;
    &lt;li id=&quot;tj0w&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/querying/basics/&quot; target=&quot;_blank&quot;&gt;PromQL Tutorial&lt;/a&gt;&lt;/strong&gt; — изучение языка запросов&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;KEnj&quot;&gt;&lt;strong&gt;YouTube:&lt;/strong&gt; &amp;quot;Мониторинг в DevOps с Prometheus и Grafana&amp;quot; — практический курс&lt;/li&gt;
    &lt;li id=&quot;eZUL&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://sre.google/sre-book/monitoring-distributed-systems/&quot; target=&quot;_blank&quot;&gt;The Four Golden Signals&lt;/a&gt;&lt;/strong&gt; — принципы мониторинга от Google SRE&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;QFNU&quot;&gt;✅ Чек-лист модуля&lt;/h2&gt;
  &lt;ul id=&quot;R0uf&quot;&gt;
    &lt;li id=&quot;1aWK&quot;&gt;Понимаю важность мониторинга в DevOps&lt;/li&gt;
    &lt;li id=&quot;Y17a&quot;&gt;Знаю четыре золотых сигнала мониторинга&lt;/li&gt;
    &lt;li id=&quot;HO7y&quot;&gt;Установил и настроил Prometheus&lt;/li&gt;
    &lt;li id=&quot;iiQY&quot;&gt;Освоил основы PromQL для запросов метрик&lt;/li&gt;
    &lt;li id=&quot;MTVS&quot;&gt;Настроил сбор метрик с Node Exporter и cAdvisor&lt;/li&gt;
    &lt;li id=&quot;sstM&quot;&gt;Создал дашборды в Grafana&lt;/li&gt;
    &lt;li id=&quot;0QcB&quot;&gt;Настроил алерты в Prometheus и Alertmanager&lt;/li&gt;
    &lt;li id=&quot;C0Px&quot;&gt;Добавил метрики в собственное приложение&lt;/li&gt;
    &lt;li id=&quot;jwVc&quot;&gt;Изучил основы логирования с ELK Stack&lt;/li&gt;
    &lt;li id=&quot;UQJP&quot;&gt;Понимаю разницу между мониторингом и наблюдаемостью&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h2 id=&quot;BtLg&quot;&gt;🚀 Что дальше?&lt;/h2&gt;
    &lt;p id=&quot;WfEE&quot;&gt;После освоения мониторинга переходите к &lt;strong&gt;Модулю 10: Облачные платформы&lt;/strong&gt; для изучения современных облачных решений и их интеграции с системами мониторинга.&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>lalimi:Yqk30YHfsou</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/Yqk30YHfsou?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Модуль 8: Infrastructure as Code (IaC) — Управление инфраструктурой через код</title><published>2025-06-11T11:04:04.902Z</published><updated>2025-06-11T11:04:04.902Z</updated><summary type="html">Курс DevOps для новичков 2025</summary><content type="html">
  &lt;p id=&quot;8-infrastructure-as-code-iac&quot;&gt;&lt;em&gt;Курс DevOps для новичков 2025&lt;/em&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;infrastructure-as-code&quot;&gt;🏗️ Что такое Infrastructure as Code?&lt;/h2&gt;
  &lt;p id=&quot;lr1c&quot;&gt;&lt;strong&gt;IaC&lt;/strong&gt; — это практика управления инфраструктурой через код вместо ручной настройки. Вместо того чтобы настраивать сервера через веб-интерфейс или командную строку, вы описываете желаемое состояние инфраструктуры в текстовых файлах и применяете их автоматически.&lt;/p&gt;
  &lt;p id=&quot;X3nw&quot;&gt;По данным исследований 2025 года, компании, использующие IaC, развертывают инфраструктуру в &lt;strong&gt;10 раз быстрее&lt;/strong&gt; и имеют на &lt;strong&gt;50% меньше ошибок&lt;/strong&gt; конфигурации&lt;a href=&quot;https://habr.com/ru/companies/ru_mts/articles/908452/&quot; target=&quot;_blank&quot;&gt;1&lt;/a&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;iac&quot;&gt;🎯 Преимущества IaC&lt;/h2&gt;
  &lt;h2 id=&quot;rb5w&quot;&gt;Версионирование&lt;/h2&gt;
  &lt;p id=&quot;qVcw&quot;&gt;Инфраструктура хранится в Git с полной историей изменений. Можно откатиться к любой версии и отследить, кто что изменил.&lt;/p&gt;
  &lt;h2 id=&quot;G22T&quot;&gt;Воспроизводимость&lt;/h2&gt;
  &lt;p id=&quot;p7Dw&quot;&gt;Одинаковые конфигурации в разных средах (dev, staging, production). Исключается проблема &amp;quot;работает на моей машине&amp;quot;.&lt;/p&gt;
  &lt;h2 id=&quot;eUr8&quot;&gt;Автоматизация&lt;/h2&gt;
  &lt;p id=&quot;q6Bv&quot;&gt;Быстрое создание и удаление инфраструктуры. Новая среда разворачивается за минуты, а не дни.&lt;/p&gt;
  &lt;h2 id=&quot;7rzD&quot;&gt;Документация&lt;/h2&gt;
  &lt;p id=&quot;Bn9d&quot;&gt;Код служит живой документацией архитектуры. Всегда актуальное описание инфраструктуры.&lt;/p&gt;
  &lt;h2 id=&quot;LN2X&quot;&gt;Совместная работа&lt;/h2&gt;
  &lt;p id=&quot;PgGK&quot;&gt;Команда может вместе работать над инфраструктурой через pull requests и code review.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform---iac&quot;&gt;🔧 Terraform — лидер IaC&lt;/h2&gt;
  &lt;p id=&quot;Fn60&quot;&gt;&lt;strong&gt;Terraform&lt;/strong&gt; — инструмент от HashiCorp, который позволяет описывать инфраструктуру на декларативном языке HCL (HashiCorp Configuration Language). Он поддерживает сотни провайдеров: AWS, Azure, GCP, Kubernetes, Docker и многие другие.&lt;/p&gt;
  &lt;h2 id=&quot;qGfS&quot;&gt;Основные концепции Terraform&lt;/h2&gt;
  &lt;p id=&quot;TWEd&quot;&gt;&lt;strong&gt;Provider&lt;/strong&gt; — плагин для взаимодействия с API сервиса (AWS, Azure, etc.)&lt;br /&gt; &lt;strong&gt;Resource&lt;/strong&gt; — компонент инфраструктуры (сервер, база данных, сеть)&lt;br /&gt; &lt;strong&gt;Data Source&lt;/strong&gt; — информация о существующих ресурсах&lt;br /&gt; &lt;strong&gt;Variable&lt;/strong&gt; — входные параметры конфигурации&lt;br /&gt; &lt;strong&gt;Output&lt;/strong&gt; — выходные значения конфигурации&lt;br /&gt; &lt;strong&gt;State&lt;/strong&gt; — текущее состояние инфраструктуры&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform&quot;&gt;⚙️ Установка Terraform&lt;/h2&gt;
  &lt;pre id=&quot;C2Yk&quot; data-lang=&quot;bash&quot;&gt;# Загрузка и установка Terraform
wget https://releases.hashicorp.com/terraform/1.7.0/terraform_1.7.0_linux_amd64.zip
unzip terraform_1.7.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/

# Проверка установки
terraform version

# Включение автодополнения
terraform -install-autocomplete
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform&quot;&gt;🛠️ Первый проект на Terraform&lt;/h2&gt;
  &lt;h2 id=&quot;Zgpb&quot;&gt;Структура проекта&lt;/h2&gt;
  &lt;pre id=&quot;FLjX&quot;&gt;terraform-project/
├── main.tf          # Основная конфигурация
├── variables.tf     # Переменные
├── outputs.tf       # Выходные значения
├── terraform.tfvars # Значения переменных
└── providers.tf     # Провайдеры
&lt;/pre&gt;
  &lt;h2 id=&quot;Tp4y&quot;&gt;providers.tf&lt;/h2&gt;
  &lt;pre id=&quot;L4eF&quot;&gt;terraform {
  required_version = &amp;quot;&amp;gt;= 1.0&amp;quot;
  required_providers {
    aws = {
      source  = &amp;quot;hashicorp/aws&amp;quot;
      version = &amp;quot;~&amp;gt; 5.0&amp;quot;
    }
  }
}

provider &amp;quot;aws&amp;quot; {
  region = var.aws_region
}
&lt;/pre&gt;
  &lt;h2 id=&quot;wcwj&quot;&gt;variables.tf&lt;/h2&gt;
  &lt;pre id=&quot;k4kn&quot;&gt;variable &amp;quot;aws_region&amp;quot; {
  description = &amp;quot;AWS region&amp;quot;
  type        = string
  default     = &amp;quot;us-west-2&amp;quot;
}

variable &amp;quot;instance_type&amp;quot; {
  description = &amp;quot;EC2 instance type&amp;quot;
  type        = string
  default     = &amp;quot;t3.micro&amp;quot;
}

variable &amp;quot;environment&amp;quot; {
  description = &amp;quot;Environment name&amp;quot;
  type        = string
  validation {
    condition     = contains([&amp;quot;dev&amp;quot;, &amp;quot;staging&amp;quot;, &amp;quot;prod&amp;quot;], var.environment)
    error_message = &amp;quot;Environment must be dev, staging, or prod.&amp;quot;
  }
}

variable &amp;quot;project_name&amp;quot; {
  description = &amp;quot;Name of the project&amp;quot;
  type        = string
  default     = &amp;quot;devops-course&amp;quot;
}
&lt;/pre&gt;
  &lt;h2 id=&quot;2Fiz&quot;&gt;main.tf&lt;/h2&gt;
  &lt;pre id=&quot;5GAo&quot;&gt;# Data source для получения AMI
data &amp;quot;aws_ami&amp;quot; &amp;quot;ubuntu&amp;quot; {
  most_recent = true
  owners      = [&amp;quot;099720109477&amp;quot;] # Canonical

  filter {
    name   = &amp;quot;name&amp;quot;
    values = [&amp;quot;ubuntu/images/hvm-ssd/ubuntu-22.04-amd64-server-*&amp;quot;]
  }

  filter {
    name   = &amp;quot;virtualization-type&amp;quot;
    values = [&amp;quot;hvm&amp;quot;]
  }
}

# Security Group
resource &amp;quot;aws_security_group&amp;quot; &amp;quot;web_sg&amp;quot; {
  name_prefix = &amp;quot;${var.environment}-${var.project_name}-web-&amp;quot;
  description = &amp;quot;Security group for web servers&amp;quot;

  ingress {
    description = &amp;quot;HTTP&amp;quot;
    from_port   = 80
    to_port     = 80
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  ingress {
    description = &amp;quot;HTTPS&amp;quot;
    from_port   = 443
    to_port     = 443
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  ingress {
    description = &amp;quot;SSH&amp;quot;
    from_port   = 22
    to_port     = 22
    protocol    = &amp;quot;tcp&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = &amp;quot;-1&amp;quot;
    cidr_blocks = [&amp;quot;0.0.0.0/0&amp;quot;]
  }

  tags = {
    Name        = &amp;quot;${var.environment}-${var.project_name}-web-sg&amp;quot;
    Environment = var.environment
    Project     = var.project_name
  }
}

# EC2 Instance
resource &amp;quot;aws_instance&amp;quot; &amp;quot;web_server&amp;quot; {
  ami                    = data.aws_ami.ubuntu.id
  instance_type          = var.instance_type
  vpc_security_group_ids = [aws_security_group.web_sg.id]

  user_data = base64encode(templatefile(&amp;quot;${path.module}/user_data.sh&amp;quot;, {
    environment = var.environment
    project     = var.project_name
  }))

  tags = {
    Name        = &amp;quot;${var.environment}-${var.project_name}-web-server&amp;quot;
    Environment = var.environment
    Project     = var.project_name
  }
}

# Elastic IP
resource &amp;quot;aws_eip&amp;quot; &amp;quot;web_eip&amp;quot; {
  instance = aws_instance.web_server.id
  domain   = &amp;quot;vpc&amp;quot;

  tags = {
    Name        = &amp;quot;${var.environment}-${var.project_name}-eip&amp;quot;
    Environment = var.environment
  }
}
&lt;/pre&gt;
  &lt;h2 id=&quot;a6GF&quot;&gt;outputs.tf&lt;/h2&gt;
  &lt;pre id=&quot;rBgb&quot;&gt;output &amp;quot;instance_public_ip&amp;quot; {
  description = &amp;quot;Public IP address of the EC2 instance&amp;quot;
  value       = aws_eip.web_eip.public_ip
}

output &amp;quot;instance_public_dns&amp;quot; {
  description = &amp;quot;Public DNS name of the EC2 instance&amp;quot;
  value       = aws_instance.web_server.public_dns
}

output &amp;quot;security_group_id&amp;quot; {
  description = &amp;quot;ID of the security group&amp;quot;
  value       = aws_security_group.web_sg.id
}

output &amp;quot;ssh_command&amp;quot; {
  description = &amp;quot;SSH command to connect to the instance&amp;quot;
  value       = &amp;quot;ssh -i ~/.ssh/your-key.pem ubuntu@${aws_eip.web_eip.public_ip}&amp;quot;
}
&lt;/pre&gt;
  &lt;h2 id=&quot;mRER&quot;&gt;terraform.tfvars&lt;/h2&gt;
  &lt;pre id=&quot;tHdO&quot;&gt;aws_region    = &amp;quot;us-west-2&amp;quot;
instance_type = &amp;quot;t3.micro&amp;quot;
environment   = &amp;quot;dev&amp;quot;
project_name  = &amp;quot;devops-learning&amp;quot;
&lt;/pre&gt;
  &lt;h2 id=&quot;Nqhk&quot;&gt;user_data.sh&lt;/h2&gt;
  &lt;pre id=&quot;vd0F&quot; data-lang=&quot;bash&quot;&gt;#!/bin/bash
apt update
apt install -y nginx docker.io

# Настройка nginx
systemctl start nginx
systemctl enable nginx

# Создание простой страницы
cat &amp;gt; /var/www/html/index.html &amp;lt;&amp;lt; EOF
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;${project} - ${environment}&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to ${project}!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Environment: ${environment}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Server deployed with Terraform&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Timestamp: $(date)&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
EOF

# Настройка Docker
systemctl start docker
systemctl enable docker
usermod -aG docker ubuntu
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform&quot;&gt;🚀 Основные команды Terraform&lt;/h2&gt;
  &lt;pre id=&quot;9Max&quot; data-lang=&quot;bash&quot;&gt;# Инициализация проекта (загрузка провайдеров)
terraform init

# Форматирование кода
terraform fmt

# Валидация конфигурации
terraform validate

# Планирование изменений (dry-run)
terraform plan

# Планирование с сохранением в файл
terraform plan -out=tfplan

# Применение изменений
terraform apply

# Применение сохраненного плана
terraform apply tfplan

# Просмотр текущего состояния
terraform show

# Список ресурсов в state
terraform state list

# Подробная информация о ресурсе
terraform state show aws_instance.web_server

# Уничтожение инфраструктуры
terraform destroy

# Импорт существующего ресурса
terraform import aws_instance.web_server i-1234567890abcdef0
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;8s2O&quot;&gt;🛠️ Практические задания&lt;/h2&gt;
  &lt;h2 id=&quot;zdKB&quot;&gt;Задание 8.1: Создание базовой инфраструктуры&lt;/h2&gt;
  &lt;pre id=&quot;l5fp&quot; data-lang=&quot;bash&quot;&gt;# 1. Создание проекта
mkdir terraform-aws-demo
cd terraform-aws-demo

# 2. Настройка AWS CLI (если еще не настроен)
aws configure

# 3. Создание файлов конфигурации
# (используйте примеры выше)

# 4. Инициализация и применение
terraform init
terraform plan
terraform apply

# 5. Проверка результата
curl http://$(terraform output -raw instance_public_ip)
&lt;/pre&gt;
  &lt;h2 id=&quot;1tWx&quot;&gt;Задание 8.2: Модули Terraform&lt;/h2&gt;
  &lt;pre id=&quot;svsY&quot;&gt;# modules/vpc/main.tf
resource &amp;quot;aws_vpc&amp;quot; &amp;quot;main&amp;quot; {
  cidr_block           = var.cidr_block
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = var.vpc_name
  }
}

resource &amp;quot;aws_internet_gateway&amp;quot; &amp;quot;main&amp;quot; {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = &amp;quot;${var.vpc_name}-igw&amp;quot;
  }
}

resource &amp;quot;aws_subnet&amp;quot; &amp;quot;public&amp;quot; {
  count             = length(var.public_subnet_cidrs)
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_cidrs[count.index]
  availability_zone = var.availability_zones[count.index]

  map_public_ip_on_launch = true

  tags = {
    Name = &amp;quot;${var.vpc_name}-public-${count.index + 1}&amp;quot;
    Type = &amp;quot;public&amp;quot;
  }
}

resource &amp;quot;aws_route_table&amp;quot; &amp;quot;public&amp;quot; {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = &amp;quot;0.0.0.0/0&amp;quot;
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name = &amp;quot;${var.vpc_name}-public-rt&amp;quot;
  }
}

resource &amp;quot;aws_route_table_association&amp;quot; &amp;quot;public&amp;quot; {
  count          = length(aws_subnet.public)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}
&lt;/pre&gt;
  &lt;pre id=&quot;2HH2&quot;&gt;# modules/vpc/variables.tf
variable &amp;quot;vpc_name&amp;quot; {
  description = &amp;quot;Name of the VPC&amp;quot;
  type        = string
}

variable &amp;quot;cidr_block&amp;quot; {
  description = &amp;quot;CIDR block for VPC&amp;quot;
  type        = string
  default     = &amp;quot;10.0.0.0/16&amp;quot;
}

variable &amp;quot;public_subnet_cidrs&amp;quot; {
  description = &amp;quot;CIDR blocks for public subnets&amp;quot;
  type        = list(string)
  default     = [&amp;quot;10.0.1.0/24&amp;quot;, &amp;quot;10.0.2.0/24&amp;quot;]
}

variable &amp;quot;availability_zones&amp;quot; {
  description = &amp;quot;Availability zones&amp;quot;
  type        = list(string)
  default     = [&amp;quot;us-west-2a&amp;quot;, &amp;quot;us-west-2b&amp;quot;]
}
&lt;/pre&gt;
  &lt;pre id=&quot;mu67&quot;&gt;# modules/vpc/outputs.tf
output &amp;quot;vpc_id&amp;quot; {
  description = &amp;quot;ID of the VPC&amp;quot;
  value       = aws_vpc.main.id
}

output &amp;quot;public_subnet_ids&amp;quot; {
  description = &amp;quot;IDs of the public subnets&amp;quot;
  value       = aws_subnet.public[*].id
}

output &amp;quot;internet_gateway_id&amp;quot; {
  description = &amp;quot;ID of the Internet Gateway&amp;quot;
  value       = aws_internet_gateway.main.id
}
&lt;/pre&gt;
  &lt;h2 id=&quot;wC66&quot;&gt;Использование модуля&lt;/h2&gt;
  &lt;pre id=&quot;dJo4&quot;&gt;# main.tf
module &amp;quot;vpc&amp;quot; {
  source = &amp;quot;./modules/vpc&amp;quot;

  vpc_name             = &amp;quot;my-vpc&amp;quot;
  cidr_block           = &amp;quot;10.0.0.0/16&amp;quot;
  public_subnet_cidrs  = [&amp;quot;10.0.1.0/24&amp;quot;, &amp;quot;10.0.2.0/24&amp;quot;]
  availability_zones   = [&amp;quot;us-west-2a&amp;quot;, &amp;quot;us-west-2b&amp;quot;]
}

resource &amp;quot;aws_instance&amp;quot; &amp;quot;web&amp;quot; {
  ami           = data.aws_ami.ubuntu.id
  instance_type = &amp;quot;t3.micro&amp;quot;
  subnet_id     = module.vpc.public_subnet_ids[0]

  tags = {
    Name = &amp;quot;web-server-in-custom-vpc&amp;quot;
  }
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;ansible&quot;&gt;🔄 Ansible — управление конфигурациями&lt;/h2&gt;
  &lt;p id=&quot;71hr&quot;&gt;&lt;strong&gt;Ansible&lt;/strong&gt; — инструмент автоматизации для управления конфигурациями серверов. В отличие от Terraform, который создает инфраструктуру, Ansible настраивает программное обеспечение.&lt;/p&gt;
  &lt;h2 id=&quot;CJIK&quot;&gt;Установка Ansible&lt;/h2&gt;
  &lt;pre id=&quot;vwGz&quot; data-lang=&quot;bash&quot;&gt;# Ubuntu/Debian
sudo apt update
sudo apt install ansible

# Проверка установки
ansible --version
&lt;/pre&gt;
  &lt;h2 id=&quot;95cU&quot;&gt;Inventory файл&lt;/h2&gt;
  &lt;pre id=&quot;1zKH&quot;&gt;# inventory/hosts.yml
all:
  children:
    webservers:
      hosts:
        web1.example.com:
          ansible_host: 192.168.1.10
          ansible_user: ubuntu
        web2.example.com:
          ansible_host: 192.168.1.11
          ansible_user: ubuntu
    databases:
      hosts:
        db1.example.com:
          ansible_host: 192.168.1.20
          ansible_user: ubuntu
      vars:
        db_port: 5432
&lt;/pre&gt;
  &lt;h2 id=&quot;gJ8v&quot;&gt;Playbook для настройки веб-сервера&lt;/h2&gt;
  &lt;pre id=&quot;4BEJ&quot;&gt;# playbooks/webserver.yml
---
- name: Configure web servers
  hosts: webservers
  become: yes
  vars:
    nginx_port: 80
    app_name: &amp;quot;devops-demo&amp;quot;
    
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Install required packages
      apt:
        name:
          - nginx
          - docker.io
          - git
          - curl
        state: present

    - name: Start and enable nginx
      systemd:
        name: nginx
        state: started
        enabled: yes

    - name: Start and enable docker
      systemd:
        name: docker
        state: started
        enabled: yes

    - name: Add ubuntu user to docker group
      user:
        name: ubuntu
        groups: docker
        append: yes

    - name: Create application directory
      file:
        path: /opt/{{ app_name }}
        state: directory
        owner: ubuntu
        group: ubuntu
        mode: &amp;#x27;0755&amp;#x27;

    - name: Configure nginx
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/{{ app_name }}
      notify: restart nginx

    - name: Enable nginx site
      file:
        src: /etc/nginx/sites-available/{{ app_name }}
        dest: /etc/nginx/sites-enabled/{{ app_name }}
        state: link
      notify: restart nginx

    - name: Remove default nginx site
      file:
        path: /etc/nginx/sites-enabled/default
        state: absent
      notify: restart nginx

    - name: Open firewall for HTTP
      ufw:
        rule: allow
        port: &amp;quot;{{ nginx_port }}&amp;quot;

  handlers:
    - name: restart nginx
      systemd:
        name: nginx
        state: restarted
&lt;/pre&gt;
  &lt;h2 id=&quot;9Tir&quot;&gt;Шаблон Nginx&lt;/h2&gt;
  &lt;pre id=&quot;98Jx&quot;&gt;# templates/nginx.conf.j2
server {
    listen {{ nginx_port }};
    server_name {{ inventory_hostname }};

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /health {
        access_log off;
        return 200 &amp;quot;healthy\n&amp;quot;;
        add_header Content-Type text/plain;
    }
}
&lt;/pre&gt;
  &lt;h2 id=&quot;aPKp&quot;&gt;Запуск Ansible&lt;/h2&gt;
  &lt;pre id=&quot;1kTv&quot; data-lang=&quot;bash&quot;&gt;# Проверка подключения
ansible all -i inventory/hosts.yml -m ping

# Запуск playbook
ansible-playbook -i inventory/hosts.yml playbooks/webserver.yml

# Запуск с ограничением на группу хостов
ansible-playbook -i inventory/hosts.yml playbooks/webserver.yml --limit webservers

# Dry-run (проверка без изменений)
ansible-playbook -i inventory/hosts.yml playbooks/webserver.yml --check
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;terraform--ansible&quot;&gt;📊 Интеграция Terraform и Ansible&lt;/h2&gt;
  &lt;h2 id=&quot;AcRo&quot;&gt;Terraform с Ansible provisioner&lt;/h2&gt;
  &lt;pre id=&quot;bWKM&quot;&gt;resource &amp;quot;aws_instance&amp;quot; &amp;quot;web_server&amp;quot; {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type
  key_name      = aws_key_pair.deployer.key_name

  tags = {
    Name = &amp;quot;web-server&amp;quot;
  }

  provisioner &amp;quot;remote-exec&amp;quot; {
    inline = [
      &amp;quot;sudo apt update&amp;quot;,
      &amp;quot;sudo apt install -y python3&amp;quot;
    ]

    connection {
      type        = &amp;quot;ssh&amp;quot;
      user        = &amp;quot;ubuntu&amp;quot;
      private_key = file(&amp;quot;~/.ssh/id_rsa&amp;quot;)
      host        = self.public_ip
    }
  }

  provisioner &amp;quot;local-exec&amp;quot; {
    command = &amp;quot;ansible-playbook -i &amp;#x27;${self.public_ip},&amp;#x27; --private-key ~/.ssh/id_rsa playbooks/webserver.yml&amp;quot;
  }
}
&lt;/pre&gt;
  &lt;h2 id=&quot;l5PU&quot;&gt;Генерация Ansible inventory из Terraform&lt;/h2&gt;
  &lt;pre id=&quot;Krt9&quot;&gt;# outputs.tf
output &amp;quot;ansible_inventory&amp;quot; {
  value = templatefile(&amp;quot;${path.module}/inventory.tpl&amp;quot;, {
    webservers = aws_instance.web_servers[*].public_ip
    databases  = aws_instance.db_servers[*].private_ip
  })
}

resource &amp;quot;local_file&amp;quot; &amp;quot;ansible_inventory&amp;quot; {
  content  = templatefile(&amp;quot;${path.module}/inventory.tpl&amp;quot;, {
    webservers = aws_instance.web_servers[*].public_ip
    databases  = aws_instance.db_servers[*].private_ip
  })
  filename = &amp;quot;${path.module}/generated_inventory.yml&amp;quot;
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;aer6&quot;&gt;📖 Полезные ресурсы&lt;/h2&gt;
  &lt;ul id=&quot;3qjL&quot;&gt;
    &lt;li id=&quot;g9j4&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.hashicorp.com/terraform/docs&quot; target=&quot;_blank&quot;&gt;Terraform Documentation&lt;/a&gt;&lt;/strong&gt; — официальная документация&lt;/li&gt;
    &lt;li id=&quot;MzDi&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://registry.terraform.io/&quot; target=&quot;_blank&quot;&gt;Terraform Registry&lt;/a&gt;&lt;/strong&gt; — готовые модули и провайдеры&lt;/li&gt;
    &lt;li id=&quot;OVBb&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.ansible.com/ansible/latest/user_guide/&quot; target=&quot;_blank&quot;&gt;Ansible Documentation&lt;/a&gt;&lt;/strong&gt; — руководство по Ansible&lt;/li&gt;
    &lt;li id=&quot;BOm2&quot;&gt;&lt;strong&gt;YouTube:&lt;/strong&gt; &amp;quot;Terraform от А до Я&amp;quot; — практический курс по IaC&lt;a href=&quot;https://www.youtube.com/watch?v=2FsmJrorp9Q&quot; target=&quot;_blank&quot;&gt;8&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;Q3lM&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://spacelift.io/blog/terraform-infrastructure-as-code&quot; target=&quot;_blank&quot;&gt;Infrastructure as Code Guide&lt;/a&gt;&lt;/strong&gt; — подробное руководство&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;tyhv&quot;&gt;✅ Чек-лист модуля&lt;/h2&gt;
  &lt;ul id=&quot;Y8LZ&quot;&gt;
    &lt;li id=&quot;hujl&quot;&gt;Понимаю концепции Infrastructure as Code&lt;/li&gt;
    &lt;li id=&quot;saAQ&quot;&gt;Установил и настроил Terraform&lt;/li&gt;
    &lt;li id=&quot;e0tF&quot;&gt;Создал первую инфраструктуру с Terraform&lt;/li&gt;
    &lt;li id=&quot;Tz4U&quot;&gt;Освоил основные команды Terraform&lt;/li&gt;
    &lt;li id=&quot;znfR&quot;&gt;Работал с переменными и outputs&lt;/li&gt;
    &lt;li id=&quot;o3zW&quot;&gt;Создал и использовал Terraform модули&lt;/li&gt;
    &lt;li id=&quot;ZcAx&quot;&gt;Настроил удаленное хранение state&lt;/li&gt;
    &lt;li id=&quot;fwhQ&quot;&gt;Установил и изучил Ansible&lt;/li&gt;
    &lt;li id=&quot;JG52&quot;&gt;Создал Ansible playbook для настройки серверов&lt;/li&gt;
    &lt;li id=&quot;ujS9&quot;&gt;Интегрировал Terraform с Ansible&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h2 id=&quot;gOKv&quot;&gt;🚀 Что дальше?&lt;/h2&gt;
    &lt;p id=&quot;wLTS&quot;&gt;После освоения Infrastructure as Code переходите к &lt;strong&gt;Модулю 9: Мониторинг и наблюдаемость&lt;/strong&gt; для изучения систем мониторинга инфраструктуры и приложений.&lt;/p&gt;
  &lt;/section&gt;

</content></entry><entry><id>lalimi:rMI44ETMvtL</id><link rel="alternate" type="text/html" href="https://teletype.in/@lalimi/rMI44ETMvtL?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=lalimi"></link><title>Модуль 7: CI/CD — Непрерывная интеграция и развертывание</title><published>2025-06-11T10:58:13.169Z</published><updated>2025-06-11T10:58:13.169Z</updated><summary type="html">Курс DevOps для новичков 2025</summary><content type="html">
  &lt;p id=&quot;ocCh&quot;&gt;&lt;em&gt;Курс DevOps для новичков 2025&lt;/em&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;cicd&quot;&gt;🔄 Что такое CI/CD?&lt;/h2&gt;
  &lt;p id=&quot;JxDo&quot;&gt;&lt;strong&gt;CI/CD&lt;/strong&gt; — это набор практик, которые автоматизируют процесс доставки кода от разработчика до пользователя. Это позволяет выпускать изменения быстро, безопасно и с минимальным вмешательством человека.&lt;/p&gt;
  &lt;p id=&quot;nrk6&quot;&gt;&lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt; — автоматическая сборка, тестирование и интеграция изменений в основную ветку кода&lt;/p&gt;
  &lt;p id=&quot;Cr9i&quot;&gt;&lt;strong&gt;Continuous Delivery (CD)&lt;/strong&gt; — автоматическая подготовка изменений к развертыванию&lt;/p&gt;
  &lt;p id=&quot;sAcU&quot;&gt;&lt;strong&gt;Continuous Deployment (CD)&lt;/strong&gt; — автоматическое развертывание изменений в продакшн&lt;/p&gt;
  &lt;p id=&quot;ZwwV&quot;&gt;По данным DevOps Research and Assessment 2024, команды с зрелыми CI/CD практиками развертывают код в &lt;strong&gt;208 раз чаще&lt;/strong&gt; и восстанавливаются после сбоев в &lt;strong&gt;106 раз быстрее&lt;/strong&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;cicd&quot;&gt;🎯 Зачем нужен CI/CD?&lt;/h2&gt;
  &lt;h2 id=&quot;gAXd&quot;&gt;Проблемы традиционной разработки&lt;/h2&gt;
  &lt;ul id=&quot;47li&quot;&gt;
    &lt;li id=&quot;QsRC&quot;&gt;Долгие циклы релизов (месяцы)&lt;/li&gt;
    &lt;li id=&quot;2eCH&quot;&gt;Высокий риск ошибок при развертывании&lt;/li&gt;
    &lt;li id=&quot;Ku9n&quot;&gt;Сложности интеграции кода разных разработчиков&lt;/li&gt;
    &lt;li id=&quot;rVrt&quot;&gt;Ручные процессы тестирования и развертывания&lt;/li&gt;
    &lt;li id=&quot;Fvf3&quot;&gt;&amp;quot;Integration Hell&amp;quot; — проблемы при слиянии кода&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h2 id=&quot;pMBv&quot;&gt;Преимущества CI/CD&lt;/h2&gt;
  &lt;ul id=&quot;aXD8&quot;&gt;
    &lt;li id=&quot;k4sp&quot;&gt;&lt;strong&gt;Быстрая обратная связь&lt;/strong&gt; — ошибки обнаруживаются в течение минут&lt;/li&gt;
    &lt;li id=&quot;4i3R&quot;&gt;&lt;strong&gt;Снижение рисков&lt;/strong&gt; — маленькие изменения легче откатить&lt;/li&gt;
    &lt;li id=&quot;xfsv&quot;&gt;&lt;strong&gt;Повышение качества&lt;/strong&gt; — автоматические тесты на каждом этапе&lt;/li&gt;
    &lt;li id=&quot;49i3&quot;&gt;&lt;strong&gt;Ускорение доставки&lt;/strong&gt; — от идеи до пользователя за часы, а не месяцы&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;cicd&quot;&gt;🏗️ Архитектура CI/CD пайплайна&lt;/h2&gt;
  &lt;h2 id=&quot;6EGG&quot;&gt;Типичный пайплайн включает этапы:&lt;/h2&gt;
  &lt;pre id=&quot;8PbI&quot;&gt;1. Source        → Разработчик делает commit в Git
2. Build         → Автоматическая сборка приложения
3. Test          → Запуск автоматических тестов
4. Security Scan → Проверка на уязвимости
5. Package       → Создание артефактов (Docker образы)
6. Deploy Staging → Развертывание в тестовую среду
7. Integration Tests → Тестирование в реальной среде
8. Deploy Production → Развертывание в продакшн
9. Monitor       → Мониторинг работы приложения
&lt;/pre&gt;
  &lt;h2 id=&quot;HvZF&quot;&gt;Стратегии развертывания&lt;/h2&gt;
  &lt;p id=&quot;Zywm&quot;&gt;&lt;strong&gt;Blue-Green&lt;/strong&gt; — две идентичные среды, переключение между ними&lt;br /&gt; &lt;strong&gt;Canary&lt;/strong&gt; — постепенный перевод трафика на новую версию&lt;br /&gt; &lt;strong&gt;Rolling&lt;/strong&gt; — поэтапная замена экземпляров приложения&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;github-actions---cicd&quot;&gt;🚀 GitHub Actions — современный CI/CD&lt;/h2&gt;
  &lt;h2 id=&quot;vnsI&quot;&gt;Основные концепции&lt;/h2&gt;
  &lt;p id=&quot;DZXh&quot;&gt;&lt;strong&gt;Workflow&lt;/strong&gt; — автоматизированный процесс, описанный в YAML файле&lt;br /&gt; &lt;strong&gt;Job&lt;/strong&gt; — набор шагов, выполняющихся на одном runner&lt;br /&gt; &lt;strong&gt;Step&lt;/strong&gt; — отдельная задача (команда или action)&lt;br /&gt; &lt;strong&gt;Runner&lt;/strong&gt; — сервер, выполняющий workflows&lt;/p&gt;
  &lt;h2 id=&quot;4IuB&quot;&gt;Базовый workflow для Node.js&lt;/h2&gt;
  &lt;pre id=&quot;85hR&quot;&gt;# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  NODE_VERSION: &amp;#x27;18&amp;#x27;
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        node-version: [16.x, 18.x, 20.x]
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}
        cache: &amp;#x27;npm&amp;#x27;
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linter
      run: npm run lint
    
    - name: Run unit tests
      run: npm test -- --coverage
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage/lcov.info
    
    - name: Run security audit
      run: npm audit --audit-level moderate

  build-and-push:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == &amp;#x27;refs/heads/main&amp;#x27;
    
    outputs:
      image-digest: ${{ steps.build.outputs.digest }}
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Login to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=sha,prefix={{branch}}-
          type=raw,value=latest,enable={{is_default_branch}}
    
    - name: Build and push Docker image
      id: build
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max

  deploy-staging:
    needs: build-and-push
    runs-on: ubuntu-latest
    environment: staging
    
    steps:
    - name: Deploy to staging
      run: |
        echo &amp;quot;Deploying to staging environment...&amp;quot;
        echo &amp;quot;Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}&amp;quot;
        # Здесь команды для развертывания в staging

  integration-tests:
    needs: deploy-staging
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    
    - name: Run integration tests
      run: |
        echo &amp;quot;Running integration tests against staging...&amp;quot;
        # npm run test:integration

  deploy-production:
    needs: [build-and-push, integration-tests]
    runs-on: ubuntu-latest
    environment: production
    if: github.ref == &amp;#x27;refs/heads/main&amp;#x27;
    
    steps:
    - name: Deploy to production
      run: |
        echo &amp;quot;Deploying to production...&amp;quot;
        echo &amp;quot;Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}&amp;quot;
        # kubectl set image deployment/myapp myapp=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;IsEo&quot;&gt;🛠️ Практические задания&lt;/h2&gt;
  &lt;h2 id=&quot;vh9i&quot;&gt;Задание 7.1: Создание простого CI пайплайна&lt;/h2&gt;
  &lt;pre id=&quot;WEmp&quot; data-lang=&quot;bash&quot;&gt;# 1. Создание Node.js приложения
mkdir ci-cd-demo
cd ci-cd-demo
npm init -y

# 2. Установка зависимостей
npm install express
npm install --save-dev jest supertest eslint nodemon

# 3. Настройка package.json
cat &amp;gt; package.json &amp;lt;&amp;lt; &amp;#x27;EOF&amp;#x27;
{
  &amp;quot;name&amp;quot;: &amp;quot;ci-cd-demo&amp;quot;,
  &amp;quot;version&amp;quot;: &amp;quot;1.0.0&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;Demo app for CI/CD learning&amp;quot;,
  &amp;quot;main&amp;quot;: &amp;quot;app.js&amp;quot;,
  &amp;quot;scripts&amp;quot;: {
    &amp;quot;start&amp;quot;: &amp;quot;node app.js&amp;quot;,
    &amp;quot;dev&amp;quot;: &amp;quot;nodemon app.js&amp;quot;,
    &amp;quot;test&amp;quot;: &amp;quot;jest&amp;quot;,
    &amp;quot;test:watch&amp;quot;: &amp;quot;jest --watch&amp;quot;,
    &amp;quot;lint&amp;quot;: &amp;quot;eslint .&amp;quot;,
    &amp;quot;lint:fix&amp;quot;: &amp;quot;eslint . --fix&amp;quot;
  },
  &amp;quot;dependencies&amp;quot;: {
    &amp;quot;express&amp;quot;: &amp;quot;^4.18.2&amp;quot;
  },
  &amp;quot;devDependencies&amp;quot;: {
    &amp;quot;jest&amp;quot;: &amp;quot;^29.7.0&amp;quot;,
    &amp;quot;supertest&amp;quot;: &amp;quot;^6.3.3&amp;quot;,
    &amp;quot;eslint&amp;quot;: &amp;quot;^8.57.0&amp;quot;,
    &amp;quot;nodemon&amp;quot;: &amp;quot;^3.0.2&amp;quot;
  }
}
EOF
&lt;/pre&gt;
  &lt;h2 id=&quot;Hc6J&quot;&gt;Создание приложения&lt;/h2&gt;
  &lt;pre id=&quot;ic3B&quot; data-lang=&quot;javascript&quot;&gt;// app.js
const express = require(&amp;#x27;express&amp;#x27;);
const app = express();
const port = process.env.PORT || 3000;

app.use(express.json());

// Простая база данных в памяти
let users = [
  { id: 1, name: &amp;#x27;Alice&amp;#x27;, email: &amp;#x27;alice@example.com&amp;#x27; },
  { id: 2, name: &amp;#x27;Bob&amp;#x27;, email: &amp;#x27;bob@example.com&amp;#x27; }
];

app.get(&amp;#x27;/&amp;#x27;, (req, res) =&amp;gt; {
  res.json({ 
    message: &amp;#x27;Hello CI/CD!&amp;#x27;, 
    version: &amp;#x27;1.0.0&amp;#x27;,
    timestamp: new Date().toISOString()
  });
});

app.get(&amp;#x27;/health&amp;#x27;, (req, res) =&amp;gt; {
  res.json({ 
    status: &amp;#x27;OK&amp;#x27;, 
    uptime: process.uptime(),
    timestamp: new Date().toISOString()
  });
});

app.get(&amp;#x27;/users&amp;#x27;, (req, res) =&amp;gt; {
  res.json(users);
});

app.post(&amp;#x27;/users&amp;#x27;, (req, res) =&amp;gt; {
  const { name, email } = req.body;
  
  if (!name || !email) {
    return res.status(400).json({ error: &amp;#x27;Name and email are required&amp;#x27; });
  }
  
  const newUser = {
    id: users.length + 1,
    name,
    email
  };
  
  users.push(newUser);
  res.status(201).json(newUser);
});

if (require.main === module) {
  app.listen(port, () =&amp;gt; {
    console.log(&amp;#x60;Server running on port ${port}&amp;#x60;);
  });
}

module.exports = app;
&lt;/pre&gt;
  &lt;h2 id=&quot;uOI7&quot;&gt;Создание тестов&lt;/h2&gt;
  &lt;pre id=&quot;kjqL&quot; data-lang=&quot;javascript&quot;&gt;// app.test.js
const request = require(&amp;#x27;supertest&amp;#x27;);
const app = require(&amp;#x27;./app&amp;#x27;);

describe(&amp;#x27;App&amp;#x27;, () =&amp;gt; {
  test(&amp;#x27;GET / should return hello message&amp;#x27;, async () =&amp;gt; {
    const response = await request(app).get(&amp;#x27;/&amp;#x27;);
    expect(response.status).toBe(200);
    expect(response.body.message).toBe(&amp;#x27;Hello CI/CD!&amp;#x27;);
    expect(response.body.version).toBe(&amp;#x27;1.0.0&amp;#x27;);
  });

  test(&amp;#x27;GET /health should return OK status&amp;#x27;, async () =&amp;gt; {
    const response = await request(app).get(&amp;#x27;/health&amp;#x27;);
    expect(response.status).toBe(200);
    expect(response.body.status).toBe(&amp;#x27;OK&amp;#x27;);
    expect(response.body.uptime).toBeGreaterThanOrEqual(0);
  });

  test(&amp;#x27;GET /users should return users list&amp;#x27;, async () =&amp;gt; {
    const response = await request(app).get(&amp;#x27;/users&amp;#x27;);
    expect(response.status).toBe(200);
    expect(Array.isArray(response.body)).toBe(true);
    expect(response.body.length).toBeGreaterThan(0);
  });

  test(&amp;#x27;POST /users should create new user&amp;#x27;, async () =&amp;gt; {
    const newUser = {
      name: &amp;#x27;Charlie&amp;#x27;,
      email: &amp;#x27;charlie@example.com&amp;#x27;
    };

    const response = await request(app)
      .post(&amp;#x27;/users&amp;#x27;)
      .send(newUser);

    expect(response.status).toBe(201);
    expect(response.body.name).toBe(newUser.name);
    expect(response.body.email).toBe(newUser.email);
    expect(response.body.id).toBeDefined();
  });

  test(&amp;#x27;POST /users should return 400 for invalid data&amp;#x27;, async () =&amp;gt; {
    const response = await request(app)
      .post(&amp;#x27;/users&amp;#x27;)
      .send({ name: &amp;#x27;Test&amp;#x27; }); // missing email

    expect(response.status).toBe(400);
    expect(response.body.error).toBe(&amp;#x27;Name and email are required&amp;#x27;);
  });
});
&lt;/pre&gt;
  &lt;h2 id=&quot;CYHV&quot;&gt;Задание 7.2: Dockerfile для приложения&lt;/h2&gt;
  &lt;pre id=&quot;NFqg&quot;&gt;# Dockerfile
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine AS runtime

# Создание пользователя
RUN addgroup -g 1001 -S nodejs &amp;amp;&amp;amp; \
    adduser -S nextjs -u 1001

WORKDIR /app

# Копирование зависимостей
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=nextjs:nodejs . .

# Переключение на непривилегированного пользователя
USER nextjs

EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e &amp;quot;require(&amp;#x27;http&amp;#x27;).get(&amp;#x27;http://localhost:3000/health&amp;#x27;, (res) =&amp;gt; { process.exit(res.statusCode === 200 ? 0 : 1) })&amp;quot;

CMD [&amp;quot;npm&amp;quot;, &amp;quot;start&amp;quot;]
&lt;/pre&gt;
  &lt;h2 id=&quot;lL9A&quot;&gt;Задание 7.3: GitHub Actions workflow&lt;/h2&gt;
  &lt;pre id=&quot;3YRP&quot;&gt;# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: &amp;#x27;18&amp;#x27;
        cache: &amp;#x27;npm&amp;#x27;
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linter
      run: npm run lint
    
    - name: Run tests
      run: npm test
    
    - name: Security audit
      run: npm audit --audit-level moderate

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == &amp;#x27;push&amp;#x27;
    
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v3
    
    - name: Login to GitHub Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Build and push
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: |
          ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
          ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;jenkins---cicd&quot;&gt;🔧 Jenkins — классический CI/CD&lt;/h2&gt;
  &lt;h2 id=&quot;FEXb&quot;&gt;Установка Jenkins&lt;/h2&gt;
  &lt;pre id=&quot;8c2L&quot; data-lang=&quot;bash&quot;&gt;# Установка Java
sudo apt update
sudo apt install openjdk-11-jdk

# Добавление репозитория Jenkins
wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c &amp;#x27;echo deb http://pkg.jenkins.io/debian-stable binary/ &amp;gt; /etc/apt/sources.list.d/jenkins.list&amp;#x27;

# Установка Jenkins
sudo apt update
sudo apt install jenkins

# Запуск Jenkins
sudo systemctl start jenkins
sudo systemctl enable jenkins

# Получение первоначального пароля
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
&lt;/pre&gt;
  &lt;h2 id=&quot;VPf6&quot;&gt;Jenkinsfile пример&lt;/h2&gt;
  &lt;pre id=&quot;SkMy&quot; data-lang=&quot;groovy&quot;&gt;groovy
pipeline {
    agent any
    
    environment {
        DOCKER_IMAGE = &amp;quot;myapp&amp;quot;
        DOCKER_TAG = &amp;quot;${BUILD_NUMBER}&amp;quot;
        DOCKER_REGISTRY = &amp;quot;ghcr.io&amp;quot;
    }
    
    stages {
        stage(&amp;#x27;Checkout&amp;#x27;) {
            steps {
                checkout scm
            }
        }
        
        stage(&amp;#x27;Install Dependencies&amp;#x27;) {
            steps {
                sh &amp;#x27;npm install&amp;#x27;
            }
        }
        
        stage(&amp;#x27;Lint&amp;#x27;) {
            steps {
                sh &amp;#x27;npm run lint&amp;#x27;
            }
        }
        
        stage(&amp;#x27;Test&amp;#x27;) {
            steps {
                sh &amp;#x27;npm test&amp;#x27;
            }
            post {
                always {
                    publishTestResults testResultsPattern: &amp;#x27;test-results.xml&amp;#x27;
                }
            }
        }
        
        stage(&amp;#x27;Security Scan&amp;#x27;) {
            steps {
                sh &amp;#x27;npm audit&amp;#x27;
            }
        }
        
        stage(&amp;#x27;Build Docker Image&amp;#x27;) {
            steps {
                script {
                    def image = docker.build(&amp;quot;${DOCKER_IMAGE}:${DOCKER_TAG}&amp;quot;)
                    docker.withRegistry(&amp;quot;https://${DOCKER_REGISTRY}&amp;quot;, &amp;#x27;github-registry-credentials&amp;#x27;) {
                        image.push()
                        image.push(&amp;quot;latest&amp;quot;)
                    }
                }
            }
        }
        
        stage(&amp;#x27;Deploy to Staging&amp;#x27;) {
            steps {
                sh &amp;quot;&amp;quot;&amp;quot;
                    docker run -d --name staging-${BUILD_NUMBER} \
                    -p 3001:3000 \
                    ${DOCKER_IMAGE}:${DOCKER_TAG}
                &amp;quot;&amp;quot;&amp;quot;
            }
        }
        
        stage(&amp;#x27;Integration Tests&amp;#x27;) {
            steps {
                sh &amp;#x27;npm run test:integration&amp;#x27;
            }
        }
        
        stage(&amp;#x27;Deploy to Production&amp;#x27;) {
            when {
                branch &amp;#x27;main&amp;#x27;
            }
            steps {
                script {
                    input message: &amp;#x27;Deploy to production?&amp;#x27;, ok: &amp;#x27;Deploy&amp;#x27;
                }
                sh &amp;quot;&amp;quot;&amp;quot;
                    kubectl set image deployment/myapp-deployment \
                    myapp=${DOCKER_IMAGE}:${DOCKER_TAG}
                &amp;quot;&amp;quot;&amp;quot;
            }
        }
    }
    
    post {
        always {
            cleanWs()
        }
        success {
            slackSend channel: &amp;#x27;#deployments&amp;#x27;, 
                      message: &amp;quot;✅ Pipeline succeeded for ${env.JOB_NAME} #${env.BUILD_NUMBER}&amp;quot;
        }
        failure {
            slackSend channel: &amp;#x27;#deployments&amp;#x27;,
                      message: &amp;quot;❌ Pipeline failed for ${env.JOB_NAME} #${env.BUILD_NUMBER}&amp;quot;
        }
    }
}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;6woJ&quot;&gt;📊 Мониторинг пайплайнов&lt;/h2&gt;
  &lt;h2 id=&quot;jcyk&quot;&gt;Метрики CI/CD&lt;/h2&gt;
  &lt;p id=&quot;On2j&quot;&gt;&lt;strong&gt;Lead Time&lt;/strong&gt; — время от коммита до развертывания&lt;br /&gt; &lt;strong&gt;Deployment Frequency&lt;/strong&gt; — частота развертываний&lt;br /&gt; &lt;strong&gt;Mean Time to Recovery&lt;/strong&gt; — время восстановления после сбоя&lt;br /&gt; &lt;strong&gt;Change Failure Rate&lt;/strong&gt; — процент неудачных изменений&lt;/p&gt;
  &lt;h2 id=&quot;NHt8&quot;&gt;Уведомления и алерты&lt;/h2&gt;
  &lt;pre id=&quot;QgBG&quot;&gt;# Добавление в GitHub Actions
- name: Notify Slack on failure
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: failure
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}
    message: |
      ❌ Build failed!
      Repository: ${{ github.repository }}
      Branch: ${{ github.ref }}
      Commit: ${{ github.sha }}
&lt;/pre&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;qMCo&quot;&gt;📖 Полезные ресурсы&lt;/h2&gt;
  &lt;ul id=&quot;OJ0x&quot;&gt;
    &lt;li id=&quot;xxV1&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.github.com/en/actions&quot; target=&quot;_blank&quot;&gt;GitHub Actions Documentation&lt;/a&gt;&lt;/strong&gt; — официальная документация&lt;/li&gt;
    &lt;li id=&quot;1owC&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://www.jenkins.io/doc/book/&quot; target=&quot;_blank&quot;&gt;Jenkins Handbook&lt;/a&gt;&lt;/strong&gt; — полное руководство по Jenkins&lt;/li&gt;
    &lt;li id=&quot;iD4J&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://docs.gitlab.com/ee/ci/&quot; target=&quot;_blank&quot;&gt;GitLab CI/CD&lt;/a&gt;&lt;/strong&gt; — альтернативная платформа CI/CD&lt;/li&gt;
    &lt;li id=&quot;oWxk&quot;&gt;&lt;strong&gt;YouTube:&lt;/strong&gt; &amp;quot;CI/CD с нуля до продакшена&amp;quot; — практический курс&lt;/li&gt;
    &lt;li id=&quot;WAe5&quot;&gt;&lt;strong&gt;&lt;a href=&quot;https://itrevolution.com/the-devops-handbook/&quot; target=&quot;_blank&quot;&gt;The DevOps Handbook&lt;/a&gt;&lt;/strong&gt; — книга о DevOps практиках&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h2 id=&quot;EtDq&quot;&gt;✅ Чек-лист модуля&lt;/h2&gt;
  &lt;ul id=&quot;Qlbz&quot;&gt;
    &lt;li id=&quot;BRgI&quot;&gt;Понимаю концепции CI/CD и их преимущества&lt;/li&gt;
    &lt;li id=&quot;qPVF&quot;&gt;Создал простое приложение с тестами&lt;/li&gt;
    &lt;li id=&quot;4ZwK&quot;&gt;Настроил GitHub Actions workflow&lt;/li&gt;
    &lt;li id=&quot;AoE8&quot;&gt;Реализовал автоматическую сборку Docker образов&lt;/li&gt;
    &lt;li id=&quot;DYlP&quot;&gt;Настроил автоматическое развертывание&lt;/li&gt;
    &lt;li id=&quot;Hb8O&quot;&gt;Изучил стратегии развертывания (Blue-Green, Canary)&lt;/li&gt;
    &lt;li id=&quot;brN0&quot;&gt;Добавил проверки безопасности в пайплайн&lt;/li&gt;
    &lt;li id=&quot;We4n&quot;&gt;Настроил уведомления о статусе сборки&lt;/li&gt;
    &lt;li id=&quot;2sol&quot;&gt;Понимаю метрики эффективности CI/CD&lt;/li&gt;
    &lt;li id=&quot;GZOG&quot;&gt;Умею отлаживать проблемы в пайплайнах&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;section style=&quot;background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;h2 id=&quot;5rAV&quot;&gt;🚀 Что дальше?&lt;/h2&gt;
    &lt;p id=&quot;sdkN&quot;&gt;После освоения CI/CD переходите к &lt;strong&gt;Модулю 8: Infrastructure as Code&lt;/strong&gt; для изучения управления инфраструктурой через код и автоматизации развертывания сред.&lt;/p&gt;
  &lt;/section&gt;

</content></entry></feed>