From 46866051a9837ae9503ab3f8665d0317ce29e2dc Mon Sep 17 00:00:00 2001 From: dorley174 Date: Thu, 19 Feb 2026 22:59:36 +0300 Subject: [PATCH 1/2] feat: added terraform lab part --- .github/workflows/terraform-ci.yml | 57 +++ .gitignore | 4 +- app_python/docs/LAB04.md | 173 ++++++++ lab04_proofs/proof.png | Bin 0 -> 102687 bytes lab04_proofs/terraform_intalling_log.txt | 282 +++++++++++++ lab04_proofs/ubuntu_logs.txt | 488 ++++++++++++++++++++++ pulumi/.gitignore | 12 + pulumi/Pulumi.yaml | 6 + pulumi/README.md | 62 +++ pulumi/__main__.py | 145 +++++++ pulumi/requirements.txt | 2 + scripts/load-env.ps1 | 33 ++ terraform/.gitignore | 21 + terraform/.tflint.hcl | 6 + terraform/README.md | 56 +++ terraform/github/.gitignore | 7 + terraform/github/.tflint.hcl | 3 + terraform/github/main.tf | 11 + terraform/github/outputs.tf | 9 + terraform/github/providers.tf | 8 + terraform/github/terraform.tfvars.example | 14 + terraform/github/variables.tf | 30 ++ terraform/github/versions.tf | 10 + terraform/locals.tf | 15 + terraform/main.tf | 88 ++++ terraform/outputs.tf | 29 ++ terraform/providers.tf | 12 + terraform/terraform.tfvars.example | 40 ++ terraform/variables.tf | 133 ++++++ terraform/versions.tf | 12 + 30 files changed, 1767 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/terraform-ci.yml create mode 100644 app_python/docs/LAB04.md create mode 100644 lab04_proofs/proof.png create mode 100644 lab04_proofs/terraform_intalling_log.txt create mode 100644 lab04_proofs/ubuntu_logs.txt create mode 100644 pulumi/.gitignore create mode 100644 pulumi/Pulumi.yaml create mode 100644 pulumi/README.md create mode 100644 pulumi/__main__.py create mode 100644 pulumi/requirements.txt create mode 100644 scripts/load-env.ps1 create mode 100644 terraform/.gitignore create mode 100644 terraform/.tflint.hcl create mode 100644 terraform/README.md create mode 100644 terraform/github/.gitignore create mode 100644 terraform/github/.tflint.hcl create mode 100644 terraform/github/main.tf create mode 100644 terraform/github/outputs.tf create mode 100644 terraform/github/providers.tf create mode 100644 terraform/github/terraform.tfvars.example create mode 100644 terraform/github/variables.tf create mode 100644 terraform/github/versions.tf create mode 100644 terraform/locals.tf create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/providers.tf create mode 100644 terraform/terraform.tfvars.example create mode 100644 terraform/variables.tf create mode 100644 terraform/versions.tf diff --git a/.github/workflows/terraform-ci.yml b/.github/workflows/terraform-ci.yml new file mode 100644 index 0000000000..d6bc61d1a6 --- /dev/null +++ b/.github/workflows/terraform-ci.yml @@ -0,0 +1,57 @@ +name: Terraform CI + +on: + pull_request: + paths: + - "terraform/**" + - ".github/workflows/terraform-ci.yml" + push: + branches: + - master + - lab04 + paths: + - "terraform/**" + - ".github/workflows/terraform-ci.yml" + +jobs: + terraform-check: + name: "fmt / validate / tflint" + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + workdir: + - terraform + - terraform/github + + defaults: + run: + working-directory: ${{ matrix.workdir }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_wrapper: false + + - name: Terraform fmt + run: terraform fmt -check -recursive + + - name: Terraform init (no backend) + run: terraform init -backend=false + + - name: Terraform validate + run: terraform validate -no-color + + - name: Setup TFLint + uses: terraform-linters/setup-tflint@v3 + + - name: TFLint init + run: tflint --init + + - name: TFLint + run: tflint diff --git a/.gitignore b/.gitignore index 30d74d2584..d61b66f420 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -test \ No newline at end of file +test +.env +key.json \ No newline at end of file diff --git a/app_python/docs/LAB04.md b/app_python/docs/LAB04.md new file mode 100644 index 0000000000..c5df87c5b8 --- /dev/null +++ b/app_python/docs/LAB04.md @@ -0,0 +1,173 @@ +# LAB04 — Infrastructure as Code (Terraform + Pulumi) + +## 0) Почему Yandex Cloud (я из РФ) + +From Russia is better to work with **Yandex Cloud** (registry, billing, accessability). As a zone i use `ru-central1-a`. + +Alternatives: VK Cloud / Selectel + +--- + +## 1) Terraform + +### 1.1. hat to create + +- VPC Network +- Subnet +- Security Group с inbound rules: + - **22/tcp** (SSH) — using my IP (`allowed_ssh_cidr`) + - **80/tcp** — open out + - **5000/tcp** — open out +- VM (Compute Instance) with public IP (NAT) + +### 1.2. Repo structure + +``` +terraform/ + main.tf + providers.tf + variables.tf + locals.tf + outputs.tf + versions.tf + .gitignore + terraform.tfvars.example + .tflint.hcl +``` + +### 1.3. Prepare + +1) Download Terraform. +2) Download `yc` CLI. +3) Create an SSH key: + +```bash +ssh-keygen -t ed25519 -C "lab04" -f ~/.ssh/lab04_ed25519 +``` + +4) How to know my IP (example): + +```bash +curl ifconfig.me +``` + +### 1.4. Start + +```bash +cd terraform +cp terraform.tfvars.example terraform.tfvars +# filling terraform.tfvars + +terraform init +terraform fmt +terraform validate +terraform plan +terraform apply +``` + +**Output after apply** (вставьте сюда ваш вывод): + +- `terraform version` +- `terraform plan` output +- `terraform apply` output +- `public_ip` / `ssh_command` + +### 1.5. Access check + +```bash +ssh -i ~/.ssh/lab04_ed25519 ubuntu@ +``` + +### 1.6. Delete resourses + +```bash +terraform destroy +``` + +--- + +## 2) Pulumi + +### 2.1. What to create + +Same is in Terraform (Network/Subnet/SG/VM). + +### 2.2. Structure + +``` +pulumi/ + Pulumi.yaml + requirements.txt + __main__.py + README.md + .gitignore +``` + +### 2.3. Authorization YC + +Using env (`YC_TOKEN`, `YC_CLOUD_ID`, `YC_FOLDER_ID`, `YC_ZONE`) or using `pulumi config` keys `yandex:*`. + +### 2.4. Start + +```bash +cd pulumi +python -m venv venv +# Windows: +# .\venv\Scripts\activate +# Linux/macOS: +# source venv/bin/activate +pip install -r requirements.txt + +pulumi login +pulumi stack init dev + +# Provider config (пример): +pulumi config set yandex:cloudId +pulumi config set yandex:folderId +pulumi config set yandex:zone ru-central1-a +pulumi config set --secret yandex:token + +# Project config: +pulumi config set zone ru-central1-a +pulumi config set subnetCidr 10.10.0.0/24 +pulumi config set allowedSshCidr "<ваш_IP>/32" +pulumi config set sshUser ubuntu +pulumi config set sshPublicKeyPath "~/.ssh/lab04_ed25519.pub" + +pulumi preview +pulumi up +``` + +**Output after up**: + +- `pulumi version` +- `pulumi up` output +- `public_ip` / `ssh_command` + +### 2.5. Delete resourses + +```bash +pulumi destroy +``` + +--- + +## 3) Comparison Terraform vs Pulumi + +| Criteria | Terraform | Pulumi | +|---|---|---| +| Language | HCL | Python | +| Reusing | modules | full language abstraction | +| entry threshold | lower | upper (needed) | +| State | loval / remote backend | Pulumi Cloud / local | + +--- + +## Bonus 1 — Terraform CI (fmt/validate/tflint) + +There are workflow `.github/workflows/terraform-ci.yml`. + +log + +--- + diff --git a/lab04_proofs/proof.png b/lab04_proofs/proof.png new file mode 100644 index 0000000000000000000000000000000000000000..35724a8b2913dc5c443bcda4c68d927fa45c6efa GIT binary patch literal 102687 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 z zX~=D3vdOZ~5M=>RYe1Td--OqXB=U+EdZ&yFYg~-K<*ApxnyJvR(Ap93)5bM}lp86G z)?=}&9^9cn%f6yN6P|Y-UNOsQG`%ZBC=-am64lE{COG8!$ zW@WiTRf#y0$5Y3eAC;v#u}S}Wn-{5>+f0+gtbF*#m$>$i&%|GP>N}p~->92>=>1$m zJPWuB$LT(OXXfkoS;#2AxNJpWCEBX5B<%Ic{nZ5AK1^iywthCb-`* zceU}FY#=&q!GbWQFvPsa>%%snGag-(&M)InRItUtAj!;gRBbg6E-rfjjKuJoje}G! z5xVfI&iWBxF5rH2w;WMH!v|4v{h3AFsIa(QBfkPMf$=H~Z)uRqdn=qLIXv)gALg!( z&?t~R%mbyK3BL}tq*fNmz@IZv>L(ZA389=R;8jpw02Ci_s??8J&v%konU-tn6MP|$ z1(xMyw(}UQmJ_5~-J1Bda?ASLZegA$(4##10xhxsE{HAw>`*07r*6(jh@WU$YM`sH z@5uc7+4fyOuWPC(izJv|HA?1x?{`p3Ik(=QZThR@A4Vt7qCKIjles^SH@zynKKT7R z-y#$J6PM(}NcI$$%xe~war7*cawB$9G=hCdi59&F+B zu9RQGww^+H7Sek{VxD^m&=#_6{+vMG%LQw!XWkOoXK&!a6!O9dN+Pt&-CZ@O2V!NF zNvTOy8O~qfdTrO`+@CtuZ9~9vxg1j8jDl$cBpb5Q=5cRa-t4ge%Ns9Y%HktbAQG}< zIOOym292R2;3Va#1oEH}8A2yp1Bdksg2z;iyG;*IZUeX{w&&BQk(|~G|7^h<1-*2e z1=u&$&l{J*{KxYXiljsRiS#(HMTnAx*TMn%v4lblHuIP#E*DZ&4)xDH&+e+v>+;H( z;1_?okofb7@t}Yshn@9xLiZj$uqlhtIj4JSk@2he)w6voW;;vTRaYzK51z`Y6RRj5 zL4ALgo%uJM3?KU|ZT1RyvbI{`sff4y7=7bQD>wFYR@$|9EVO8s)%q@{HQC0~x`vr| z=N8QO&<_yqHI|-ve7HN!ecD{p;!SD6Wmr@5*dXgVxBaimpKYjy}v1|?*}IL>LyuCi(As9#2+^a92eH&K_MYC2eEpVA*%2$OHUTj&T43McDfXz zqD7Wh4m9!hIU4z~Mi=ln$F5j{0LQ>&EIxt#7J7$>=2?|h@ApbQ%`J15V-YzA$7`!j zd51S*3h##eH;|j0Jb@y3Jr&T4h722tkW?8$tcl7K6DN=cnZ?)}nTsrsLrVo7GejQ9 z?*I+cpkaa5ZZZAx1^&ox-p22Gq0DoA{fmYp%a7_CG1p@TLBiZ4SIUF;Y&Pp6az{>M znminCjQgdunFnk$Z-qE^3)F?ArS0frg{=<>Uj8!lZT9 zsu{1HKHFFJ1jOu7Jg&<7umT}jzS?!8SLJThiS+M+h?#T8Lx|!ya^cd z`5g-cY46ZlFB+1p_wf_-Ub=uTwu .\scripts\load-env.ps1 +Loaded .env OK +YC_CLOUD_ID=b1gca960emnn9qqikne9 +YC_FOLDER_ID=b1g82kdcn5grlmu79ano +YC_ZONE=ru-central1-a +YC_SERVICE_ACCOUNT_KEY_FILE=C:\DevOps\DevOps-Core-Course\key.json +PS C:\DevOps\DevOps-Core-Course> terraform -chdir=terraform apply +data.yandex_compute_image.os: Reading... +data.yandex_compute_image.os: Read complete after 1s [id=fd8lt661chfo5i13a40d] + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated +with the following symbols: + + create + +Terraform will perform the following actions: + + # yandex_compute_instance.vm will be created + + resource "yandex_compute_instance" "vm" { + + allow_stopping_for_update = true + + created_at = (known after apply) + + folder_id = (known after apply) + + fqdn = (known after apply) + + gpu_cluster_id = (known after apply) + + hardware_generation = (known after apply) + + hostname = (known after apply) + + id = (known after apply) + + labels = { + + "project" = "lab04" + } + + maintenance_grace_period = (known after apply) + + maintenance_policy = (known after apply) + + metadata = { + + "ssh-keys" = "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + } + + name = "lab04-vm" + + network_acceleration_type = "standard" + + platform_id = "standard-v2" + + status = (known after apply) + + zone = "ru-central1-a" + + + boot_disk { + + auto_delete = true + + device_name = (known after apply) + + disk_id = (known after apply) + + mode = (known after apply) + + + initialize_params { + + block_size = (known after apply) + + description = (known after apply) + + image_id = "fd8lt661chfo5i13a40d" + + name = (known after apply) + + size = 10 + + snapshot_id = (known after apply) + + type = "network-hdd" + } + } + + + metadata_options (known after apply) + + + network_interface { + + index = (known after apply) + + ip_address = (known after apply) + + ipv4 = true + + ipv6 = (known after apply) + + ipv6_address = (known after apply) + + mac_address = (known after apply) + + nat = true + + nat_ip_address = (known after apply) + + nat_ip_version = (known after apply) + + security_group_ids = (known after apply) + + subnet_id = (known after apply) + } + + + placement_policy (known after apply) + + + resources { + + core_fraction = 20 + + cores = 2 + + memory = 1 + } + + + scheduling_policy { + + preemptible = false + } + } + + # yandex_vpc_network.lab_net will be created + + resource "yandex_vpc_network" "lab_net" { + + created_at = (known after apply) + + default_security_group_id = (known after apply) + + folder_id = (known after apply) + + id = (known after apply) + + labels = { + + "project" = "lab04" + } + + name = "lab04-net" + + subnet_ids = (known after apply) + } + + # yandex_vpc_security_group.vm_sg will be created + + resource "yandex_vpc_security_group" "vm_sg" { + + created_at = (known after apply) + + description = "Security Group for Lab04 VM" + + folder_id = (known after apply) + + id = (known after apply) + + labels = { + + "project" = "lab04" + } + + name = "lab04-sg" + + network_id = (known after apply) + + status = (known after apply) + + + egress { + + description = "Allow all outbound" + + from_port = 0 + + id = (known after apply) + + labels = (known after apply) + + port = -1 + + protocol = "ANY" + + to_port = 65535 + + v4_cidr_blocks = [ + + "0.0.0.0/0", + ] + + v6_cidr_blocks = [] + # (2 unchanged attributes hidden) + } + + + ingress { + + description = "App port (Flask)" + + from_port = -1 + + id = (known after apply) + + labels = (known after apply) + + port = 5000 + + protocol = "TCP" + + to_port = -1 + + v4_cidr_blocks = [ + + "0.0.0.0/0", + ] + + v6_cidr_blocks = [] + # (2 unchanged attributes hidden) + } + + ingress { + + description = "HTTP" + + from_port = -1 + + id = (known after apply) + + labels = (known after apply) + + port = 80 + + protocol = "TCP" + + to_port = -1 + + v4_cidr_blocks = [ + + "0.0.0.0/0", + ] + + v6_cidr_blocks = [] + # (2 unchanged attributes hidden) + } + + ingress { + + description = "SSH from allowed CIDR" + + from_port = -1 + + id = (known after apply) + + labels = (known after apply) + + port = 22 + + protocol = "TCP" + + to_port = -1 + + v4_cidr_blocks = [ + + "95.111.204.70/32", + ] + + v6_cidr_blocks = [] + # (2 unchanged attributes hidden) + } + } + + # yandex_vpc_subnet.lab_subnet will be created + + resource "yandex_vpc_subnet" "lab_subnet" { + + created_at = (known after apply) + + folder_id = (known after apply) + + id = (known after apply) + + labels = { + + "project" = "lab04" + } + + name = "lab04-subnet" + + network_id = (known after apply) + + v4_cidr_blocks = [ + + "10.10.0.0/24", + ] + + v6_cidr_blocks = (known after apply) + + zone = "ru-central1-a" + } + +Plan: 4 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + app_url = (known after apply) + + http_url = (known after apply) + + internal_ip = (known after apply) + + public_ip = (known after apply) + + ssh_command = (known after apply) + + vm_id = (known after apply) +╷ +│ Warning: Cannot connect to YC tool initialization service. Network connectivity to the service is required for provider version control. +│ +│ +│ with provider["registry.terraform.io/yandex-cloud/yandex"], +│ on providers.tf line 1, in provider "yandex": +│ 1: provider "yandex" { +│ +╵ + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +yandex_vpc_network.lab_net: Creating... +yandex_vpc_network.lab_net: Creation complete after 4s [id=enpq59lnhclspku28afm] +yandex_vpc_subnet.lab_subnet: Creating... +yandex_vpc_security_group.vm_sg: Creating... +yandex_vpc_subnet.lab_subnet: Creation complete after 1s [id=e9bedb7ig70u3rpvqeru] +yandex_vpc_security_group.vm_sg: Creation complete after 3s [id=enp5bnpeefpntqlukehb] +yandex_compute_instance.vm: Creating... +yandex_compute_instance.vm: Still creating... [00m10s elapsed] +yandex_compute_instance.vm: Still creating... [00m20s elapsed] +yandex_compute_instance.vm: Still creating... [00m30s elapsed] +yandex_compute_instance.vm: Creation complete after 35s [id=fhmdplo02ifil4mk7odj] +╷ +│ Warning: Cannot connect to YC tool initialization service. Network connectivity to the service is required for provider version control. +│ +│ +│ with provider["registry.terraform.io/yandex-cloud/yandex"], +│ on providers.tf line 1, in provider "yandex": +│ 1: provider "yandex" { +│ +╵ + +Apply complete! Resources: 4 added, 0 changed, 0 destroyed. + +Outputs: + +app_url = "http://89.169.147.72:5000/" +http_url = "http://89.169.147.72/" +internal_ip = "10.10.0.22" +public_ip = "89.169.147.72" +ssh_command = "ssh -i ~/.ssh/id_ed25519 ubuntu@89.169.147.72" +vm_id = "fhmdplo02ifil4mk7odj" +PS C:\DevOps\DevOps-Core-Course> ssh -i $env:USERPROFILE\.ssh\lab04_ed25519 ubuntu@89.169.147.72 +The authenticity of host '89.169.147.72 (89.169.147.72)' can't be established. +ED25519 key fingerprint is SHA256:87OV4P2mx41pGWV3CIi0gSmPp8kE6JXzmB6sfnxBg2c. +This key is not known by any other names. +Are you sure you want to continue connecting (yes/no/[fingerprint])? yes +Warning: Permanently added '89.169.147.72' (ED25519) to the list of known hosts. +Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-100-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/pro + + System information as of Thu Feb 19 19:29:02 UTC 2026 + + System load: 0.2 Processes: 100 + Usage of /: 23.1% of 9.04GB Users logged in: 0 + Memory usage: 19% IPv4 address for eth0: 10.10.0.22 + Swap usage: 0% + + +Expanded Security Maintenance for Applications is not enabled. + +0 updates can be applied immediately. + +Enable ESM Apps to receive additional future security updates. +See https://ubuntu.com/esm or run: sudo pro status + + + +The programs included with the Ubuntu system are free software; +the exact distribution terms for each program are described in the +individual files in /usr/share/doc/*/copyright. + +Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by +applicable law. + +To run a command as administrator (user "root"), use "sudo ". +See "man sudo_root" for details. \ No newline at end of file diff --git a/lab04_proofs/ubuntu_logs.txt b/lab04_proofs/ubuntu_logs.txt new file mode 100644 index 0000000000..ca88584f03 --- /dev/null +++ b/lab04_proofs/ubuntu_logs.txt @@ -0,0 +1,488 @@ +ubuntu@fhmdplo02ifil4mk7odj:~$ sudo apt update +Hit:1 http://mirror.yandex.ru/ubuntu noble InRelease +Get:2 http://mirror.yandex.ru/ubuntu noble-updates InRelease [126 kB] +Get:3 http://mirror.yandex.ru/ubuntu noble-backports InRelease [126 kB] +Get:4 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB] +Get:5 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 Packages [1771 kB] +Get:6 http://mirror.yandex.ru/ubuntu noble-updates/main Translation-en [328 kB] +Get:7 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 Components [175 kB] +Get:8 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 c-n-f Metadata [16.5 kB] +Get:9 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 Packages [1557 kB] +Get:10 http://mirror.yandex.ru/ubuntu noble-updates/universe Translation-en [316 kB] +Get:11 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 Components [386 kB] +Get:12 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 c-n-f Metadata [32.6 kB] +Get:13 http://mirror.yandex.ru/ubuntu noble-updates/restricted amd64 Packages [2663 kB] +Get:14 http://mirror.yandex.ru/ubuntu noble-updates/restricted Translation-en [613 kB] +Get:15 http://mirror.yandex.ru/ubuntu noble-updates/restricted amd64 Components [212 B] +Get:16 http://mirror.yandex.ru/ubuntu noble-updates/multiverse Translation-en [7044 B] +Get:17 http://mirror.yandex.ru/ubuntu noble-updates/multiverse amd64 Components [940 B] +Get:18 http://mirror.yandex.ru/ubuntu noble-backports/main amd64 Components [7308 B] +Get:19 http://mirror.yandex.ru/ubuntu noble-backports/universe amd64 Components [10.5 kB] +Get:20 http://mirror.yandex.ru/ubuntu noble-backports/restricted amd64 Components [216 B] +Get:21 http://mirror.yandex.ru/ubuntu noble-backports/multiverse amd64 Components [212 B] +Get:22 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages [1474 kB] +Get:23 http://security.ubuntu.com/ubuntu noble-security/main Translation-en [237 kB] +Get:24 http://security.ubuntu.com/ubuntu noble-security/main amd64 Components [21.5 kB] +Get:25 http://security.ubuntu.com/ubuntu noble-security/main amd64 c-n-f Metadata [9892 B] +Get:26 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Packages [935 kB] +Get:27 http://security.ubuntu.com/ubuntu noble-security/universe Translation-en [214 kB] +Get:28 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Components [74.2 kB] +Get:29 http://security.ubuntu.com/ubuntu noble-security/universe amd64 c-n-f Metadata [20.0 kB] +Get:30 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Packages [2516 kB] +Get:31 http://security.ubuntu.com/ubuntu noble-security/restricted Translation-en [582 kB] +Get:32 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Components [212 B] +Get:33 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Components [212 B] +Fetched 14.3 MB in 3s (5184 kB/s) +Reading package lists... Done +Building dependency tree... Done +Reading state information... Done +8 packages can be upgraded. Run 'apt list --upgradable' to see them. +ubuntu@fhmdplo02ifil4mk7odj:~$ sudo apt install -y python3-venv python3-pip +Reading package lists... Done +Building dependency tree... Done +Reading state information... Done +The following additional packages will be installed: + binutils binutils-common binutils-x86-64-linux-gnu build-essential bzip2 cpp cpp-13 cpp-13-x86-64-linux-gnu + cpp-x86-64-linux-gnu dpkg-dev fakeroot g++ g++-13 g++-13-x86-64-linux-gnu g++-x86-64-linux-gnu gcc gcc-13 + gcc-13-base gcc-13-x86-64-linux-gnu gcc-14-base gcc-x86-64-linux-gnu javascript-common libalgorithm-diff-perl + libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan8 libatomic1 libbinutils libcc1-0 libctf-nobfd0 + libctf0 libdpkg-perl libexpat1 libexpat1-dev libfakeroot libfile-fcntllock-perl libgcc-13-dev libgcc-s1 + libgomp1 libgprofng0 libhwasan0 libisl23 libitm1 libjs-jquery libjs-sphinxdoc libjs-underscore liblsan0 libmpc3 + libpython3-dev libpython3.12-dev libquadmath0 libsframe1 libstdc++-13-dev libstdc++6 libtsan2 libubsan1 + lto-disabled-list make python3-dev python3-pip-whl python3-setuptools-whl python3-wheel python3.12-dev + python3.12-venv zlib1g-dev +Suggested packages: + binutils-doc gprofng-gui bzip2-doc cpp-doc gcc-13-locales cpp-13-doc debian-keyring g++-multilib + g++-13-multilib gcc-13-doc gcc-multilib autoconf automake libtool flex bison gdb gcc-doc gcc-13-multilib + gdb-x86-64-linux-gnu apache2 | lighttpd | httpd bzr libstdc++-13-doc make-doc +The following NEW packages will be installed: + binutils binutils-common binutils-x86-64-linux-gnu build-essential bzip2 cpp cpp-13 cpp-13-x86-64-linux-gnu + cpp-x86-64-linux-gnu dpkg-dev fakeroot g++ g++-13 g++-13-x86-64-linux-gnu g++-x86-64-linux-gnu gcc gcc-13 + gcc-13-base gcc-13-x86-64-linux-gnu gcc-x86-64-linux-gnu javascript-common libalgorithm-diff-perl + libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan8 libatomic1 libbinutils libcc1-0 libctf-nobfd0 + libctf0 libdpkg-perl libexpat1-dev libfakeroot libfile-fcntllock-perl libgcc-13-dev libgomp1 libgprofng0 + libhwasan0 libisl23 libitm1 libjs-jquery libjs-sphinxdoc libjs-underscore liblsan0 libmpc3 libpython3-dev + libpython3.12-dev libquadmath0 libsframe1 libstdc++-13-dev libtsan2 libubsan1 lto-disabled-list make + python3-dev python3-pip python3-pip-whl python3-setuptools-whl python3-venv python3-wheel python3.12-dev + python3.12-venv zlib1g-dev +The following packages will be upgraded: + gcc-14-base libexpat1 libgcc-s1 libstdc++6 +4 upgraded, 63 newly installed, 0 to remove and 4 not upgraded. +Need to get 79.5 MB of archives. +After this operation, 272 MB of additional disk space will be used. +Get:1 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 gcc-14-base amd64 14.2.0-4ubuntu2~24.04.1 [51.0 kB] +Get:2 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libstdc++6 amd64 14.2.0-4ubuntu2~24.04.1 [792 kB] +Get:3 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libgcc-s1 amd64 14.2.0-4ubuntu2~24.04.1 [78.4 kB] +Get:4 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libexpat1 amd64 2.6.1-2ubuntu0.4 [88.2 kB] +Get:5 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 binutils-common amd64 2.42-4ubuntu2.8 [240 kB] +Get:6 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libsframe1 amd64 2.42-4ubuntu2.8 [15.6 kB] +Get:7 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libbinutils amd64 2.42-4ubuntu2.8 [576 kB] +Get:8 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libctf-nobfd0 amd64 2.42-4ubuntu2.8 [97.9 kB] +Get:9 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libctf0 amd64 2.42-4ubuntu2.8 [94.5 kB] +Get:10 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libgprofng0 amd64 2.42-4ubuntu2.8 [849 kB] +Get:11 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 binutils-x86-64-linux-gnu amd64 2.42-4ubuntu2.8 [2463 kB] +Get:12 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 binutils amd64 2.42-4ubuntu2.8 [18.1 kB] +Get:13 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 gcc-13-base amd64 13.3.0-6ubuntu2~24.04.1 [51.6 kB] +Get:14 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libisl23 amd64 0.26-3build1.1 [680 kB] +Get:15 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libmpc3 amd64 1.3.1-1build1.1 [54.6 kB] +Get:16 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 cpp-13-x86-64-linux-gnu amd64 13.3.0-6ubuntu2~24.04.1 [10.7 MB] +Get:17 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 cpp-13 amd64 13.3.0-6ubuntu2~24.04.1 [1042 B] +Get:18 http://mirror.yandex.ru/ubuntu noble/main amd64 cpp-x86-64-linux-gnu amd64 4:13.2.0-7ubuntu1 [5326 B] +Get:19 http://mirror.yandex.ru/ubuntu noble/main amd64 cpp amd64 4:13.2.0-7ubuntu1 [22.4 kB] +Get:20 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libcc1-0 amd64 14.2.0-4ubuntu2~24.04.1 [48.0 kB] +Get:21 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libgomp1 amd64 14.2.0-4ubuntu2~24.04.1 [148 kB] +Get:22 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libitm1 amd64 14.2.0-4ubuntu2~24.04.1 [29.7 kB] +Get:23 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libatomic1 amd64 14.2.0-4ubuntu2~24.04.1 [10.5 kB] +Get:24 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libasan8 amd64 14.2.0-4ubuntu2~24.04.1 [3027 kB] +Get:25 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 liblsan0 amd64 14.2.0-4ubuntu2~24.04.1 [1322 kB] +Get:26 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libtsan2 amd64 14.2.0-4ubuntu2~24.04.1 [2772 kB] +Get:27 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libubsan1 amd64 14.2.0-4ubuntu2~24.04.1 [1184 kB] +Get:28 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libhwasan0 amd64 14.2.0-4ubuntu2~24.04.1 [1641 kB] +Get:29 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libquadmath0 amd64 14.2.0-4ubuntu2~24.04.1 [153 kB] +Get:30 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libgcc-13-dev amd64 13.3.0-6ubuntu2~24.04.1 [2681 kB] +Get:31 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 gcc-13-x86-64-linux-gnu amd64 13.3.0-6ubuntu2~24.04.1 [21.1 MB] +Get:32 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 gcc-13 amd64 13.3.0-6ubuntu2~24.04.1 [494 kB] +Get:33 http://mirror.yandex.ru/ubuntu noble/main amd64 gcc-x86-64-linux-gnu amd64 4:13.2.0-7ubuntu1 [1212 B] +Get:34 http://mirror.yandex.ru/ubuntu noble/main amd64 gcc amd64 4:13.2.0-7ubuntu1 [5018 B] +Get:35 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libstdc++-13-dev amd64 13.3.0-6ubuntu2~24.04.1 [2420 kB] +Get:36 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 g++-13-x86-64-linux-gnu amd64 13.3.0-6ubuntu2~24.04.1 [12.2 MB] +Get:37 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 g++-13 amd64 13.3.0-6ubuntu2~24.04.1 [16.0 kB] +Get:38 http://mirror.yandex.ru/ubuntu noble/main amd64 g++-x86-64-linux-gnu amd64 4:13.2.0-7ubuntu1 [964 B] +Get:39 http://mirror.yandex.ru/ubuntu noble/main amd64 g++ amd64 4:13.2.0-7ubuntu1 [1100 B] +Get:40 http://mirror.yandex.ru/ubuntu noble/main amd64 make amd64 4.3-4.1build2 [180 kB] +Get:41 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libdpkg-perl all 1.22.6ubuntu6.5 [269 kB] +Get:42 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 bzip2 amd64 1.0.8-5.1build0.1 [34.5 kB] +Get:43 http://mirror.yandex.ru/ubuntu noble/main amd64 lto-disabled-list all 47 [12.4 kB] +Get:44 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 dpkg-dev all 1.22.6ubuntu6.5 [1074 kB] +Get:45 http://mirror.yandex.ru/ubuntu noble/main amd64 build-essential amd64 12.10ubuntu1 [4928 B] +Get:46 http://mirror.yandex.ru/ubuntu noble/main amd64 libfakeroot amd64 1.33-1 [32.4 kB] +Get:47 http://mirror.yandex.ru/ubuntu noble/main amd64 fakeroot amd64 1.33-1 [67.2 kB] +Get:48 http://mirror.yandex.ru/ubuntu noble/main amd64 javascript-common all 11+nmu1 [5936 B] +Get:49 http://mirror.yandex.ru/ubuntu noble/main amd64 libalgorithm-diff-perl all 1.201-1 [41.8 kB] +Get:50 http://mirror.yandex.ru/ubuntu noble/main amd64 libalgorithm-diff-xs-perl amd64 0.04-8build3 [11.2 kB] +Get:51 http://mirror.yandex.ru/ubuntu noble/main amd64 libalgorithm-merge-perl all 0.08-5 [11.4 kB] +Get:52 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libexpat1-dev amd64 2.6.1-2ubuntu0.4 [140 kB] +Get:53 http://mirror.yandex.ru/ubuntu noble/main amd64 libfile-fcntllock-perl amd64 0.22-4ubuntu5 [30.7 kB] +Get:54 http://mirror.yandex.ru/ubuntu noble/main amd64 libjs-jquery all 3.6.1+dfsg+~3.5.14-1 [328 kB] +Get:55 http://mirror.yandex.ru/ubuntu noble/main amd64 libjs-underscore all 1.13.4~dfsg+~1.11.4-3 [118 kB] +Get:56 http://mirror.yandex.ru/ubuntu noble/main amd64 libjs-sphinxdoc all 7.2.6-6 [149 kB] +Get:57 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 zlib1g-dev amd64 1:1.3.dfsg-3.1ubuntu2.1 [894 kB] +Get:58 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libpython3.12-dev amd64 3.12.3-1ubuntu0.11 [5683 kB] +Get:59 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 libpython3-dev amd64 3.12.3-0ubuntu2.1 [10.3 kB] +Get:60 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 python3.12-dev amd64 3.12.3-1ubuntu0.11 [498 kB] +Get:61 http://mirror.yandex.ru/ubuntu noble-updates/main amd64 python3-dev amd64 3.12.3-0ubuntu2.1 [26.7 kB] +Get:62 http://mirror.yandex.ru/ubuntu noble/universe amd64 python3-wheel all 0.42.0-2 [53.1 kB] +Get:63 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 python3-pip all 24.0+dfsg-1ubuntu1.3 [1320 kB] +Get:64 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 python3-pip-whl all 24.0+dfsg-1ubuntu1.3 [1707 kB] +Get:65 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 python3-setuptools-whl all 68.1.2-2ubuntu1.2 [716 kB] +Get:66 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 python3.12-venv amd64 3.12.3-1ubuntu0.11 [5680 B] +Get:67 http://mirror.yandex.ru/ubuntu noble-updates/universe amd64 python3-venv amd64 3.12.3-0ubuntu2.1 [1032 B] +Fetched 79.5 MB in 1s (68.1 MB/s) +Extracting templates from packages: 100% +(Reading database ... 106316 files and directories currently installed.) +Preparing to unpack .../gcc-14-base_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking gcc-14-base:amd64 (14.2.0-4ubuntu2~24.04.1) over (14.2.0-4ubuntu2~24.04) ... +Setting up gcc-14-base:amd64 (14.2.0-4ubuntu2~24.04.1) ... +(Reading database ... 106316 files and directories currently installed.) +Preparing to unpack .../libstdc++6_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libstdc++6:amd64 (14.2.0-4ubuntu2~24.04.1) over (14.2.0-4ubuntu2~24.04) ... +Setting up libstdc++6:amd64 (14.2.0-4ubuntu2~24.04.1) ... +(Reading database ... 106316 files and directories currently installed.) +Preparing to unpack .../libgcc-s1_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libgcc-s1:amd64 (14.2.0-4ubuntu2~24.04.1) over (14.2.0-4ubuntu2~24.04) ... +Setting up libgcc-s1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +(Reading database ... 106316 files and directories currently installed.) +Preparing to unpack .../00-libexpat1_2.6.1-2ubuntu0.4_amd64.deb ... +Unpacking libexpat1:amd64 (2.6.1-2ubuntu0.4) over (2.6.1-2ubuntu0.3) ... +Selecting previously unselected package binutils-common:amd64. +Preparing to unpack .../01-binutils-common_2.42-4ubuntu2.8_amd64.deb ... +Unpacking binutils-common:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package libsframe1:amd64. +Preparing to unpack .../02-libsframe1_2.42-4ubuntu2.8_amd64.deb ... +Unpacking libsframe1:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package libbinutils:amd64. +Preparing to unpack .../03-libbinutils_2.42-4ubuntu2.8_amd64.deb ... +Unpacking libbinutils:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package libctf-nobfd0:amd64. +Preparing to unpack .../04-libctf-nobfd0_2.42-4ubuntu2.8_amd64.deb ... +Unpacking libctf-nobfd0:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package libctf0:amd64. +Preparing to unpack .../05-libctf0_2.42-4ubuntu2.8_amd64.deb ... +Unpacking libctf0:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package libgprofng0:amd64. +Preparing to unpack .../06-libgprofng0_2.42-4ubuntu2.8_amd64.deb ... +Unpacking libgprofng0:amd64 (2.42-4ubuntu2.8) ... +Selecting previously unselected package binutils-x86-64-linux-gnu. +Preparing to unpack .../07-binutils-x86-64-linux-gnu_2.42-4ubuntu2.8_amd64.deb ... +Unpacking binutils-x86-64-linux-gnu (2.42-4ubuntu2.8) ... +Selecting previously unselected package binutils. +Preparing to unpack .../08-binutils_2.42-4ubuntu2.8_amd64.deb ... +Unpacking binutils (2.42-4ubuntu2.8) ... +Selecting previously unselected package gcc-13-base:amd64. +Preparing to unpack .../09-gcc-13-base_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking gcc-13-base:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package libisl23:amd64. +Preparing to unpack .../10-libisl23_0.26-3build1.1_amd64.deb ... +Unpacking libisl23:amd64 (0.26-3build1.1) ... +Selecting previously unselected package libmpc3:amd64. +Preparing to unpack .../11-libmpc3_1.3.1-1build1.1_amd64.deb ... +Unpacking libmpc3:amd64 (1.3.1-1build1.1) ... +Selecting previously unselected package cpp-13-x86-64-linux-gnu. +Preparing to unpack .../12-cpp-13-x86-64-linux-gnu_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking cpp-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package cpp-13. +Preparing to unpack .../13-cpp-13_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking cpp-13 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package cpp-x86-64-linux-gnu. +Preparing to unpack .../14-cpp-x86-64-linux-gnu_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking cpp-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package cpp. +Preparing to unpack .../15-cpp_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking cpp (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package libcc1-0:amd64. +Preparing to unpack .../16-libcc1-0_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libcc1-0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libgomp1:amd64. +Preparing to unpack .../17-libgomp1_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libgomp1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libitm1:amd64. +Preparing to unpack .../18-libitm1_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libitm1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libatomic1:amd64. +Preparing to unpack .../19-libatomic1_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libatomic1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libasan8:amd64. +Preparing to unpack .../20-libasan8_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libasan8:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package liblsan0:amd64. +Preparing to unpack .../21-liblsan0_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking liblsan0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libtsan2:amd64. +Preparing to unpack .../22-libtsan2_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libtsan2:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libubsan1:amd64. +Preparing to unpack .../23-libubsan1_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libubsan1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libhwasan0:amd64. +Preparing to unpack .../24-libhwasan0_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libhwasan0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libquadmath0:amd64. +Preparing to unpack .../25-libquadmath0_14.2.0-4ubuntu2~24.04.1_amd64.deb ... +Unpacking libquadmath0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Selecting previously unselected package libgcc-13-dev:amd64. +Preparing to unpack .../26-libgcc-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking libgcc-13-dev:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package gcc-13-x86-64-linux-gnu. +Preparing to unpack .../27-gcc-13-x86-64-linux-gnu_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking gcc-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package gcc-13. +Preparing to unpack .../28-gcc-13_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking gcc-13 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package gcc-x86-64-linux-gnu. +Preparing to unpack .../29-gcc-x86-64-linux-gnu_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking gcc-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package gcc. +Preparing to unpack .../30-gcc_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking gcc (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package libstdc++-13-dev:amd64. +Preparing to unpack .../31-libstdc++-13-dev_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking libstdc++-13-dev:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package g++-13-x86-64-linux-gnu. +Preparing to unpack .../32-g++-13-x86-64-linux-gnu_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking g++-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package g++-13. +Preparing to unpack .../33-g++-13_13.3.0-6ubuntu2~24.04.1_amd64.deb ... +Unpacking g++-13 (13.3.0-6ubuntu2~24.04.1) ... +Selecting previously unselected package g++-x86-64-linux-gnu. +Preparing to unpack .../34-g++-x86-64-linux-gnu_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking g++-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package g++. +Preparing to unpack .../35-g++_4%3a13.2.0-7ubuntu1_amd64.deb ... +Unpacking g++ (4:13.2.0-7ubuntu1) ... +Selecting previously unselected package make. +Preparing to unpack .../36-make_4.3-4.1build2_amd64.deb ... +Unpacking make (4.3-4.1build2) ... +Selecting previously unselected package libdpkg-perl. +Preparing to unpack .../37-libdpkg-perl_1.22.6ubuntu6.5_all.deb ... +Unpacking libdpkg-perl (1.22.6ubuntu6.5) ... +Selecting previously unselected package bzip2. +Preparing to unpack .../38-bzip2_1.0.8-5.1build0.1_amd64.deb ... +Unpacking bzip2 (1.0.8-5.1build0.1) ... +Selecting previously unselected package lto-disabled-list. +Preparing to unpack .../39-lto-disabled-list_47_all.deb ... +Unpacking lto-disabled-list (47) ... +Selecting previously unselected package dpkg-dev. +Preparing to unpack .../40-dpkg-dev_1.22.6ubuntu6.5_all.deb ... +Unpacking dpkg-dev (1.22.6ubuntu6.5) ... +Selecting previously unselected package build-essential. +Preparing to unpack .../41-build-essential_12.10ubuntu1_amd64.deb ... +Unpacking build-essential (12.10ubuntu1) ... +Selecting previously unselected package libfakeroot:amd64. +Preparing to unpack .../42-libfakeroot_1.33-1_amd64.deb ... +Unpacking libfakeroot:amd64 (1.33-1) ... +Selecting previously unselected package fakeroot. +Preparing to unpack .../43-fakeroot_1.33-1_amd64.deb ... +Unpacking fakeroot (1.33-1) ... +Selecting previously unselected package javascript-common. +Preparing to unpack .../44-javascript-common_11+nmu1_all.deb ... +Unpacking javascript-common (11+nmu1) ... +Selecting previously unselected package libalgorithm-diff-perl. +Preparing to unpack .../45-libalgorithm-diff-perl_1.201-1_all.deb ... +Unpacking libalgorithm-diff-perl (1.201-1) ... +Selecting previously unselected package libalgorithm-diff-xs-perl:amd64. +Preparing to unpack .../46-libalgorithm-diff-xs-perl_0.04-8build3_amd64.deb ... +Unpacking libalgorithm-diff-xs-perl:amd64 (0.04-8build3) ... +Selecting previously unselected package libalgorithm-merge-perl. +Preparing to unpack .../47-libalgorithm-merge-perl_0.08-5_all.deb ... +Unpacking libalgorithm-merge-perl (0.08-5) ... +Selecting previously unselected package libexpat1-dev:amd64. +Preparing to unpack .../48-libexpat1-dev_2.6.1-2ubuntu0.4_amd64.deb ... +Unpacking libexpat1-dev:amd64 (2.6.1-2ubuntu0.4) ... +Selecting previously unselected package libfile-fcntllock-perl. +Preparing to unpack .../49-libfile-fcntllock-perl_0.22-4ubuntu5_amd64.deb ... +Unpacking libfile-fcntllock-perl (0.22-4ubuntu5) ... +Selecting previously unselected package libjs-jquery. +Preparing to unpack .../50-libjs-jquery_3.6.1+dfsg+~3.5.14-1_all.deb ... +Unpacking libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... +Selecting previously unselected package libjs-underscore. +Preparing to unpack .../51-libjs-underscore_1.13.4~dfsg+~1.11.4-3_all.deb ... +Unpacking libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... +Selecting previously unselected package libjs-sphinxdoc. +Preparing to unpack .../52-libjs-sphinxdoc_7.2.6-6_all.deb ... +Unpacking libjs-sphinxdoc (7.2.6-6) ... +Selecting previously unselected package zlib1g-dev:amd64. +Preparing to unpack .../53-zlib1g-dev_1%3a1.3.dfsg-3.1ubuntu2.1_amd64.deb ... +Unpacking zlib1g-dev:amd64 (1:1.3.dfsg-3.1ubuntu2.1) ... +Selecting previously unselected package libpython3.12-dev:amd64. +Preparing to unpack .../54-libpython3.12-dev_3.12.3-1ubuntu0.11_amd64.deb ... +Unpacking libpython3.12-dev:amd64 (3.12.3-1ubuntu0.11) ... +Selecting previously unselected package libpython3-dev:amd64. +Preparing to unpack .../55-libpython3-dev_3.12.3-0ubuntu2.1_amd64.deb ... +Unpacking libpython3-dev:amd64 (3.12.3-0ubuntu2.1) ... +Selecting previously unselected package python3.12-dev. +Preparing to unpack .../56-python3.12-dev_3.12.3-1ubuntu0.11_amd64.deb ... +Unpacking python3.12-dev (3.12.3-1ubuntu0.11) ... +Selecting previously unselected package python3-dev. +Preparing to unpack .../57-python3-dev_3.12.3-0ubuntu2.1_amd64.deb ... +Unpacking python3-dev (3.12.3-0ubuntu2.1) ... +Selecting previously unselected package python3-wheel. +Preparing to unpack .../58-python3-wheel_0.42.0-2_all.deb ... +Unpacking python3-wheel (0.42.0-2) ... +Selecting previously unselected package python3-pip. +Preparing to unpack .../59-python3-pip_24.0+dfsg-1ubuntu1.3_all.deb ... +Unpacking python3-pip (24.0+dfsg-1ubuntu1.3) ... +Selecting previously unselected package python3-pip-whl. +Preparing to unpack .../60-python3-pip-whl_24.0+dfsg-1ubuntu1.3_all.deb ... +Unpacking python3-pip-whl (24.0+dfsg-1ubuntu1.3) ... +Selecting previously unselected package python3-setuptools-whl. +Preparing to unpack .../61-python3-setuptools-whl_68.1.2-2ubuntu1.2_all.deb ... +Unpacking python3-setuptools-whl (68.1.2-2ubuntu1.2) ... +Selecting previously unselected package python3.12-venv. +Preparing to unpack .../62-python3.12-venv_3.12.3-1ubuntu0.11_amd64.deb ... +Unpacking python3.12-venv (3.12.3-1ubuntu0.11) ... +Selecting previously unselected package python3-venv. +Preparing to unpack .../63-python3-venv_3.12.3-0ubuntu2.1_amd64.deb ... +Unpacking python3-venv (3.12.3-0ubuntu2.1) ... +Setting up libexpat1:amd64 (2.6.1-2ubuntu0.4) ... +Setting up javascript-common (11+nmu1) ... +Setting up python3-setuptools-whl (68.1.2-2ubuntu1.2) ... +Setting up lto-disabled-list (47) ... +Setting up libfile-fcntllock-perl (0.22-4ubuntu5) ... +Setting up python3-pip-whl (24.0+dfsg-1ubuntu1.3) ... +Setting up libalgorithm-diff-perl (1.201-1) ... +Setting up binutils-common:amd64 (2.42-4ubuntu2.8) ... +Setting up libctf-nobfd0:amd64 (2.42-4ubuntu2.8) ... +Setting up libgomp1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up bzip2 (1.0.8-5.1build0.1) ... +Setting up python3-wheel (0.42.0-2) ... +Setting up libsframe1:amd64 (2.42-4ubuntu2.8) ... +Setting up libfakeroot:amd64 (1.33-1) ... +Setting up fakeroot (1.33-1) ... +update-alternatives: using /usr/bin/fakeroot-sysv to provide /usr/bin/fakeroot (fakeroot) in auto mode +Setting up gcc-13-base:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Setting up libexpat1-dev:amd64 (2.6.1-2ubuntu0.4) ... +Setting up make (4.3-4.1build2) ... +Setting up libquadmath0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libmpc3:amd64 (1.3.1-1build1.1) ... +Setting up libatomic1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up python3-pip (24.0+dfsg-1ubuntu1.3) ... +Setting up libdpkg-perl (1.22.6ubuntu6.5) ... +Setting up libubsan1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up zlib1g-dev:amd64 (1:1.3.dfsg-3.1ubuntu2.1) ... +Setting up libhwasan0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libasan8:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libtsan2:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libjs-jquery (3.6.1+dfsg+~3.5.14-1) ... +Setting up libbinutils:amd64 (2.42-4ubuntu2.8) ... +Setting up libisl23:amd64 (0.26-3build1.1) ... +Setting up libalgorithm-diff-xs-perl:amd64 (0.04-8build3) ... +Setting up libcc1-0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up liblsan0:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libitm1:amd64 (14.2.0-4ubuntu2~24.04.1) ... +Setting up libjs-underscore (1.13.4~dfsg+~1.11.4-3) ... +Setting up libalgorithm-merge-perl (0.08-5) ... +Setting up libctf0:amd64 (2.42-4ubuntu2.8) ... +Setting up python3.12-venv (3.12.3-1ubuntu0.11) ... +Setting up cpp-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Setting up libpython3.12-dev:amd64 (3.12.3-1ubuntu0.11) ... +Setting up libgprofng0:amd64 (2.42-4ubuntu2.8) ... +Setting up python3-venv (3.12.3-0ubuntu2.1) ... +Setting up python3.12-dev (3.12.3-1ubuntu0.11) ... +Setting up libjs-sphinxdoc (7.2.6-6) ... +Setting up libgcc-13-dev:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Setting up libstdc++-13-dev:amd64 (13.3.0-6ubuntu2~24.04.1) ... +Setting up binutils-x86-64-linux-gnu (2.42-4ubuntu2.8) ... +Setting up cpp-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Setting up libpython3-dev:amd64 (3.12.3-0ubuntu2.1) ... +Setting up cpp-13 (13.3.0-6ubuntu2~24.04.1) ... +Setting up gcc-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Setting up binutils (2.42-4ubuntu2.8) ... +Setting up dpkg-dev (1.22.6ubuntu6.5) ... +Setting up python3-dev (3.12.3-0ubuntu2.1) ... +Setting up gcc-13 (13.3.0-6ubuntu2~24.04.1) ... +Setting up cpp (4:13.2.0-7ubuntu1) ... +Setting up g++-13-x86-64-linux-gnu (13.3.0-6ubuntu2~24.04.1) ... +Setting up gcc-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Setting up gcc (4:13.2.0-7ubuntu1) ... +Setting up g++-x86-64-linux-gnu (4:13.2.0-7ubuntu1) ... +Setting up g++-13 (13.3.0-6ubuntu2~24.04.1) ... +Setting up g++ (4:13.2.0-7ubuntu1) ... +update-alternatives: using /usr/bin/g++ to provide /usr/bin/c++ (c++) in auto mode +Setting up build-essential (12.10ubuntu1) ... +Processing triggers for man-db (2.12.0-4build2) ... +Processing triggers for libc-bin (2.39-0ubuntu8.7) ... +Scanning processes... +Scanning candidates... +Scanning linux images... + +Running kernel seems to be up-to-date. + +Restarting services... + systemctl restart multipathd.service packagekit.service polkit.service + +Service restarts being deferred: + /etc/needrestart/restart.d/dbus.service + systemctl restart unattended-upgrades.service + +No containers need to be restarted. + +User sessions running outdated binaries: + ubuntu @ session #1: apt[1405] + +No VM guests are running outdated hypervisor (qemu) binaries on this host. +ubuntu@fhmdplo02ifil4mk7odj:~$ sudo apt install -y python3-venv python3-pip +Reading package lists... Done +Building dependency tree... Done +Reading state information... Done +python3-venv is already the newest version (3.12.3-0ubuntu2.1). +python3-pip is already the newest version (24.0+dfsg-1ubuntu1.3). +0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded. +ubuntu@fhmdplo02ifil4mk7odj:~$ mkdir -p ~/app && cd ~/app +ubuntu@fhmdplo02ifil4mk7odj:~/app$ cat > app.py <<'PY' +> from flask import Flask +> app = Flask(__name__) +> +> @app.get("/") +> def hello(): +> return "OK: lab04 VM is alive\n" +> PY +ubuntu@fhmdplo02ifil4mk7odj:~/app$ python3 -m venv venv +ubuntu@fhmdplo02ifil4mk7odj:~/app$ source venv/bin/activate +(venv) ubuntu@fhmdplo02ifil4mk7odj:~/app$ pip install flask +Collecting flask + Downloading flask-3.1.3-py3-none-any.whl.metadata (3.2 kB) +Collecting blinker>=1.9.0 (from flask) + Downloading blinker-1.9.0-py3-none-any.whl.metadata (1.6 kB) +Collecting click>=8.1.3 (from flask) + Downloading click-8.3.1-py3-none-any.whl.metadata (2.6 kB) +Collecting itsdangerous>=2.2.0 (from flask) + Downloading itsdangerous-2.2.0-py3-none-any.whl.metadata (1.9 kB) +Collecting jinja2>=3.1.2 (from flask) + Downloading jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB) +Collecting markupsafe>=2.1.1 (from flask) + Downloading markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.7 kB) +Collecting werkzeug>=3.1.0 (from flask) + Downloading werkzeug-3.1.6-py3-none-any.whl.metadata (4.0 kB) +Downloading flask-3.1.3-py3-none-any.whl (103 kB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 103.4/103.4 kB 1.8 MB/s eta 0:00:00 +Downloading blinker-1.9.0-py3-none-any.whl (8.5 kB) +Downloading click-8.3.1-py3-none-any.whl (108 kB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 108.3/108.3 kB 7.4 MB/s eta 0:00:00 +Downloading itsdangerous-2.2.0-py3-none-any.whl (16 kB) +Downloading jinja2-3.1.6-py3-none-any.whl (134 kB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 134.9/134.9 kB 8.5 MB/s eta 0:00:00 +Downloading markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (22 kB) +Downloading werkzeug-3.1.6-py3-none-any.whl (225 kB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 225.2/225.2 kB 11.1 MB/s eta 0:00:00 +Installing collected packages: markupsafe, itsdangerous, click, blinker, werkzeug, jinja2, flask +Successfully installed blinker-1.9.0 click-8.3.1 flask-3.1.3 itsdangerous-2.2.0 jinja2-3.1.6 markupsafe-3.0.3 werkzeug-3.1.6 +(venv) ubuntu@fhmdplo02ifil4mk7odj:~/app$ FLASK_APP=app.py flask run --host=0.0.0.0 --port=5000 + * Serving Flask app 'app.py' + * Debug mode: off +WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on all addresses (0.0.0.0) + * Running on http://127.0.0.1:5000 + * Running on http://10.10.0.22:5000 +Press CTRL+C to quit +95.111.204.70 - - [19/Feb/2026 19:33:15] "GET / HTTP/1.1" 200 - +95.111.204.70 - - [19/Feb/2026 19:33:17] "GET /favicon.ico HTTP/1.1" 404 - \ No newline at end of file diff --git a/pulumi/.gitignore b/pulumi/.gitignore new file mode 100644 index 0000000000..4aff6b34cb --- /dev/null +++ b/pulumi/.gitignore @@ -0,0 +1,12 @@ +# Python +__pycache__/ +*.py[cod] +.venv/ +venv/ + +# Pulumi state/config +Pulumi.*.yaml + +# IDE +.vscode/ +.idea/ diff --git a/pulumi/Pulumi.yaml b/pulumi/Pulumi.yaml new file mode 100644 index 0000000000..7e92a0ad45 --- /dev/null +++ b/pulumi/Pulumi.yaml @@ -0,0 +1,6 @@ +name: lab04-pulumi-yc +runtime: + name: python + options: + virtualenv: venv +description: Lab04 infrastructure in Yandex Cloud using Pulumi (Python) diff --git a/pulumi/README.md b/pulumi/README.md new file mode 100644 index 0000000000..92b74ed68e --- /dev/null +++ b/pulumi/README.md @@ -0,0 +1,62 @@ +# Lab04 — Pulumi (Yandex Cloud, Python) + +## Before + +1) Download Pulumi. +2) Download Python 3.10+. +3) Download project requirements: + +```bash +python -m venv venv +# Windows: +# .\venv\Scripts\activate +# macOS/Linux: +# source venv/bin/activate +pip install -r requirements.txt +``` + +## Auth using Yandex Cloud + +Pulumi provider Yandex uses same env/confic as Terrarform +Simplier + +- add env variables `YC_TOKEN`, `YC_CLOUD_ID`, `YC_FOLDER_ID`, `YC_ZONE` + +or (using pulumi config): + +```bash +pulumi config set yandex:cloudId +pulumi config set yandex:folderId +pulumi config set yandex:zone ru-central1-a +pulumi config set --secret yandex:token +``` + +## Project settings (my vaaariables) + +```bash +pulumi config set zone ru-central1-a +pulumi config set subnetCidr 10.10.0.0/24 +pulumi config set allowedSshCidr "<ваш_IP>/32" + +pulumi config set sshUser ubuntu +pulumi config set sshPublicKeyPath "~/.ssh/lab04_ed25519.pub" +# либо: +# pulumi config set sshPublicKey "ssh-ed25519 AAAA... lab04" + +pulumi config set imageFamily ubuntu-2404-lts +``` + +## Start + +```bash +pulumi preview +pulumi up +``` + +After `pulumi up` in output will be `public_ip` and `ssh_command`. + +## Delete resourses + +```bash +pulumi destroy +``` diff --git a/pulumi/__main__.py b/pulumi/__main__.py new file mode 100644 index 0000000000..d8ea114bf9 --- /dev/null +++ b/pulumi/__main__.py @@ -0,0 +1,145 @@ +import os + +import pulumi +import pulumi_yandex as yandex + +cfg = pulumi.Config() + +# ----------------- +# Config (project) +# ----------------- +zone = cfg.get("zone") or os.getenv("YC_ZONE") or "ru-central1-a" +subnet_cidr = cfg.get("subnetCidr") or "10.10.0.0/24" +allowed_ssh_cidr = cfg.get("allowedSshCidr") or "0.0.0.0/0" + +ssh_user = cfg.get("sshUser") or "ubuntu" +ssh_public_key = cfg.get("sshPublicKey") +ssh_public_key_path = cfg.get("sshPublicKeyPath") + +image_family = cfg.get("imageFamily") or "ubuntu-2404-lts" + +vm_cores = int(cfg.get("vmCores") or 2) +vm_memory_gb = int(cfg.get("vmMemoryGb") or 1) +vm_core_fraction = int(cfg.get("vmCoreFraction") or 20) + +disk_size_gb = int(cfg.get("diskSizeGb") or 10) +disk_type = cfg.get("diskType") or "network-hdd" + +platform_id = cfg.get("platformId") or "standard-v2" + +# SSH public key: either inline or from file +if not ssh_public_key: + if ssh_public_key_path: + path = os.path.expanduser(ssh_public_key_path) + with open(path, "r", encoding="utf-8") as f: + ssh_public_key = f.read().strip() + else: + raise Exception( + "Set sshPublicKey (inline) or sshPublicKeyPath (path to .pub) via pulumi config" + ) + +# ----------------- +# Data: image +# ----------------- +image = yandex.get_compute_image(family=image_family) + +# ----------------- +# Network +# ----------------- +net = yandex.VpcNetwork("lab04-net") + +subnet = yandex.VpcSubnet( + "lab04-subnet", + network_id=net.id, + zone=zone, + v4_cidr_blocks=[subnet_cidr], +) + +# ----------------- +# Security Group +# ----------------- +sg = yandex.VpcSecurityGroup( + "lab04-sg", + network_id=net.id, + ingress=[ + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="SSH", + v4_cidr_blocks=[allowed_ssh_cidr], + port=22, + ), + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="HTTP", + v4_cidr_blocks=["0.0.0.0/0"], + port=80, + ), + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="App 5000", + v4_cidr_blocks=["0.0.0.0/0"], + port=5000, + ), + ], + egress=[ + yandex.VpcSecurityGroupEgressArgs( + protocol="ANY", + description="Allow all outbound", + v4_cidr_blocks=["0.0.0.0/0"], + from_port=0, + to_port=65535, + ) + ], +) + +# ----------------- +# VM +# ----------------- +vm = yandex.ComputeInstance( + "lab04-vm", + zone=zone, + platform_id=platform_id, + resources=yandex.ComputeInstanceResourcesArgs( + cores=vm_cores, + memory=vm_memory_gb, + core_fraction=vm_core_fraction, + ), + boot_disk=yandex.ComputeInstanceBootDiskArgs( + initialize_params=yandex.ComputeInstanceBootDiskInitializeParamsArgs( + image_id=image.id, + size=disk_size_gb, + type=disk_type, + ) + ), + network_interfaces=[ + yandex.ComputeInstanceNetworkInterfaceArgs( + subnet_id=subnet.id, + nat=True, + security_group_ids=[sg.id], + ) + ], + metadata={ + "ssh-keys": f"{ssh_user}:{ssh_public_key}", + }, + allow_stopping_for_update=True, +) + + +def _nat_ip(network_interfaces): + """Handle both dict-style and typed outputs.""" + ni0 = network_interfaces[0] + if isinstance(ni0, dict): + return ni0.get("nat_ip_address") + return getattr(ni0, "nat_ip_address", None) + + +public_ip = vm.network_interfaces.apply(_nat_ip) +internal_ip = vm.network_interfaces.apply( + lambda nis: nis[0].get("ip_address") if isinstance(nis[0], dict) else getattr(nis[0], "ip_address", None) +) + +pulumi.export("public_ip", public_ip) +pulumi.export("internal_ip", internal_ip) +pulumi.export("ssh_command", public_ip.apply(lambda ip: f"ssh -i ~/.ssh/lab04_ed25519 {ssh_user}@{ip}")) +pulumi.export("http_url", public_ip.apply(lambda ip: f"http://{ip}/")) +pulumi.export("app_url", public_ip.apply(lambda ip: f"http://{ip}:5000/")) diff --git a/pulumi/requirements.txt b/pulumi/requirements.txt new file mode 100644 index 0000000000..4fcd3c0981 --- /dev/null +++ b/pulumi/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4.0.0 +pulumi-yandex diff --git a/scripts/load-env.ps1 b/scripts/load-env.ps1 new file mode 100644 index 0000000000..498d804eea --- /dev/null +++ b/scripts/load-env.ps1 @@ -0,0 +1,33 @@ +$envFile = Join-Path (Get-Location) ".env" +if (!(Test-Path $envFile)) { + throw "Не найден .env в корне: $envFile" +} + +Get-Content $envFile | ForEach-Object { + $line = $_.Trim() + if ($line.Length -eq 0) { return } + if ($line.StartsWith("#")) { return } + + $parts = $line -split "=", 2 + if ($parts.Count -ne 2) { return } + + $name = $parts[0].Trim() + $value = $parts[1].Trim().Trim('"').Trim("'") + + # экспорт в текущее окружение + Set-Item -Path "Env:$name" -Value $value +} + +# привести YC_SERVICE_ACCOUNT_KEY_FILE к абсолютному пути, если он относительный +if ($env:YC_SERVICE_ACCOUNT_KEY_FILE -and !(Split-Path $env:YC_SERVICE_ACCOUNT_KEY_FILE -IsAbsolute)) { + $candidate = Join-Path (Get-Location) $env:YC_SERVICE_ACCOUNT_KEY_FILE + if (Test-Path $candidate) { + $env:YC_SERVICE_ACCOUNT_KEY_FILE = (Resolve-Path $candidate).Path + } +} + +Write-Host "Loaded .env OK" +Write-Host "YC_CLOUD_ID=$env:YC_CLOUD_ID" +Write-Host "YC_FOLDER_ID=$env:YC_FOLDER_ID" +Write-Host "YC_ZONE=$env:YC_ZONE" +Write-Host "YC_SERVICE_ACCOUNT_KEY_FILE=$env:YC_SERVICE_ACCOUNT_KEY_FILE" diff --git a/terraform/.gitignore b/terraform/.gitignore new file mode 100644 index 0000000000..2d2b98b02a --- /dev/null +++ b/terraform/.gitignore @@ -0,0 +1,21 @@ +# Terraform local state / cache +.terraform/ +*.tfstate +*.tfstate.* + +# Variables (не коммитим) +*.tfvars +terraform.tfvars + +# Crash logs +crash.log +crash.*.log + +# Override files +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Lock file (в реальных проектах часто коммитят, но в рамках лабы можно игнорировать) +.terraform.lock.hcl diff --git a/terraform/.tflint.hcl b/terraform/.tflint.hcl new file mode 100644 index 0000000000..6eb5862287 --- /dev/null +++ b/terraform/.tflint.hcl @@ -0,0 +1,6 @@ +plugin "terraform" { + enabled = true +} + +# Базовые правила tflint включаются по умолчанию. +# Провайдер-специфичные ruleset'ы можно подключать отдельно, но для лабы достаточно базового. diff --git a/terraform/README.md b/terraform/README.md new file mode 100644 index 0000000000..def80b4b55 --- /dev/null +++ b/terraform/README.md @@ -0,0 +1,56 @@ +# Lab04 — Terraform (Yandex Cloud) + +Target: up the VM or netwwork and security group using ports **22/80/5000**. + +## Before + +1) Download Terraform. +2) Download YC CLI и залогиньтесь. +3) Prepare SSH-ключ (ed25519 рекомендуется): + +```bash +ssh-keygen -t ed25519 -C "lab04" -f ~/.ssh/lab04_ed25519 +``` + +## Variables settings + +Copy exaample andd fill: + +```bash +cp terraform.tfvars.example terraform.tfvars +``` + +Check that: +- `allowed_ssh_cidr` is better to take in outter IP `/32`. +- SSH-key may transfer using `ssh_public_key` (as a string), лor `ssh_public_key_path`. + +### How to transfer creds of Yandex Cloud + +There are 2 ways: + +**A) Using env:** +- `YC_TOKEN` или `YC_SERVICE_ACCOUNT_KEY_FILE` +- `YC_CLOUD_ID` +- `YC_FOLDER_ID` + +**B) Using terraform.tfvars:** +- `cloud_id`, `folder_id` +- `service_account_key_file` or `yc_token` + +## Start + +```bash +terraform init +terraform fmt +terraform validate +terraform plan +terraform apply +``` + +After `apply` Terraform outputs `public_ip` и `ssh_command`. + +## Delete resourses + +```bash +terraform destroy +``` diff --git a/terraform/github/.gitignore b/terraform/github/.gitignore new file mode 100644 index 0000000000..6c721539e4 --- /dev/null +++ b/terraform/github/.gitignore @@ -0,0 +1,7 @@ +.terraform/ +*.tfstate +*.tfstate.* +*.tfvars +terraform.tfvars +crash.log +.terraform.lock.hcl diff --git a/terraform/github/.tflint.hcl b/terraform/github/.tflint.hcl new file mode 100644 index 0000000000..75d15f14aa --- /dev/null +++ b/terraform/github/.tflint.hcl @@ -0,0 +1,3 @@ +plugin "terraform" { + enabled = true +} diff --git a/terraform/github/main.tf b/terraform/github/main.tf new file mode 100644 index 0000000000..2709d7849d --- /dev/null +++ b/terraform/github/main.tf @@ -0,0 +1,11 @@ +resource "github_repository" "course_repo" { + name = var.repo_name + description = var.repo_description + visibility = var.visibility + + has_issues = true + has_projects = false + has_wiki = false + + # auto_init = true # включите, если хотите создать repo с пустым коммитом +} diff --git a/terraform/github/outputs.tf b/terraform/github/outputs.tf new file mode 100644 index 0000000000..81dffb5fb3 --- /dev/null +++ b/terraform/github/outputs.tf @@ -0,0 +1,9 @@ +output "repo_full_name" { + value = github_repository.course_repo.full_name + description = "owner/name" +} + +output "repo_url" { + value = github_repository.course_repo.html_url + description = "URL репозитория" +} diff --git a/terraform/github/providers.tf b/terraform/github/providers.tf new file mode 100644 index 0000000000..fa406ffc5e --- /dev/null +++ b/terraform/github/providers.tf @@ -0,0 +1,8 @@ +provider "github" { + # Можно передать token/owner через переменные, либо через env: + # GITHUB_TOKEN + # GITHUB_OWNER (не всегда поддерживается, обычно owner задают в provider block) + + token = var.github_token != "" ? var.github_token : null + owner = var.github_owner != "" ? var.github_owner : null +} diff --git a/terraform/github/terraform.tfvars.example b/terraform/github/terraform.tfvars.example new file mode 100644 index 0000000000..3557c3db2d --- /dev/null +++ b/terraform/github/terraform.tfvars.example @@ -0,0 +1,14 @@ +# Лучше хранить токен в env: +# export GITHUB_TOKEN=... +# или в PowerShell: +# $env:GITHUB_TOKEN="..." + +# Но если надо: +# github_token = "..." # НЕ КОММИТИТЬ + +# Если owner не задан, GitHub provider обычно берёт owner из токена. +# github_owner = "your-username-or-org" + +repo_name = "DevOps-Core-Course" +repo_description = "DevOps course repository managed by Terraform" +visibility = "public" diff --git a/terraform/github/variables.tf b/terraform/github/variables.tf new file mode 100644 index 0000000000..87b10b3062 --- /dev/null +++ b/terraform/github/variables.tf @@ -0,0 +1,30 @@ +variable "github_token" { + type = string + description = "GitHub Personal Access Token (PAT). Можно оставить пустым и задать через env GITHUB_TOKEN" + default = "" + sensitive = true +} + +variable "github_owner" { + type = string + description = "Владелец (username или org). Можно оставить пустым — owner будет взят из токена (если провайдер сможет)" + default = "" +} + +variable "repo_name" { + type = string + description = "Название репозитория (например DevOps-Core-Course)" + default = "DevOps-Core-Course" +} + +variable "repo_description" { + type = string + description = "Описание репозитория" + default = "DevOps course repository managed by Terraform" +} + +variable "visibility" { + type = string + description = "public/private/internal" + default = "public" +} diff --git a/terraform/github/versions.tf b/terraform/github/versions.tf new file mode 100644 index 0000000000..dd2ecc138e --- /dev/null +++ b/terraform/github/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.6.0" + + required_providers { + github = { + source = "integrations/github" + version = ">= 5.0.0" + } + } +} diff --git a/terraform/locals.tf b/terraform/locals.tf new file mode 100644 index 0000000000..3704986e2d --- /dev/null +++ b/terraform/locals.tf @@ -0,0 +1,15 @@ +locals { + # Можно задать ключ прямо строкой (ssh_public_key), а можно указать путь к файлу (ssh_public_key_path). + # try(...) нужен, чтобы terraform validate проходил даже без файла. + ssh_public_key_resolved = trimspace(coalesce( + (var.ssh_public_key != "" ? var.ssh_public_key : null), + try(file(var.ssh_public_key_path), null), + "" + )) + + instance_metadata = local.ssh_public_key_resolved != "" ? { + # Формат, который ожидает cloud-init в образах YC: "user:ssh_public_key" + # (см. офиц. примеры/доки) + "ssh-keys" = "${var.ssh_user}:${local.ssh_public_key_resolved}" + } : {} +} diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000000..b933dbe32d --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,88 @@ +data "yandex_compute_image" "os" { + family = var.image_family +} + +resource "yandex_vpc_network" "lab_net" { + name = "${var.project_name}-net" + labels = var.labels +} + +resource "yandex_vpc_subnet" "lab_subnet" { + name = "${var.project_name}-subnet" + zone = var.zone + network_id = yandex_vpc_network.lab_net.id + v4_cidr_blocks = [var.subnet_cidr] + labels = var.labels +} + +resource "yandex_vpc_security_group" "vm_sg" { + name = "${var.project_name}-sg" + description = "Security Group for Lab04 VM" + network_id = yandex_vpc_network.lab_net.id + + ingress { + description = "SSH from allowed CIDR" + protocol = "TCP" + v4_cidr_blocks = [var.allowed_ssh_cidr] + port = 22 + } + + ingress { + description = "HTTP" + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 80 + } + + ingress { + description = "App port (Flask)" + protocol = "TCP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 5000 + } + + egress { + description = "Allow all outbound" + protocol = "ANY" + v4_cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 65535 + } + + labels = var.labels +} + +resource "yandex_compute_instance" "vm" { + name = "${var.project_name}-vm" + platform_id = var.platform_id + zone = var.zone + + resources { + cores = var.vm_cores + memory = var.vm_memory_gb + core_fraction = var.vm_core_fraction + } + + scheduling_policy { + preemptible = var.preemptible + } + + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.os.id + size = var.disk_size_gb + type = var.disk_type + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.lab_subnet.id + nat = true + security_group_ids = [yandex_vpc_security_group.vm_sg.id] + } + + metadata = local.instance_metadata + + allow_stopping_for_update = true + labels = var.labels +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000000..1be16233f7 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,29 @@ +output "vm_id" { + value = yandex_compute_instance.vm.id + description = "ID виртуальной машины" +} + +output "internal_ip" { + value = yandex_compute_instance.vm.network_interface[0].ip_address + description = "Внутренний IP (в подсети)" +} + +output "public_ip" { + value = yandex_compute_instance.vm.network_interface[0].nat_ip_address + description = "Публичный IP (NAT)" +} + +output "ssh_command" { + description = "Команда для подключения по SSH (подставьте путь к приватному ключу)" + value = "ssh -i ~/.ssh/id_ed25519 ${var.ssh_user}@${yandex_compute_instance.vm.network_interface[0].nat_ip_address}" +} + +output "http_url" { + description = "URL для HTTP (если вы поставите веб-сервер на VM)" + value = "http://${yandex_compute_instance.vm.network_interface[0].nat_ip_address}/" +} + +output "app_url" { + description = "URL для приложения на 5000 порту (если вы его запустите)" + value = "http://${yandex_compute_instance.vm.network_interface[0].nat_ip_address}:5000/" +} diff --git a/terraform/providers.tf b/terraform/providers.tf new file mode 100644 index 0000000000..365effc630 --- /dev/null +++ b/terraform/providers.tf @@ -0,0 +1,12 @@ +provider "yandex" { + # Можно передавать через переменные (terraform.tfvars), а можно через env: + # YC_CLOUD_ID, YC_FOLDER_ID, YC_TOKEN / YC_SERVICE_ACCOUNT_KEY_FILE + # Если значения пустые, Terraform передаст null и провайдер попробует взять их из env. + + cloud_id = var.cloud_id != "" ? var.cloud_id : null + folder_id = var.folder_id != "" ? var.folder_id : null + zone = var.zone + + token = var.yc_token != "" ? var.yc_token : null + service_account_key_file = var.service_account_key_file != "" ? var.service_account_key_file : null +} diff --git a/terraform/terraform.tfvars.example b/terraform/terraform.tfvars.example new file mode 100644 index 0000000000..e766e30f61 --- /dev/null +++ b/terraform/terraform.tfvars.example @@ -0,0 +1,40 @@ +# --- YC identifiers --- +# Можно оставить пустым и задать через env YC_CLOUD_ID / YC_FOLDER_ID +cloud_id = "" +folder_id = "" + +# --- Zone / Network --- +zone = "ru-central1-a" +subnet_cidr = "10.10.0.0/24" + +# Разрешить SSH только с вашего IP (пример): +# allowed_ssh_cidr = "93.184.216.34/32" +allowed_ssh_cidr = "0.0.0.0/0" + +# --- Auth --- +# Рекомендуется: env YC_TOKEN / YC_SERVICE_ACCOUNT_KEY_FILE. +# yc_token = "..." +# service_account_key_file = "C:/Users//key.json" + +# --- SSH --- +ssh_user = "ubuntu" + +# ВАРИАНТ 1: вставить ключ строкой +# ssh_public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... lab04" + +# ВАРИАНТ 2: путь до .pub +ssh_public_key_path = "~/.ssh/lab04_ed25519.pub" + +# --- VM sizing --- +vm_cores = 2 +vm_memory_gb = 1 +vm_core_fraction = 20 + +preemptible = false +platform_id = "standard-v2" +disk_size_gb = 10 +disk_type = "network-hdd" + +# image_family может отличаться. Если data source не найдёт образ — +# уточните доступные семьи образов в YC. +image_family = "ubuntu-2404-lts" diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000000..49f75e7e93 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,133 @@ +variable "project_name" { + type = string + description = "Префикс/название для ресурсов Lab04" + default = "lab04" +} + +variable "labels" { + type = map(string) + description = "Лейблы Yandex Cloud (опционально)" + default = { + project = "lab04" + } +} + +# --- Yandex Cloud provider config --- + +variable "cloud_id" { + type = string + description = "YC cloud_id (можно оставить пустым и задать через env YC_CLOUD_ID)" + default = "" +} + +variable "folder_id" { + type = string + description = "YC folder_id (можно оставить пустым и задать через env YC_FOLDER_ID)" + default = "b1g82kdcn5grlmu79ano" +} + +variable "zone" { + type = string + description = "Зона доступности (например, ru-central1-a)" + default = "ru-central1-a" +} + +variable "yc_token" { + type = string + description = "OAuth/IAM токен (можно оставить пустым и задать через env YC_TOKEN)" + default = "" + sensitive = true +} + +variable "service_account_key_file" { + type = string + description = "Путь к JSON-ключу сервисного аккаунта (можно оставить пустым и задать через env YC_SERVICE_ACCOUNT_KEY_FILE)" + default = "" + sensitive = true +} + +# --- Network / Security --- + +variable "subnet_cidr" { + type = string + description = "CIDR подсети" + default = "10.10.0.0/24" +} + +variable "allowed_ssh_cidr" { + type = string + description = "CIDR, откуда разрешён SSH (желательно ваш белый IP /32)" + # Чтобы не заблокировать себя на первом запуске, оставляем дефолт открытым. + # В отчёте лучше указать ваш IP/32. + default = "0.0.0.0/0" +} + +# --- VM --- + +variable "image_family" { + type = string + description = "Семейство образа (data.yandex_compute_image.family)" + default = "ubuntu-2404-lts" +} + +variable "platform_id" { + type = string + description = "Платформа VM" + default = "standard-v2" +} + +variable "vm_cores" { + type = number + description = "vCPU" + default = 2 +} + +variable "vm_memory_gb" { + type = number + description = "RAM (GB)" + default = 1 +} + +variable "vm_core_fraction" { + type = number + description = "Доля CPU (5/20/50/100). 20 часто дешевле" + default = 20 +} + +variable "disk_size_gb" { + type = number + description = "Размер диска (GB)" + default = 10 +} + +variable "disk_type" { + type = string + description = "Тип диска (например network-hdd / network-ssd)" + default = "network-hdd" +} + +variable "preemptible" { + type = bool + description = "Преемптивная VM (дешевле, но может выключаться)" + default = false +} + +# --- SSH keys --- + +variable "ssh_user" { + type = string + description = "Пользователь в образе (для Ubuntu обычно ubuntu)" + default = "ubuntu" +} + +variable "ssh_public_key" { + type = string + description = "Содержимое публичного ключа (ssh-ed25519 AAAA... comment). Можно не задавать, если задаёте ssh_public_key_path" + default = "" +} + +variable "ssh_public_key_path" { + type = string + description = "Путь к публичному ключу (например ~/.ssh/id_ed25519.pub). Используется, если ssh_public_key пустой" + default = "" +} diff --git a/terraform/versions.tf b/terraform/versions.tf new file mode 100644 index 0000000000..b0f4ecb816 --- /dev/null +++ b/terraform/versions.tf @@ -0,0 +1,12 @@ +terraform { + required_version = ">= 1.6.0" + + required_providers { + yandex = { + source = "yandex-cloud/yandex" + # Не фиксируем точную версию, чтобы не ломаться при обновлениях. + # При желании можно зафиксировать (например, ">= 0.170.0"). + version = ">= 0.100.0" + } + } +} From 11d5b0b773f8bbb0c881c2e4b63cfd4028593bbc Mon Sep 17 00:00:00 2001 From: dorley174 Date: Thu, 19 Feb 2026 23:56:21 +0300 Subject: [PATCH 2/2] finished work with pulumi --- app_python/docs/LAB04.md | 2 +- lab04_proofs/pulumi_config_log.txt | 282 ++++++++++++ lab04_proofs/pulumi_result.txt | 0 .../{ubuntu_logs.txt => terraform_result.txt} | 0 .../dev/dev.1771534421400792500.json | 427 ++++++++++++++++++ .../dev/dev.1771534421400792500.json.attrs | 1 + .../dev-1771534421389384600.checkpoint.json | 427 ++++++++++++++++++ ...-1771534421389384600.checkpoint.json.attrs | 1 + .../dev/dev-1771534421389384600.history.json | 44 ++ ...dev-1771534421389384600.history.json.attrs | 1 + pulumi/.pulumi-state/.pulumi/meta.yaml | 1 + pulumi/.pulumi-state/.pulumi/meta.yaml.attrs | 1 + .../.pulumi/stacks/lab04-pulumi-yc/dev.json | 427 ++++++++++++++++++ .../stacks/lab04-pulumi-yc/dev.json.attrs | 1 + .../stacks/lab04-pulumi-yc/dev.json.bak | 420 +++++++++++++++++ .../stacks/lab04-pulumi-yc/dev.json.bak.attrs | 1 + pulumi/__main__.py | 5 +- 17 files changed, 2038 insertions(+), 3 deletions(-) create mode 100644 lab04_proofs/pulumi_config_log.txt create mode 100644 lab04_proofs/pulumi_result.txt rename lab04_proofs/{ubuntu_logs.txt => terraform_result.txt} (100%) create mode 100644 pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json create mode 100644 pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json.attrs create mode 100644 pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json create mode 100644 pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json.attrs create mode 100644 pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json create mode 100644 pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json.attrs create mode 100644 pulumi/.pulumi-state/.pulumi/meta.yaml create mode 100644 pulumi/.pulumi-state/.pulumi/meta.yaml.attrs create mode 100644 pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json create mode 100644 pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.attrs create mode 100644 pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak create mode 100644 pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak.attrs diff --git a/app_python/docs/LAB04.md b/app_python/docs/LAB04.md index c5df87c5b8..32c243bde7 100644 --- a/app_python/docs/LAB04.md +++ b/app_python/docs/LAB04.md @@ -167,7 +167,7 @@ pulumi destroy There are workflow `.github/workflows/terraform-ci.yml`. -log +all logs in lab04 folder --- diff --git a/lab04_proofs/pulumi_config_log.txt b/lab04_proofs/pulumi_config_log.txt new file mode 100644 index 0000000000..94e3e04dd9 --- /dev/null +++ b/lab04_proofs/pulumi_config_log.txt @@ -0,0 +1,282 @@ +PS C:\DevOps\DevOps-Core-Course> git add . +PS C:\DevOps\DevOps-Core-Course> git commit -m "feat: added terraform lab part" +[lab04 4686605] feat: added terraform lab part + 30 files changed, 1767 insertions(+), 1 deletion(-) + create mode 100644 .github/workflows/terraform-ci.yml + create mode 100644 app_python/docs/LAB04.md + create mode 100644 lab04_proofs/proof.png + create mode 100644 lab04_proofs/terraform_intalling_log.txt + create mode 100644 lab04_proofs/ubuntu_logs.txt + create mode 100644 pulumi/.gitignore + create mode 100644 pulumi/Pulumi.yaml + create mode 100644 pulumi/README.md + create mode 100644 pulumi/__main__.py + create mode 100644 pulumi/requirements.txt + create mode 100644 scripts/load-env.ps1 + create mode 100644 terraform/.gitignore + create mode 100644 terraform/.tflint.hcl + create mode 100644 terraform/README.md + create mode 100644 terraform/github/.gitignore + create mode 100644 terraform/github/.tflint.hcl + create mode 100644 terraform/github/main.tf + create mode 100644 terraform/github/outputs.tf + create mode 100644 terraform/github/providers.tf + create mode 100644 terraform/github/terraform.tfvars.example + create mode 100644 terraform/github/variables.tf + create mode 100644 terraform/github/versions.tf + create mode 100644 terraform/locals.tf + create mode 100644 terraform/main.tf + create mode 100644 terraform/outputs.tf + create mode 100644 terraform/providers.tf + create mode 100644 terraform/terraform.tfvars.example + create mode 100644 terraform/variables.tf + create mode 100644 terraform/versions.tf +PS C:\DevOps\DevOps-Core-Course> git push origin lab04 +Enumerating objects: 47, done. +Counting objects: 100% (47/47), done. +Delta compression using up to 20 threads +Compressing objects: 100% (36/36), done. +Writing objects: 100% (41/41), 113.24 KiB | 5.66 MiB/s, done. +Total 41 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0) +remote: Resolving deltas: 100% (2/2), completed with 2 local objects. +remote: +remote: Create a pull request for 'lab04' on GitHub by visiting: +remote: https://github.com/dorley174/DevOps-Core-Course/pull/new/lab04 +remote: +To https://github.com/dorley174/DevOps-Core-Course + * [new branch] lab04 -> lab04 +PS C:\DevOps\DevOps-Core-Course> .\scripts\load-env.ps1 +Loaded .env OK +YC_CLOUD_ID=b1gca960emnn9qqikne9 +YC_FOLDER_ID=b1g82kdcn5grlmu79ano +YC_ZONE=ru-central1-a +YC_SERVICE_ACCOUNT_KEY_FILE=C:\DevOps\DevOps-Core-Course\key.json +PS C:\DevOps\DevOps-Core-Course> winget install -e --id Pulumi.Pulumi +Найдено Pulumi [Pulumi.Pulumi] Версия 3.222.0 +Лицензия на это приложение предоставлена вам владельцем. +Корпорация Майкрософт не несет ответственность за сторонние пакеты и не предоставляет для них никакие лицензии. +Скачивание https://github.com/pulumi/pulumi-winget/releases/download/v3.222.0/pulumi-3.222.0-windows-x64.msi + ██████████████████████████████ 87.8 MB / 87.8 MB +Хэш установщика успешно проверен +Запуск установки пакета... +Успешно установлено +PS C:\DevOps\DevOps-Core-Course> pulumi version +pulumi : Имя "pulumi" не распознано как имя командлета, функции, файла сценария или выполняемой программы. Проверьте прави +льность написания имени, а также наличие и правильность пути, после чего повторите попытку. +строка:1 знак:1 ++ pulumi version ++ ~~~~~~ + + CategoryInfo : ObjectNotFound: (pulumi:String) [], CommandNotFoundException + + FullyQualifiedErrorId : CommandNotFoundException + +PS C:\DevOps\DevOps-Core-Course> + * Журнал восстановлен + + +PS C:\DevOps\DevOps-Core-Course> .\scripts\load-env.ps1 +Loaded .env OK +YC_CLOUD_ID=b1gca960emnn9qqikne9 +YC_FOLDER_ID=b1g82kdcn5grlmu79ano +YC_ZONE=ru-central1-a +YC_SERVICE_ACCOUNT_KEY_FILE=C:\DevOps\DevOps-Core-Course\key.json +PS C:\DevOps\DevOps-Core-Course> pulumi version +v3.222.0 +PS C:\DevOps\DevOps-Core-Course> mkdir pulumi +mkdir : Элемент с указанным именем C:\DevOps\DevOps-Core-Course\pulumi уже существует. +строка:1 знак:1 ++ mkdir pulumi ++ ~~~~~~~~~~~~ + + CategoryInfo : ResourceExists: (C:\DevOps\DevOps-Core-Course\pulumi:String) [New-Item], IOException + + FullyQualifiedErrorId : DirectoryExist,Microsoft.PowerShell.Commands.NewItemCommand + +PS C:\DevOps\DevOps-Core-Course> cd pulumi +PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi new python +error: C:\DevOps\DevOps-Core-Course\pulumi is not empty; use --force to continue and overwrite existing files, or use --dir to specify an empty directory. +PS C:\DevOps\DevOps-Core-Course\pulumi> tree /f +Структура папок +Серийный номер тома: 56C3-7760 +C:. +│ .gitignore +│ Pulumi.yaml +│ README.md +│ requirements.txt +│ __main__.py +│ +└───__pycache__ + __main__.cpython-311.pyc + +PS C:\DevOps\DevOps-Core-Course\pulumi> python -m venv venv +PS C:\DevOps\DevOps-Core-Course\pulumi> .\venv\Scripts\activate +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pip install -r requirements.txt +Collecting pulumi<4.0.0,>=3.0.0 (from -r requirements.txt (line 1)) + Downloading pulumi-3.222.0-py3-none-any.whl.metadata (3.8 kB) +Collecting pulumi-yandex (from -r requirements.txt (line 2)) + Downloading pulumi_yandex-0.13.0.tar.gz (425 kB) + Installing build dependencies ... done + Getting requirements to build wheel ... done + Preparing metadata (pyproject.toml) ... done +Collecting debugpy~=1.8.7 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading debugpy-1.8.20-cp313-cp313-win_amd64.whl.metadata (1.5 kB) +Collecting dill~=0.4 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading dill-0.4.1-py3-none-any.whl.metadata (10 kB) +Collecting grpcio<2,>=1.68.1 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading grpcio-1.78.0-cp313-cp313-win_amd64.whl.metadata (3.9 kB) +Requirement already satisfied: pip>=24.3.1 in c:\devops\devops-core-course\pulumi\venv\lib\site-packages (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) (24.3.1) +Collecting protobuf<7,>=3.20.3 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading protobuf-6.33.5-cp310-abi3-win_amd64.whl.metadata (593 bytes) +Collecting pyyaml~=6.0 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading pyyaml-6.0.3-cp313-cp313-win_amd64.whl.metadata (2.4 kB) +Collecting semver~=3.0 (from pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Downloading semver-3.0.4-py3-none-any.whl.metadata (6.8 kB) +Collecting parver>=0.2.1 (from pulumi-yandex->-r requirements.txt (line 2)) + Downloading parver-0.5-py3-none-any.whl.metadata (2.7 kB) +Collecting typing-extensions~=4.12 (from grpcio<2,>=1.68.1->pulumi<4.0.0,>=3.0.0->-r requirements.txt (line 1)) + Using cached typing_extensions-4.15.0-py3-none-any.whl.metadata (3.3 kB) +Collecting arpeggio>=1.7 (from parver>=0.2.1->pulumi-yandex->-r requirements.txt (line 2)) + Downloading Arpeggio-2.0.3-py2.py3-none-any.whl.metadata (2.4 kB) +Collecting attrs>=19.2 (from parver>=0.2.1->pulumi-yandex->-r requirements.txt (line 2)) + Using cached attrs-25.4.0-py3-none-any.whl.metadata (10 kB) +Downloading pulumi-3.222.0-py3-none-any.whl (390 kB) +Downloading debugpy-1.8.20-cp313-cp313-win_amd64.whl (5.4 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.4/5.4 MB 7.1 MB/s eta 0:00:00 +Downloading dill-0.4.1-py3-none-any.whl (120 kB) +Downloading grpcio-1.78.0-cp313-cp313-win_amd64.whl (4.8 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.8/4.8 MB 7.6 MB/s eta 0:00:00 +Downloading parver-0.5-py3-none-any.whl (15 kB) +Downloading protobuf-6.33.5-cp310-abi3-win_amd64.whl (437 kB) +Downloading pyyaml-6.0.3-cp313-cp313-win_amd64.whl (154 kB) +Downloading semver-3.0.4-py3-none-any.whl (17 kB) +Downloading Arpeggio-2.0.3-py2.py3-none-any.whl (54 kB) +Using cached attrs-25.4.0-py3-none-any.whl (67 kB) +Using cached typing_extensions-4.15.0-py3-none-any.whl (44 kB) +Building wheels for collected packages: pulumi-yandex + Building wheel for pulumi-yandex (pyproject.toml) ... done + Created wheel for pulumi-yandex: filename=pulumi_yandex-0.13.0-py3-none-any.whl size=606675 sha256=8441929cfc6b1f5855695216aff4c9946e00cbdecca3d15f56ed027966eaa71e + Stored in directory: c:\users\данил\appdata\local\pip\cache\wheels\d0\b7\cf\9a6c587521036e8cbd68fa735d2f5d352bb7fb4f71d8d5aaac +Successfully built pulumi-yandex +Installing collected packages: arpeggio, typing-extensions, semver, pyyaml, protobuf, dill, debugpy, attrs, parver, grpcio, pulumi, pulumi-yandex +Successfully installed arpeggio-2.0.3 attrs-25.4.0 debugpy-1.8.20 dill-0.4.1 grpcio-1.78.0 parver-0.5 protobuf-6.33.5 pulumi-3.222.0 pulumi-yandex-0.13.0 pyyaml-6.0.3 semver-3.0.4 typing-extensions-4.15.0 + +[notice] A new release of pip is available: 24.3.1 -> 26.0.1 +[notice] To update, run: python.exe -m pip install --upgrade pip +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi version +v3.222.0 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> python --version +Python 3.13.1 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi login file://C:\DevOps\DevOps-Core-Course\pulumi\.pulumi-state +error: problem logging in: unable to open bucket file:///C:/DevOps/DevOps-Core-Course/pulumi/.pulumi-state?no_tmp_dir=true: GetFileAttributesEx C:\DevOps\DevOps-Core-Course\pulumi\.pulumi-state: The system cannot find the file specified. +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> New-Item -ItemType Directory -Force .pulumi-state | Out-Null +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi login file://C:\DevOps\DevOps-Core-Course\pulumi\.pulumi-state +Logged in to Dorley as Dorley\Данил (file://C:/DevOps/DevOps-Core-Course/pulumi/.pulumi-state) +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi whoami +Dorley\Данил +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi stack ls +NAME LAST UPDATE RESOURCE COUNT +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi stack init dev +Enter your passphrase to protect config/secrets: +Re-enter your passphrase to confirm: +Created stack 'dev' +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> cd C:\DevOps\DevOps-Core-Course +(venv) PS C:\DevOps\DevOps-Core-Course> .\scripts\load-env.ps1 +Loaded .env OK +YC_CLOUD_ID=b1gca960emnn9qqikne9 +YC_FOLDER_ID=b1g82kdcn5grlmu79ano +YC_ZONE=ru-central1-a +YC_SERVICE_ACCOUNT_KEY_FILE=C:\DevOps\DevOps-Core-Course\key.json +(venv) PS C:\DevOps\DevOps-Core-Course> cd pulumi +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> .\venv\Scripts\activate +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set zone ru-central1-a +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set subnetCidr 10.10.0.0/24 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set allowedSshCidr "95.111.204.70/32" +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set sshUser ubuntu +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set sshPublicKeyPath "~/.ssh/lab04_ed25519.pub" +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config set imageFamily ubuntu-2404-lts +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi preview +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing update (dev): + Type Name Plan Info + + pulumi:pulumi:Stack lab04-pulumi-yc-dev create 1 error +Diagnostics: + pulumi:pulumi:Stack (lab04-pulumi-yc-dev): + error: Program failed with an unhandled exception: + Traceback (most recent call last): + File "C:\DevOps\DevOps-Core-Course\pulumi\__main__.py", line 4, in + import pulumi_yandex as yandex + File "C:\DevOps\DevOps-Core-Course\pulumi\venv\Lib\site-packages\pulumi_yandex\__init__.py", line 5, in + from . import _utilities + File "C:\DevOps\DevOps-Core-Course\pulumi\venv\Lib\site-packages\pulumi_yandex\_utilities.py", line 10, in + import pkg_resources + ModuleNotFoundError: No module named 'pkg_resources' + +Resources: + + 1 to create + 1 errored + +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> python -m pip install --upgrade pip setuptools wheel +Requirement already satisfied: pip in c:\devops\devops-core-course\pulumi\venv\lib\site-packages (24.3.1) +Collecting pip + Downloading pip-26.0.1-py3-none-any.whl.metadata (4.7 kB) +Collecting setuptools + Using cached setuptools-82.0.0-py3-none-any.whl.metadata (6.6 kB) +Collecting wheel + Downloading wheel-0.46.3-py3-none-any.whl.metadata (2.4 kB) +Collecting packaging>=24.0 (from wheel) + Using cached packaging-26.0-py3-none-any.whl.metadata (3.3 kB) +Downloading pip-26.0.1-py3-none-any.whl (1.8 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 8.3 MB/s eta 0:00:00 +Using cached setuptools-82.0.0-py3-none-any.whl (1.0 MB) +Downloading wheel-0.46.3-py3-none-any.whl (30 kB) +Using cached packaging-26.0-py3-none-any.whl (74 kB) +Installing collected packages: setuptools, pip, packaging, wheel + Attempting uninstall: pip + Found existing installation: pip 24.3.1 + Uninstalling pip-24.3.1: + Successfully uninstalled pip-24.3.1 +Successfully installed packaging-26.0 pip-26.0.1 setuptools-82.0.0 wheel-0.46.3 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> python -c "import pkg_resources; print('pkg_resources OK')" +Traceback (most recent call last): + File "", line 1, in + import pkg_resources; print('pkg_resources OK') + ^^^^^^^^^^^^^^^^^^^^ +ModuleNotFoundError: No module named 'pkg_resources' +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> winget install -e --id Python.Python.3.12 +Найден существующий установленный пакет. Попытка обновления установленного пакета... +Найдено Python 3.12 [Python.Python.3.12] Версия 3.12.10 +Лицензия на это приложение предоставлена вам владельцем. +Корпорация Майкрософт не несет ответственность за сторонние пакеты и не предоставляет для них никакие лицензии. +Скачивание https://www.python.org/ftp/python/3.12.10/python-3.12.10-amd64.exe + ██████████████████████████████ 25.7 MB / 25.7 MB +Хэш установщика успешно проверен +Запуск установки пакета... +Вы отменили установку. +Сбой установки с кодом выхода: 1602 +Журнал установщика доступен по адресу: C:\Users\Данил\AppData\Local\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir\Python.Python.3.12.3.12.10-26-02-19-23-43-29.log +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pip uninstall -y setuptools +Found existing installation: setuptools 82.0.0 +Uninstalling setuptools-82.0.0: + Successfully uninstalled setuptools-82.0.0 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pip install setuptools==80.9.0 +Collecting setuptools==80.9.0 + Downloading setuptools-80.9.0-py3-none-any.whl.metadata (6.6 kB) +Downloading setuptools-80.9.0-py3-none-any.whl (1.2 MB) + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2/1.2 MB 6.8 MB/s 0:00:00 +Installing collected packages: setuptools +Successfully installed setuptools-80.9.0 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> python -c "import pkg_resources; print('pkg_resources OK')" +:1: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81. + import pkg_resources; print('pkg_resources OK') +pkg_resources OK +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi stack ls +NAME LAST UPDATE RESOURCE COUNT +dev* 11 minutes ago 0 +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi stack select dev +(venv) PS C:\DevOps\DevOps-Core-Course\pulumi> pulumi config +KEY VALUE +allowedSshCidr 95.111.204.70/32 +imageFamily ubuntu-2404-lts +sshPublicKeyPath ~/.ssh/lab04_ed25519.pub +sshUser ubuntu +subnetCidr 10.10.0.0/24 +zone ru-central1-a \ No newline at end of file diff --git a/lab04_proofs/pulumi_result.txt b/lab04_proofs/pulumi_result.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lab04_proofs/ubuntu_logs.txt b/lab04_proofs/terraform_result.txt similarity index 100% rename from lab04_proofs/ubuntu_logs.txt rename to lab04_proofs/terraform_result.txt diff --git a/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json b/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json new file mode 100644 index 0000000000..b14f996692 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json @@ -0,0 +1,427 @@ +{ + "version": 3, + "checkpoint": { + "stack": "organization/lab04-pulumi-yc/dev", + "latest": { + "manifest": { + "time": "2026-02-19T23:53:41.118824+03:00", + "magic": "7b54cd6e79f5cecd9ae124cb92b834b486c7e21993124e3a4e456c27c3ce48f9", + "version": "v3.222.0" + }, + "secrets_providers": { + "type": "passphrase", + "state": { + "salt": "v1:3yNf1Kmt4mA=:v1:Uk9In8z0RD2XJTza:lncnLY42u3UftJy+QfrDw6S2OT6vmQ==" + } + }, + "resources": [ + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0", + "custom": true, + "id": "7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "type": "pulumi:providers:yandex", + "inputs": { + "__internal": {}, + "version": "0.13.0" + }, + "outputs": { + "version": "0.13.0" + }, + "created": "2026-02-19T20:52:45.8287147Z", + "modified": "2026-02-19T20:52:45.8287147Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "custom": false, + "type": "pulumi:pulumi:Stack", + "outputs": { + "app_url": "http://89.169.135.154:5000/", + "http_url": "http://89.169.135.154/", + "internal_ip": "10.10.0.6", + "public_ip": "89.169.135.154", + "ssh_command": "ssh -i ~/.ssh/lab04_ed25519 ubuntu@89.169.135.154" + }, + "created": "2026-02-19T20:52:45.8630518Z", + "modified": "2026-02-19T20:52:45.8630518Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net", + "custom": true, + "id": "enpet9l87ashn294afa1", + "type": "yandex:index/vpcNetwork:VpcNetwork", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-net-7bf49ed" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":60000000000,\"delete\":60000000000,\"update\":60000000000}}", + "createdAt": "2026-02-19T20:52:48Z", + "defaultSecurityGroupId": "enp912ofg69vrp8iegur", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpet9l87ashn294afa1", + "labels": {}, + "name": "lab04-net-7bf49ed", + "subnetIds": [] + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "created": "2026-02-19T20:52:49.994421Z", + "modified": "2026-02-19T20:52:49.994421Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet", + "custom": true, + "id": "e9b3hl3h09t6drs68pbg", + "type": "yandex:index/vpcSubnet:VpcSubnet", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:50Z", + "description": "", + "dhcpOptions": null, + "folderId": "b1g82kdcn5grlmu79ano", + "id": "e9b3hl3h09t6drs68pbg", + "labels": {}, + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "routeTableId": "", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "v6CidrBlocks": [], + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "v4CidrBlocks": [], + "zone": [] + }, + "created": "2026-02-19T20:52:50.5480973Z", + "modified": "2026-02-19T20:52:50.5480973Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "custom": true, + "id": "enpb8heveqi8pp7mvbcv", + "type": "yandex:index/vpcSecurityGroup:VpcSecurityGroup", + "inputs": { + "__defaults": [ + "name" + ], + "egresses": [ + { + "__defaults": [ + "port" + ], + "description": "Allow all outbound", + "fromPort": 0, + "port": -1, + "protocol": "ANY", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "ingresses": [ + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "SSH", + "fromPort": -1, + "port": 22, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "HTTP", + "fromPort": -1, + "port": 80, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "App 5000", + "fromPort": -1, + "port": 5000, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:52Z", + "description": "", + "egresses": [ + { + "description": "Allow all outbound", + "fromPort": 0, + "id": "enpqsfspqfq9fqiee48t", + "labels": {}, + "port": -1, + "predefinedTarget": "", + "protocol": "ANY", + "securityGroupId": "", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpb8heveqi8pp7mvbcv", + "ingresses": [ + { + "description": "SSH", + "fromPort": -1, + "id": "enpbhntafog7fraba6rd", + "labels": {}, + "port": 22, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ], + "v6CidrBlocks": [] + }, + { + "description": "HTTP", + "fromPort": -1, + "id": "enp80blit93rhb8rh3eb", + "labels": {}, + "port": 80, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + }, + { + "description": "App 5000", + "fromPort": -1, + "id": "enp39asi999eg5hhq4o1", + "labels": {}, + "port": 5000, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "labels": {}, + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1", + "status": "ACTIVE" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "egresses": [], + "ingresses": [], + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ] + }, + "created": "2026-02-19T20:52:52.5246052Z", + "modified": "2026-02-19T20:52:52.5246052Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/computeInstance:ComputeInstance::lab04-vm", + "custom": true, + "id": "fhm7ed1a5b85rs8u3uop", + "type": "yandex:index/computeInstance:ComputeInstance", + "inputs": { + "__defaults": [ + "name", + "networkAccelerationType" + ], + "allowStoppingForUpdate": true, + "bootDisk": { + "__defaults": [ + "autoDelete" + ], + "autoDelete": true, + "initializeParams": { + "__defaults": [], + "imageId": "fd8lt661chfo5i13a40d", + "size": 10, + "type": "network-hdd" + } + }, + "metadata": { + "__defaults": [], + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "__defaults": [ + "ipv4" + ], + "ipv4": true, + "nat": true, + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "platformId": "standard-v2", + "resources": { + "__defaults": [], + "coreFraction": 20, + "cores": 2, + "memory": 1 + }, + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":300000000000,\"delete\":300000000000,\"update\":300000000000},\"schema_version\":\"1\"}", + "allowStoppingForUpdate": true, + "bootDisk": { + "autoDelete": true, + "deviceName": "fhmonvdcv96scusbdsm3", + "diskId": "fhmonvdcv96scusbdsm3", + "initializeParams": { + "blockSize": 4096, + "description": "", + "imageId": "fd8lt661chfo5i13a40d", + "name": "", + "size": 10, + "snapshotId": "", + "type": "network-hdd" + }, + "mode": "READ_WRITE" + }, + "createdAt": "2026-02-19T20:52:53Z", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "fqdn": "fhm7ed1a5b85rs8u3uop.auto.internal", + "hostname": "fhm7ed1a5b85rs8u3uop", + "id": "fhm7ed1a5b85rs8u3uop", + "labels": {}, + "metadata": { + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "dnsRecords": [], + "index": 0, + "ipAddress": "10.10.0.6", + "ipv4": true, + "ipv6": false, + "ipv6Address": "", + "ipv6DnsRecords": [], + "macAddress": "d0:0d:77:34:2a:2a", + "nat": true, + "natDnsRecords": [], + "natIpAddress": "89.169.135.154", + "natIpVersion": "IPV4", + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "placementPolicy": { + "placementGroupId": "" + }, + "platformId": "standard-v2", + "resources": { + "coreFraction": 20, + "cores": 2, + "gpus": 0, + "memory": 1 + }, + "schedulingPolicy": { + "preemptible": false + }, + "secondaryDisks": [], + "serviceAccountId": "", + "status": "running", + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "allowStoppingForUpdate": [], + "bootDisk": [], + "metadata": [], + "networkInterfaces": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "platformId": [], + "resources": [], + "zone": [] + }, + "created": "2026-02-19T20:53:41.0764236Z", + "modified": "2026-02-19T20:53:41.0764236Z" + } + ], + "metadata": {} + } + } +} diff --git a/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json.attrs b/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json.attrs new file mode 100644 index 0000000000..4dbba8b4a3 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/backups/lab04-pulumi-yc/dev/dev.1771534421400792500.json.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"8aVExZ8N8dRKSmZc6/Q9ng=="} diff --git a/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json new file mode 100644 index 0000000000..b14f996692 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json @@ -0,0 +1,427 @@ +{ + "version": 3, + "checkpoint": { + "stack": "organization/lab04-pulumi-yc/dev", + "latest": { + "manifest": { + "time": "2026-02-19T23:53:41.118824+03:00", + "magic": "7b54cd6e79f5cecd9ae124cb92b834b486c7e21993124e3a4e456c27c3ce48f9", + "version": "v3.222.0" + }, + "secrets_providers": { + "type": "passphrase", + "state": { + "salt": "v1:3yNf1Kmt4mA=:v1:Uk9In8z0RD2XJTza:lncnLY42u3UftJy+QfrDw6S2OT6vmQ==" + } + }, + "resources": [ + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0", + "custom": true, + "id": "7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "type": "pulumi:providers:yandex", + "inputs": { + "__internal": {}, + "version": "0.13.0" + }, + "outputs": { + "version": "0.13.0" + }, + "created": "2026-02-19T20:52:45.8287147Z", + "modified": "2026-02-19T20:52:45.8287147Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "custom": false, + "type": "pulumi:pulumi:Stack", + "outputs": { + "app_url": "http://89.169.135.154:5000/", + "http_url": "http://89.169.135.154/", + "internal_ip": "10.10.0.6", + "public_ip": "89.169.135.154", + "ssh_command": "ssh -i ~/.ssh/lab04_ed25519 ubuntu@89.169.135.154" + }, + "created": "2026-02-19T20:52:45.8630518Z", + "modified": "2026-02-19T20:52:45.8630518Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net", + "custom": true, + "id": "enpet9l87ashn294afa1", + "type": "yandex:index/vpcNetwork:VpcNetwork", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-net-7bf49ed" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":60000000000,\"delete\":60000000000,\"update\":60000000000}}", + "createdAt": "2026-02-19T20:52:48Z", + "defaultSecurityGroupId": "enp912ofg69vrp8iegur", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpet9l87ashn294afa1", + "labels": {}, + "name": "lab04-net-7bf49ed", + "subnetIds": [] + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "created": "2026-02-19T20:52:49.994421Z", + "modified": "2026-02-19T20:52:49.994421Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet", + "custom": true, + "id": "e9b3hl3h09t6drs68pbg", + "type": "yandex:index/vpcSubnet:VpcSubnet", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:50Z", + "description": "", + "dhcpOptions": null, + "folderId": "b1g82kdcn5grlmu79ano", + "id": "e9b3hl3h09t6drs68pbg", + "labels": {}, + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "routeTableId": "", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "v6CidrBlocks": [], + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "v4CidrBlocks": [], + "zone": [] + }, + "created": "2026-02-19T20:52:50.5480973Z", + "modified": "2026-02-19T20:52:50.5480973Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "custom": true, + "id": "enpb8heveqi8pp7mvbcv", + "type": "yandex:index/vpcSecurityGroup:VpcSecurityGroup", + "inputs": { + "__defaults": [ + "name" + ], + "egresses": [ + { + "__defaults": [ + "port" + ], + "description": "Allow all outbound", + "fromPort": 0, + "port": -1, + "protocol": "ANY", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "ingresses": [ + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "SSH", + "fromPort": -1, + "port": 22, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "HTTP", + "fromPort": -1, + "port": 80, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "App 5000", + "fromPort": -1, + "port": 5000, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:52Z", + "description": "", + "egresses": [ + { + "description": "Allow all outbound", + "fromPort": 0, + "id": "enpqsfspqfq9fqiee48t", + "labels": {}, + "port": -1, + "predefinedTarget": "", + "protocol": "ANY", + "securityGroupId": "", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpb8heveqi8pp7mvbcv", + "ingresses": [ + { + "description": "SSH", + "fromPort": -1, + "id": "enpbhntafog7fraba6rd", + "labels": {}, + "port": 22, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ], + "v6CidrBlocks": [] + }, + { + "description": "HTTP", + "fromPort": -1, + "id": "enp80blit93rhb8rh3eb", + "labels": {}, + "port": 80, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + }, + { + "description": "App 5000", + "fromPort": -1, + "id": "enp39asi999eg5hhq4o1", + "labels": {}, + "port": 5000, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "labels": {}, + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1", + "status": "ACTIVE" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "egresses": [], + "ingresses": [], + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ] + }, + "created": "2026-02-19T20:52:52.5246052Z", + "modified": "2026-02-19T20:52:52.5246052Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/computeInstance:ComputeInstance::lab04-vm", + "custom": true, + "id": "fhm7ed1a5b85rs8u3uop", + "type": "yandex:index/computeInstance:ComputeInstance", + "inputs": { + "__defaults": [ + "name", + "networkAccelerationType" + ], + "allowStoppingForUpdate": true, + "bootDisk": { + "__defaults": [ + "autoDelete" + ], + "autoDelete": true, + "initializeParams": { + "__defaults": [], + "imageId": "fd8lt661chfo5i13a40d", + "size": 10, + "type": "network-hdd" + } + }, + "metadata": { + "__defaults": [], + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "__defaults": [ + "ipv4" + ], + "ipv4": true, + "nat": true, + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "platformId": "standard-v2", + "resources": { + "__defaults": [], + "coreFraction": 20, + "cores": 2, + "memory": 1 + }, + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":300000000000,\"delete\":300000000000,\"update\":300000000000},\"schema_version\":\"1\"}", + "allowStoppingForUpdate": true, + "bootDisk": { + "autoDelete": true, + "deviceName": "fhmonvdcv96scusbdsm3", + "diskId": "fhmonvdcv96scusbdsm3", + "initializeParams": { + "blockSize": 4096, + "description": "", + "imageId": "fd8lt661chfo5i13a40d", + "name": "", + "size": 10, + "snapshotId": "", + "type": "network-hdd" + }, + "mode": "READ_WRITE" + }, + "createdAt": "2026-02-19T20:52:53Z", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "fqdn": "fhm7ed1a5b85rs8u3uop.auto.internal", + "hostname": "fhm7ed1a5b85rs8u3uop", + "id": "fhm7ed1a5b85rs8u3uop", + "labels": {}, + "metadata": { + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "dnsRecords": [], + "index": 0, + "ipAddress": "10.10.0.6", + "ipv4": true, + "ipv6": false, + "ipv6Address": "", + "ipv6DnsRecords": [], + "macAddress": "d0:0d:77:34:2a:2a", + "nat": true, + "natDnsRecords": [], + "natIpAddress": "89.169.135.154", + "natIpVersion": "IPV4", + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "placementPolicy": { + "placementGroupId": "" + }, + "platformId": "standard-v2", + "resources": { + "coreFraction": 20, + "cores": 2, + "gpus": 0, + "memory": 1 + }, + "schedulingPolicy": { + "preemptible": false + }, + "secondaryDisks": [], + "serviceAccountId": "", + "status": "running", + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "allowStoppingForUpdate": [], + "bootDisk": [], + "metadata": [], + "networkInterfaces": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "platformId": [], + "resources": [], + "zone": [] + }, + "created": "2026-02-19T20:53:41.0764236Z", + "modified": "2026-02-19T20:53:41.0764236Z" + } + ], + "metadata": {} + } + } +} diff --git a/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json.attrs b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json.attrs new file mode 100644 index 0000000000..4dbba8b4a3 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.checkpoint.json.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"8aVExZ8N8dRKSmZc6/Q9ng=="} diff --git a/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json new file mode 100644 index 0000000000..aeb75b84a2 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json @@ -0,0 +1,44 @@ +{ + "kind": "update", + "startTime": 1771534364, + "message": "feat: added terraform lab part", + "environment": { + "exec.kind": "cli", + "git.author": "dorley174", + "git.author.email": "d.valiev@innopolis.university", + "git.committer": "dorley174", + "git.committer.email": "d.valiev@innopolis.university", + "git.dirty": "true", + "git.head": "46866051a9837ae9503ab3f8665d0317ce29e2dc", + "git.headName": "refs/heads/lab04", + "pulumi.arch": "amd64", + "pulumi.os": "windows", + "pulumi.version": "v3.222.0", + "runtime.executable": "C:\\DevOps\\DevOps-Core-Course\\pulumi\\venv\\Scripts\\python.exe", + "runtime.metadata.toolchain": "Pip", + "runtime.metadata.toolchainVersion": "26.0.1", + "runtime.metadata.typechecker": "None", + "runtime.name": "python", + "runtime.version": "3.13.1", + "stack.environments": "[]", + "updatePlan": "false", + "vcs.kind": "github.com", + "vcs.owner": "dorley174", + "vcs.repo": "DevOps-Core-Course", + "vcs.root": "pulumi" + }, + "config": { + "lab04-pulumi-yc:allowedSshCidr": "95.111.204.70/32", + "lab04-pulumi-yc:imageFamily": "ubuntu-2404-lts", + "lab04-pulumi-yc:sshPublicKeyPath": "~/.ssh/lab04_ed25519.pub", + "lab04-pulumi-yc:sshUser": "ubuntu", + "lab04-pulumi-yc:subnetCidr": "10.10.0.0/24", + "lab04-pulumi-yc:zone": "ru-central1-a" + }, + "version": 0, + "result": "succeeded", + "endTime": 1771534421, + "resourceChanges": { + "create": 5 + } +} diff --git a/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json.attrs b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json.attrs new file mode 100644 index 0000000000..9921a06eaa --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/history/lab04-pulumi-yc/dev/dev-1771534421389384600.history.json.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"ff0qIY8bvz4izQQb8WO+fA=="} diff --git a/pulumi/.pulumi-state/.pulumi/meta.yaml b/pulumi/.pulumi-state/.pulumi/meta.yaml new file mode 100644 index 0000000000..b82551848c --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/meta.yaml @@ -0,0 +1 @@ +version: 1 diff --git a/pulumi/.pulumi-state/.pulumi/meta.yaml.attrs b/pulumi/.pulumi-state/.pulumi/meta.yaml.attrs new file mode 100644 index 0000000000..4466031b30 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/meta.yaml.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"EaRWdV65+nlqCnYlI4a4Wg=="} diff --git a/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json new file mode 100644 index 0000000000..b14f996692 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json @@ -0,0 +1,427 @@ +{ + "version": 3, + "checkpoint": { + "stack": "organization/lab04-pulumi-yc/dev", + "latest": { + "manifest": { + "time": "2026-02-19T23:53:41.118824+03:00", + "magic": "7b54cd6e79f5cecd9ae124cb92b834b486c7e21993124e3a4e456c27c3ce48f9", + "version": "v3.222.0" + }, + "secrets_providers": { + "type": "passphrase", + "state": { + "salt": "v1:3yNf1Kmt4mA=:v1:Uk9In8z0RD2XJTza:lncnLY42u3UftJy+QfrDw6S2OT6vmQ==" + } + }, + "resources": [ + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0", + "custom": true, + "id": "7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "type": "pulumi:providers:yandex", + "inputs": { + "__internal": {}, + "version": "0.13.0" + }, + "outputs": { + "version": "0.13.0" + }, + "created": "2026-02-19T20:52:45.8287147Z", + "modified": "2026-02-19T20:52:45.8287147Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "custom": false, + "type": "pulumi:pulumi:Stack", + "outputs": { + "app_url": "http://89.169.135.154:5000/", + "http_url": "http://89.169.135.154/", + "internal_ip": "10.10.0.6", + "public_ip": "89.169.135.154", + "ssh_command": "ssh -i ~/.ssh/lab04_ed25519 ubuntu@89.169.135.154" + }, + "created": "2026-02-19T20:52:45.8630518Z", + "modified": "2026-02-19T20:52:45.8630518Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net", + "custom": true, + "id": "enpet9l87ashn294afa1", + "type": "yandex:index/vpcNetwork:VpcNetwork", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-net-7bf49ed" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":60000000000,\"delete\":60000000000,\"update\":60000000000}}", + "createdAt": "2026-02-19T20:52:48Z", + "defaultSecurityGroupId": "enp912ofg69vrp8iegur", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpet9l87ashn294afa1", + "labels": {}, + "name": "lab04-net-7bf49ed", + "subnetIds": [] + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "created": "2026-02-19T20:52:49.994421Z", + "modified": "2026-02-19T20:52:49.994421Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet", + "custom": true, + "id": "e9b3hl3h09t6drs68pbg", + "type": "yandex:index/vpcSubnet:VpcSubnet", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:50Z", + "description": "", + "dhcpOptions": null, + "folderId": "b1g82kdcn5grlmu79ano", + "id": "e9b3hl3h09t6drs68pbg", + "labels": {}, + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "routeTableId": "", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "v6CidrBlocks": [], + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "v4CidrBlocks": [], + "zone": [] + }, + "created": "2026-02-19T20:52:50.5480973Z", + "modified": "2026-02-19T20:52:50.5480973Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "custom": true, + "id": "enpb8heveqi8pp7mvbcv", + "type": "yandex:index/vpcSecurityGroup:VpcSecurityGroup", + "inputs": { + "__defaults": [ + "name" + ], + "egresses": [ + { + "__defaults": [ + "port" + ], + "description": "Allow all outbound", + "fromPort": 0, + "port": -1, + "protocol": "ANY", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "ingresses": [ + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "SSH", + "fromPort": -1, + "port": 22, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "HTTP", + "fromPort": -1, + "port": 80, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "App 5000", + "fromPort": -1, + "port": 5000, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:52Z", + "description": "", + "egresses": [ + { + "description": "Allow all outbound", + "fromPort": 0, + "id": "enpqsfspqfq9fqiee48t", + "labels": {}, + "port": -1, + "predefinedTarget": "", + "protocol": "ANY", + "securityGroupId": "", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpb8heveqi8pp7mvbcv", + "ingresses": [ + { + "description": "SSH", + "fromPort": -1, + "id": "enpbhntafog7fraba6rd", + "labels": {}, + "port": 22, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ], + "v6CidrBlocks": [] + }, + { + "description": "HTTP", + "fromPort": -1, + "id": "enp80blit93rhb8rh3eb", + "labels": {}, + "port": 80, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + }, + { + "description": "App 5000", + "fromPort": -1, + "id": "enp39asi999eg5hhq4o1", + "labels": {}, + "port": 5000, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "labels": {}, + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1", + "status": "ACTIVE" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "egresses": [], + "ingresses": [], + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ] + }, + "created": "2026-02-19T20:52:52.5246052Z", + "modified": "2026-02-19T20:52:52.5246052Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/computeInstance:ComputeInstance::lab04-vm", + "custom": true, + "id": "fhm7ed1a5b85rs8u3uop", + "type": "yandex:index/computeInstance:ComputeInstance", + "inputs": { + "__defaults": [ + "name", + "networkAccelerationType" + ], + "allowStoppingForUpdate": true, + "bootDisk": { + "__defaults": [ + "autoDelete" + ], + "autoDelete": true, + "initializeParams": { + "__defaults": [], + "imageId": "fd8lt661chfo5i13a40d", + "size": 10, + "type": "network-hdd" + } + }, + "metadata": { + "__defaults": [], + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "__defaults": [ + "ipv4" + ], + "ipv4": true, + "nat": true, + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "platformId": "standard-v2", + "resources": { + "__defaults": [], + "coreFraction": 20, + "cores": 2, + "memory": 1 + }, + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":300000000000,\"delete\":300000000000,\"update\":300000000000},\"schema_version\":\"1\"}", + "allowStoppingForUpdate": true, + "bootDisk": { + "autoDelete": true, + "deviceName": "fhmonvdcv96scusbdsm3", + "diskId": "fhmonvdcv96scusbdsm3", + "initializeParams": { + "blockSize": 4096, + "description": "", + "imageId": "fd8lt661chfo5i13a40d", + "name": "", + "size": 10, + "snapshotId": "", + "type": "network-hdd" + }, + "mode": "READ_WRITE" + }, + "createdAt": "2026-02-19T20:52:53Z", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "fqdn": "fhm7ed1a5b85rs8u3uop.auto.internal", + "hostname": "fhm7ed1a5b85rs8u3uop", + "id": "fhm7ed1a5b85rs8u3uop", + "labels": {}, + "metadata": { + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "dnsRecords": [], + "index": 0, + "ipAddress": "10.10.0.6", + "ipv4": true, + "ipv6": false, + "ipv6Address": "", + "ipv6DnsRecords": [], + "macAddress": "d0:0d:77:34:2a:2a", + "nat": true, + "natDnsRecords": [], + "natIpAddress": "89.169.135.154", + "natIpVersion": "IPV4", + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "placementPolicy": { + "placementGroupId": "" + }, + "platformId": "standard-v2", + "resources": { + "coreFraction": 20, + "cores": 2, + "gpus": 0, + "memory": 1 + }, + "schedulingPolicy": { + "preemptible": false + }, + "secondaryDisks": [], + "serviceAccountId": "", + "status": "running", + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "allowStoppingForUpdate": [], + "bootDisk": [], + "metadata": [], + "networkInterfaces": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "platformId": [], + "resources": [], + "zone": [] + }, + "created": "2026-02-19T20:53:41.0764236Z", + "modified": "2026-02-19T20:53:41.0764236Z" + } + ], + "metadata": {} + } + } +} diff --git a/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.attrs b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.attrs new file mode 100644 index 0000000000..4dbba8b4a3 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"8aVExZ8N8dRKSmZc6/Q9ng=="} diff --git a/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak new file mode 100644 index 0000000000..5e5007b70d --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak @@ -0,0 +1,420 @@ +{ + "version": 3, + "checkpoint": { + "stack": "organization/lab04-pulumi-yc/dev", + "latest": { + "manifest": { + "time": "2026-02-19T23:53:41.0764236+03:00", + "magic": "7b54cd6e79f5cecd9ae124cb92b834b486c7e21993124e3a4e456c27c3ce48f9", + "version": "v3.222.0" + }, + "secrets_providers": { + "type": "passphrase", + "state": { + "salt": "v1:3yNf1Kmt4mA=:v1:Uk9In8z0RD2XJTza:lncnLY42u3UftJy+QfrDw6S2OT6vmQ==" + } + }, + "resources": [ + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0", + "custom": true, + "id": "7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "type": "pulumi:providers:yandex", + "inputs": { + "__internal": {}, + "version": "0.13.0" + }, + "outputs": { + "version": "0.13.0" + }, + "created": "2026-02-19T20:52:45.8287147Z", + "modified": "2026-02-19T20:52:45.8287147Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "custom": false, + "type": "pulumi:pulumi:Stack", + "created": "2026-02-19T20:52:45.8630518Z", + "modified": "2026-02-19T20:52:45.8630518Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net", + "custom": true, + "id": "enpet9l87ashn294afa1", + "type": "yandex:index/vpcNetwork:VpcNetwork", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-net-7bf49ed" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":60000000000,\"delete\":60000000000,\"update\":60000000000}}", + "createdAt": "2026-02-19T20:52:48Z", + "defaultSecurityGroupId": "enp912ofg69vrp8iegur", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpet9l87ashn294afa1", + "labels": {}, + "name": "lab04-net-7bf49ed", + "subnetIds": [] + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "created": "2026-02-19T20:52:49.994421Z", + "modified": "2026-02-19T20:52:49.994421Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet", + "custom": true, + "id": "e9b3hl3h09t6drs68pbg", + "type": "yandex:index/vpcSubnet:VpcSubnet", + "inputs": { + "__defaults": [ + "name" + ], + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:50Z", + "description": "", + "dhcpOptions": null, + "folderId": "b1g82kdcn5grlmu79ano", + "id": "e9b3hl3h09t6drs68pbg", + "labels": {}, + "name": "lab04-subnet-1fa918f", + "networkId": "enpet9l87ashn294afa1", + "routeTableId": "", + "v4CidrBlocks": [ + "10.10.0.0/24" + ], + "v6CidrBlocks": [], + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "v4CidrBlocks": [], + "zone": [] + }, + "created": "2026-02-19T20:52:50.5480973Z", + "modified": "2026-02-19T20:52:50.5480973Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "custom": true, + "id": "enpb8heveqi8pp7mvbcv", + "type": "yandex:index/vpcSecurityGroup:VpcSecurityGroup", + "inputs": { + "__defaults": [ + "name" + ], + "egresses": [ + { + "__defaults": [ + "port" + ], + "description": "Allow all outbound", + "fromPort": 0, + "port": -1, + "protocol": "ANY", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "ingresses": [ + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "SSH", + "fromPort": -1, + "port": 22, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "HTTP", + "fromPort": -1, + "port": 80, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + }, + { + "__defaults": [ + "fromPort", + "toPort" + ], + "description": "App 5000", + "fromPort": -1, + "port": 5000, + "protocol": "TCP", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ] + } + ], + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":180000000000,\"delete\":180000000000,\"update\":180000000000}}", + "createdAt": "2026-02-19T20:52:52Z", + "description": "", + "egresses": [ + { + "description": "Allow all outbound", + "fromPort": 0, + "id": "enpqsfspqfq9fqiee48t", + "labels": {}, + "port": -1, + "predefinedTarget": "", + "protocol": "ANY", + "securityGroupId": "", + "toPort": 65535, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "folderId": "b1g82kdcn5grlmu79ano", + "id": "enpb8heveqi8pp7mvbcv", + "ingresses": [ + { + "description": "SSH", + "fromPort": -1, + "id": "enpbhntafog7fraba6rd", + "labels": {}, + "port": 22, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "95.111.204.70/32" + ], + "v6CidrBlocks": [] + }, + { + "description": "HTTP", + "fromPort": -1, + "id": "enp80blit93rhb8rh3eb", + "labels": {}, + "port": 80, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + }, + { + "description": "App 5000", + "fromPort": -1, + "id": "enp39asi999eg5hhq4o1", + "labels": {}, + "port": 5000, + "predefinedTarget": "", + "protocol": "TCP", + "securityGroupId": "", + "toPort": -1, + "v4CidrBlocks": [ + "0.0.0.0/0" + ], + "v6CidrBlocks": [] + } + ], + "labels": {}, + "name": "lab04-sg-7fdbda7", + "networkId": "enpet9l87ashn294afa1", + "status": "ACTIVE" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "egresses": [], + "ingresses": [], + "networkId": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcNetwork:VpcNetwork::lab04-net" + ] + }, + "created": "2026-02-19T20:52:52.5246052Z", + "modified": "2026-02-19T20:52:52.5246052Z" + }, + { + "urn": "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/computeInstance:ComputeInstance::lab04-vm", + "custom": true, + "id": "fhm7ed1a5b85rs8u3uop", + "type": "yandex:index/computeInstance:ComputeInstance", + "inputs": { + "__defaults": [ + "name", + "networkAccelerationType" + ], + "allowStoppingForUpdate": true, + "bootDisk": { + "__defaults": [ + "autoDelete" + ], + "autoDelete": true, + "initializeParams": { + "__defaults": [], + "imageId": "fd8lt661chfo5i13a40d", + "size": 10, + "type": "network-hdd" + } + }, + "metadata": { + "__defaults": [], + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "__defaults": [ + "ipv4" + ], + "ipv4": true, + "nat": true, + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "platformId": "standard-v2", + "resources": { + "__defaults": [], + "coreFraction": 20, + "cores": 2, + "memory": 1 + }, + "zone": "ru-central1-a" + }, + "outputs": { + "__meta": "{\"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0\":{\"create\":300000000000,\"delete\":300000000000,\"update\":300000000000},\"schema_version\":\"1\"}", + "allowStoppingForUpdate": true, + "bootDisk": { + "autoDelete": true, + "deviceName": "fhmonvdcv96scusbdsm3", + "diskId": "fhmonvdcv96scusbdsm3", + "initializeParams": { + "blockSize": 4096, + "description": "", + "imageId": "fd8lt661chfo5i13a40d", + "name": "", + "size": 10, + "snapshotId": "", + "type": "network-hdd" + }, + "mode": "READ_WRITE" + }, + "createdAt": "2026-02-19T20:52:53Z", + "description": "", + "folderId": "b1g82kdcn5grlmu79ano", + "fqdn": "fhm7ed1a5b85rs8u3uop.auto.internal", + "hostname": "fhm7ed1a5b85rs8u3uop", + "id": "fhm7ed1a5b85rs8u3uop", + "labels": {}, + "metadata": { + "ssh-keys": "ubuntu:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII5nKglXX/E2/S3oPKXahGr77IZELnnZlqE4oGCyEhZQ Данил@Dorley" + }, + "name": "lab04-vm-6023a00", + "networkAccelerationType": "standard", + "networkInterfaces": [ + { + "dnsRecords": [], + "index": 0, + "ipAddress": "10.10.0.6", + "ipv4": true, + "ipv6": false, + "ipv6Address": "", + "ipv6DnsRecords": [], + "macAddress": "d0:0d:77:34:2a:2a", + "nat": true, + "natDnsRecords": [], + "natIpAddress": "89.169.135.154", + "natIpVersion": "IPV4", + "securityGroupIds": [ + "enpb8heveqi8pp7mvbcv" + ], + "subnetId": "e9b3hl3h09t6drs68pbg" + } + ], + "placementPolicy": { + "placementGroupId": "" + }, + "platformId": "standard-v2", + "resources": { + "coreFraction": 20, + "cores": 2, + "gpus": 0, + "memory": 1 + }, + "schedulingPolicy": { + "preemptible": false + }, + "secondaryDisks": [], + "serviceAccountId": "", + "status": "running", + "zone": "ru-central1-a" + }, + "parent": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:pulumi:Stack::lab04-pulumi-yc-dev", + "dependencies": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "provider": "urn:pulumi:dev::lab04-pulumi-yc::pulumi:providers:yandex::default_0_13_0::7d12287d-55f3-465d-8fa0-e63bfc770a1f", + "propertyDependencies": { + "allowStoppingForUpdate": [], + "bootDisk": [], + "metadata": [], + "networkInterfaces": [ + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSecurityGroup:VpcSecurityGroup::lab04-sg", + "urn:pulumi:dev::lab04-pulumi-yc::yandex:index/vpcSubnet:VpcSubnet::lab04-subnet" + ], + "platformId": [], + "resources": [], + "zone": [] + }, + "created": "2026-02-19T20:53:41.0764236Z", + "modified": "2026-02-19T20:53:41.0764236Z" + } + ], + "metadata": {} + } + } +} diff --git a/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak.attrs b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak.attrs new file mode 100644 index 0000000000..60a4efc8b8 --- /dev/null +++ b/pulumi/.pulumi-state/.pulumi/stacks/lab04-pulumi-yc/dev.json.bak.attrs @@ -0,0 +1 @@ +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"text/plain; charset=utf-8","user.metadata":null,"md5":"N1dWOE4/X1j2axM1iAPBng=="} diff --git a/pulumi/__main__.py b/pulumi/__main__.py index d8ea114bf9..738775ea30 100644 --- a/pulumi/__main__.py +++ b/pulumi/__main__.py @@ -61,7 +61,7 @@ sg = yandex.VpcSecurityGroup( "lab04-sg", network_id=net.id, - ingress=[ + ingresses=[ yandex.VpcSecurityGroupIngressArgs( protocol="TCP", description="SSH", @@ -81,7 +81,7 @@ port=5000, ), ], - egress=[ + egresses=[ yandex.VpcSecurityGroupEgressArgs( protocol="ANY", description="Allow all outbound", @@ -92,6 +92,7 @@ ], ) + # ----------------- # VM # -----------------