{"id":337365,"date":"2022-08-22T09:00:36","date_gmt":"2022-08-22T09:00:36","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=337365"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=337365","title":{"rendered":"<span>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Jenkins \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u0432 Kubernetes \u0432 Yandex Cloud \u0441 letsencypt<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0417\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u0435 DNS \u0434\u043e\u043c\u0435\u043d\u0430 \u043d\u0430 reg.ru.<\/li>\n<li>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 DNS \u0437\u043e\u043d\u043e\u0439 \u0432 Yandex DNS c \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Kubernetes \u0432 Yandex Cloud.<\/li>\n<li>\u0420\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0443\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441.<\/li>\n<li>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Jenkins c \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u043c\u043e\u0434\u0443\u043b\u044f helm_release.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 ClusterIssue(Issue) \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f letsencypt \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430.<\/li>\n<\/ul>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p><strong>\u0411\u044b\u0441\u0442\u0440\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Jenkins \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u0432 Kubernetes \u0432 Yandex Cloud \u0441 letsencypt.<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">git clone https:\/\/github.com\/patsevanton\/infrastructure-as-a-code-example.git<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 terraform-helm-release-jenkins:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">cd terraform-helm-release-jenkins<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c private.auto.tfvars \u043d\u0430 \u0431\u0430\u0437\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 private.auto.tfvars.example.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">k8s_install.sh<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0432\u043e\u0434\u0438\u043c DNS \u0434\u043e\u043c\u0435\u043d \u043d\u0430 reg.ru \u2014 <code>mycompany.ru<\/code> \u0438\u043b\u0438 <code>mycompany.org.ru<\/code>. \u0412 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0434\u043e\u043c\u0435\u043d\u0430 \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 &#171;DNS-\u0441\u0435\u0440\u0432\u0435\u0440\u044b \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u043e\u043d\u043e\u0439&#187; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c DNS Yandex Cloud:<\/p>\n<p>  <\/p>\n<ul>\n<li>ns1.yandexcloud.net<\/li>\n<li>ns2.yandexcloud.net<\/li>\n<\/ul>\n<p>  <\/p>\n<p>DNS \u0437\u043e\u043d\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u043a\u043e\u0434\u0430. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u2014 <a href=\"https:\/\/cloud.yandex.ru\/docs\/dns\/\" rel=\"nofollow noopener noreferrer\">https:\/\/cloud.yandex.ru\/docs\/dns\/<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_dns_zone\" \"dns_domain\" {   name   = replace(var.dns_domain, \".\", \"-\")   zone   = join(\"\", [var.dns_domain, \".\"])   public = true }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0443 zone \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0442\u043e\u0447\u043a\u0430, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 join \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 \u0438 \u0442\u043e\u0447\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 DNS \u0437\u0430\u043f\u0438\u0441\u0438.<\/strong> <\/p>\n<p>  <\/p>\n<p>\u0412 \u0438\u043c\u0435\u043d\u0438 DNS \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u043a\u043e\u043d\u0446\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0442\u043e\u0447\u043a\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 join \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f DNS \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u0442\u043e\u0447\u043a\u0438. \u041a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_dns_recordset\" \"jenkins_dns_domain\" {   zone_id = yandex_dns_zone.dns_domain.id   name    = join(\"\", [var.jenkins_dns_name, \".\"])   type    = \"A\"   ttl     = 200   data    = [yandex_vpc_address.addr.external_ipv4_address[0].address] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0435 data \u2014 \u0441\u043f\u0438\u0441\u043e\u043a IP \u0430\u0434\u0440\u0435\u0441\u043e\u0432, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442\u044c\u0441\u044f \u044d\u0442\u0430 DNS \u0437\u0430\u043f\u0438\u0441\u044c.<\/p>\n<p>  <\/p>\n<p>*<em>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430.<\/em><\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c Kubernetes \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u043e\u0433\u043e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 \u2014 <code>sa-k8s-admin<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_iam_service_account\" \"sa-k8s-admin\" {   folder_id = var.yc_folder_id   name      = \"sa-k8s-admin\" }  resource \"yandex_resourcemanager_folder_iam_member\" \"sa-k8s-admin-permissions\" {   folder_id = var.yc_folder_id   role      = \"admin\"   member    = \"serviceAccount:${yandex_iam_service_account.sa-k8s-admin.id}\" }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>yandex_resourcemanager_folder_iam_member<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>yandex_resourcemanager_folder_iam_binding<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u0423 \u043c\u0435\u043d\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043e\u0434\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443. Issue \u2014 <a href=\"https:\/\/github.com\/yandex-cloud\/terraform-provider-yandex\/issues\/267\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/yandex-cloud\/terraform-provider-yandex\/issues\/267<\/a> \u0438 <a href=\"https:\/\/github.com\/yandex-cloud\/terraform-provider-yandex\/issues\/283\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/yandex-cloud\/terraform-provider-yandex\/issues\/283<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\"Binding for role \"mdb.dataproc.agent\" not found in policy\"<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 <code>role<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442. \u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/cloud.yandex.ru\/docs\/iam\/concepts\/access-control\/roles\" rel=\"nofollow noopener noreferrer\">https:\/\/cloud.yandex.ru\/docs\/iam\/concepts\/access-control\/roles<\/a>.<\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 kubernetes \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0432 Yandex Cloud.<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 kubernetes \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0432 Yandex Cloud \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 terraform \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_kubernetes_cluster\" \"zonal_k8s_cluster\" {   name        = \"my-cluster\"   description = \"my-cluster description\"   network_id  = yandex_vpc_network.k8s-network.id    master {     version = \"1.21\"     zonal {       zone      = yandex_vpc_subnet.k8s-subnet.zone       subnet_id = yandex_vpc_subnet.k8s-subnet.id     }     public_ip = true   }    service_account_id      = yandex_iam_service_account.sa-k8s-admin.id   node_service_account_id = yandex_iam_service_account.sa-k8s-admin.id   release_channel         = \"STABLE\"   \/\/ to keep permissions of service account on destroy   \/\/ until cluster will be destroyed   depends_on = [yandex_resourcemanager_folder_iam_member.sa-k8s-admin-permissions] }  # yandex_kubernetes_node_group  resource \"yandex_kubernetes_node_group\" \"k8s_node_group\" {   cluster_id  = yandex_kubernetes_cluster.zonal_k8s_cluster.id   name        = \"name\"   description = \"description\"   version     = \"1.21\"    labels = {     \"key\" = \"value\"   }    instance_template {     platform_id = \"standard-v3\"      network_interface {       nat        = true       subnet_ids = [yandex_vpc_subnet.k8s-subnet.id]     }      resources {       cores         = 2       memory        = 4       core_fraction = 50     }      boot_disk {       type = \"network-hdd\"       size = 32     }      scheduling_policy {       preemptible = true     }      metadata = {       ssh-keys = \"ubuntu:${file(\"~\/.ssh\/id_rsa.pub\")}\"     }    }    scale_policy {     fixed_scale {       size = 1     }   }    allocation_policy {     location {       zone = \"ru-central1-b\"     }   }    maintenance_policy {     auto_upgrade = true     auto_repair  = true      maintenance_window {       day        = \"monday\"       start_time = \"15:00\"       duration   = \"3h\"     }      maintenance_window {       day        = \"friday\"       start_time = \"10:00\"       duration   = \"4h30m\"     }   } }  locals {   kubeconfig = &lt;&lt;KUBECONFIG apiVersion: v1 clusters: - cluster:     server: ${yandex_kubernetes_cluster.zonal_k8s_cluster.master[0].external_v4_endpoint}     certificate-authority-data: ${base64encode(yandex_kubernetes_cluster.zonal_k8s_cluster.master[0].cluster_ca_certificate)}   name: kubernetes contexts: - context:     cluster: kubernetes     user: yc   name: ycmk8s current-context: ycmk8s users: - name: yc   user:     exec:       apiVersion: client.authentication.k8s.io\/v1beta1       command: yc       args:       - k8s       - create-token KUBECONFIG }  output \"kubeconfig\" {   value = local.kubeconfig }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f 50% \u044f\u0434\u0440\u0430 \u0438 <a href=\"https:\/\/cloud.yandex.ru\/docs\/compute\/pricing#prices-instance-resources\" rel=\"nofollow noopener noreferrer\">\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0448\u0438\u043d\u044b.<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">    resources {       ...       core_fraction = 50     }      scheduling_policy {       preemptible = true     }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421\u0435\u0442\u044c \u0438 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441.<\/strong><\/p>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u0435\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_vpc_network\" \"k8s-network\" {   name = \"k8s-network\" }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u0441\u0435\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_vpc_subnet\" \"k8s-subnet\" {   zone           = \"ru-central1-b\"   network_id     = yandex_vpc_network.k8s-network.id   v4_cidr_blocks = [\"10.5.0.0\/24\"]   depends_on = [     yandex_vpc_network.k8s-network,   ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"yandex_vpc_address\" \"addr\" {   name = \"static-ip\"   external_ipv4_address {     zone_id = \"ru-central1-b\"   } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>Jenkins \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0438\u0432\u0430\u0435\u043c c \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u043c\u043e\u0434\u0443\u043b\u044f helm_release.<\/strong> <\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <code>helm_release.tf<\/code>:<\/p>\n<p>  <\/p>\n<p><code>provider \"helm\"<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a kubernetes \u0434\u043b\u044f helm.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">provider \"helm\" {   kubernetes {     host                   = yandex_kubernetes_cluster.zonal_k8s_cluster.master[0].external_v4_endpoint     cluster_ca_certificate = yandex_kubernetes_cluster.zonal_k8s_cluster.master[0].cluster_ca_certificate     exec {       api_version = \"client.authentication.k8s.io\/v1beta1\"       args        = [\"k8s\", \"create-token\"]       command     = \"yc\"     }   } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u0435\u043c ingress-nginx.<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"helm_release\" \"ingress_nginx\" {   name       = \"ingress-nginx\"   repository = \"https:\/\/kubernetes.github.io\/ingress-nginx\"   chart      = \"ingress-nginx\"   version    = \"4.2.1\"   wait       = true   depends_on = [     yandex_kubernetes_node_group.k8s_node_group   ]   set {     name  = \"controller.service.loadBalancerIP\"     value = yandex_vpc_address.addr.external_ipv4_address[0].address   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 terraform \u043e\u043f\u0446\u0438\u0438 <code>--set key=value<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">  set {     name  = \"controller.service.loadBalancerIP\"     value = yandex_vpc_address.addr.external_ipv4_address[0].address   }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f <code>controller.service.loadBalancerIP<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441.<\/p>\n<p>  <\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c cert-manager \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 ingress-nginx.<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"helm_release\" \"cert-manager\" {   namespace        = \"cert-manager\"   create_namespace = true   name             = \"jetstack\"   repository       = \"https:\/\/charts.jetstack.io\"   chart            = \"cert-manager\"   version          = \"v1.9.1\"   wait             = true   depends_on = [     yandex_kubernetes_node_group.k8s_node_group   ]   set {     name  = \"installCRDs\"     value = true   } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c jenkins.<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">resource \"helm_release\" \"jenkins\" {   namespace        = \"jenkins\"   create_namespace = true   name             = \"jenkins\"   repository       = \"https:\/\/charts.jenkins.io\"   chart            = \"jenkins\"   wait             = true   version          = \"4.1.17\"   depends_on = [     yandex_kubernetes_node_group.k8s_node_group   ]   values = [     #file(\"${path.module}\/jenkins-values-google-login.yaml\")     yamlencode(local.jenkins_values_google_login)   ] }<\/code><\/pre>\n<p>  <\/p>\n<p>Jenkins helm \u0447\u0430\u0440\u0442\u0443 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c value.yaml \u0441 \u043d\u0430\u0448\u0438\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438. <\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c 2 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u044c value.yaml.<\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b\u0439 value.yaml \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">  values = [     file(\"${path.module}\/jenkins-values-google-login.yaml\")   ]<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c yamlencode \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0430 terraform \u043a\u043e\u0434\u0430 \u0432 yaml \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">  values = [     yamlencode(local.jenkins_values_google_login)   ]<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c terraform \u043a\u043e\u0434 \u0438\u0437 yaml \u043a\u043e\u0434\u0430?<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0435 \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0435 value.yaml, \u0430 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0435 \u0432 terraform \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">echo 'yamldecode(file(\"value.yaml\"))' | terraform console <\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 value.yaml \u0438\u043c\u0435\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">echo 'yamldecode(file(\"jenkins-values-google-login.yaml\"))' | terraform console <\/code><\/pre>\n<p>  <\/p>\n<p>\u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e yamlencode, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 yamlencode \u043a\u043e\u0434\u0430 \u0441\u0441\u044b\u043b\u0430\u044e\u0441\u044c \u043d\u0430 terraform \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e job \u043b\u0435\u0436\u0430\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0435 \u0432 <code>local.jenkins_values_google_login<\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">locals {   jenkins_values_google_login = {   \u0441\u044e\u0434\u0430   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0430\u0448\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\"hostName\"         = jenkins.mycompany.ru<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 terraform \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\"hostName\"         = \"${var.jenkins_dns_name}\"<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c <code>local.jenkins_values_google_login<\/code>.<\/strong> <\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0440\u043d\u0435 \u0441\u0442\u043e\u0438\u0442 <code>controller<\/code> \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0434\u0443\u0442 \u0432\u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 jenkins \u0438\u0437 \u043a\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f <a href=\"https:\/\/www.jenkins.io\/projects\/jcasc\/\" rel=\"nofollow noopener noreferrer\">jcasc<\/a>, <a href=\"https:\/\/github.com\/jenkinsci\/job-dsl-plugin\" rel=\"nofollow noopener noreferrer\">job-dsl<\/a>. \u041f\u0440\u0438\u043c\u0435\u0440\u044b jcasc <a href=\"https:\/\/github.com\/jenkinsci\/configuration-as-code-plugin\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/jenkinsci\/configuration-as-code-plugin<\/a><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">      \"JCasC\" = {         \"authorizationStrategy\" = &lt;&lt;-EOT         loggedInUsersCanDoAnything:           allowAnonymousRead: false         EOT<\/code><\/pre>\n<p>  <\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u2014 <a href=\"https:\/\/github.com\/jenkinsci\/configuration-as-code-plugin\/blob\/master\/demos\/global-matrix-auth\/README.md\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/jenkinsci\/configuration-as-code-plugin\/blob\/master\/demos\/global-matrix-auth\/README.md<\/a><\/p>\n<p>  <\/p>\n<p>\u0412 configScripts \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u043b\u043e\u043a EOT \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 jenkins. <code>systemMessage<\/code> \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">        \"configScripts\" = {           \"jenkins-configuration\" = &lt;&lt;-EOT           jenkins:             systemMessage: This Jenkins is configured and managed 'as code' by Managed Cloud team.           EOT<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b job:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">          \"job-config\" = yamlencode({             jobs = [               { script = file(\"${path.module}\/job1.groovy\") },               { script = file(\"${path.module}\/job2.groovy\") }             ]           })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a view:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">          jenkins:             views:               - all:                   name: \"all\"               - list:                   columns:                   - \"status\"                   - \"weather\"                   - \"jobName\"                   - \"lastSuccess\"                   - \"lastFailure\"                   - \"lastDuration\"                   - \"buildButton\"                   jobNames:                   - \"job1\"                   name: \"stage\"               - list:                   columns:                   - \"status\"                   - \"weather\"                   - \"jobName\"                   - \"lastSuccess\"                   - \"lastFailure\"                   - \"lastDuration\"                   - \"buildButton\"                   jobNames:                   - \"job2\"                   name: \"test\"             viewsTabBar: \"standard\"<\/code><\/pre>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0432\u0445\u043e\u0434\u0438\u0442\u044c \u0432 jenkins:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">        \"securityRealm\" = &lt;&lt;-EOT         googleOAuth2:           clientId: \"${var.clientId}\"           clientSecret: \"${var.clientSecret}\"           domain: \"${var.google_domain}\"         EOT<\/code><\/pre>\n<p>  <\/p>\n<p>\u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e googleOAuth2. \u041c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c local, ldap \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b jenkins:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">      \"additionalPlugins\" = [         \"google-login:1.6\",         \"job-dsl:1.81\",         \"allure-jenkins-plugin:2.30.2\",         \"ws-cleanup:0.42\",         \"build-timeout:1.21\",         \"timestamper:1.18\",         \"google-storage-plugin:1.5.6\",         \"permissive-script-security:0.7\",         \"ansicolor:1.0.2\",         \"google-oauth-plugin:1.0.6\",       ]<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Ingress:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">      \"ingress\" = {         \"annotations\" = {           \"cert-manager.io\/cluster-issuer\" = \"letsencrypt-prod\"         }         \"apiVersion\"       = \"networking.k8s.io\/v1\"         \"enabled\"          = true         \"hostName\"         = \"${var.jenkins_dns_name}\"         \"ingressClassName\" = \"nginx\"         \"tls\" = [           {             \"hosts\" = [               \"${var.jenkins_dns_name}\",             ]             \"secretName\" = \"jenkins-tls\"           },         ]       }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0442 letsencrypt, \u0442\u043e \u0432\u044b \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0435 cert-manager.io\/cluster-issuer.<\/p>\n<p>  <\/p>\n<p>\u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c javaOpts \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c Job-DSL \u0441\u043a\u0440\u0438\u043f\u0442\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">javaOpts: '-Dpermissive-script-security.enabled=true'<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 yaml \u0438 yamlencode \u0438\u0437 terraform \u043a\u043e\u0434\u0430.<\/strong><\/p>\n<p>  <\/p>\n<p>\u0427\u0435\u043c \u043f\u043b\u043e\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 yaml \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 value.yaml \u0434\u043b\u044f helm \u0447\u0430\u0440\u0442\u0430 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e yamlencode ?<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041e\u043d \u0434\u043b\u0438\u043d\u043d\u044b\u0439.<\/li>\n<li>\u0412 yaml \u043a\u043e\u0434\u0435 \u043d\u0435\u043b\u044c\u0437\u044f \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 job) \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b.<\/li>\n<li>\u0414\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043e\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0433\u043e value.yaml \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c templatefile. \u041c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u043b\u0438\u0448\u043d\u0435\u0435.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 JCasC.configScripts \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u043b\u043e\u043a \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0447\u0435\u0440\u0442\u044b (|) \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 Jenkins.<\/p>\n<p>  <\/p>\n<p>\u0412 Yaml \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0432\u0441\u0435 job \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">      job-config: |         jobs:           - script: >               pipelineJob('job1') {                 logRotator(120, -1, 1, -1)                 authenticationToken('secret')                 definition {                   cps {                     script(\"\"\"\\                       pipeline {                         agent any                         parameters {                             string(name: 'Variable', defaultValue: '', description: 'Variable', trim: true)                         }                         options {                           timestamps()                           ansiColor('xterm')                             timeout(time: 10, unit: 'MINUTES')                         }                         stages {                           stage ('build') {                             steps {                               cleanWs()                               echo \"hello job1\"                             }                           }                         }                       }\"\"\".stripIndent())                     sandbox()                   }                 }               }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0447\u0442\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 job, \u0442\u043e \u0432\u044b\u043d\u043e\u0441 \u0444\u0430\u0439\u043b\u0430 \u043b\u0443\u0447\u0448\u0435\u0435 \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435 \u0438 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">          \"job-config\" = yamlencode({             jobs = [               { script = file(\"${path.module}\/job1.groovy\") },               { script = file(\"${path.module}\/job2.groovy\") }             ]           })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>kind: ClusterIssuer<\/code> \u0432 Kubernetes.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c <code>kind: ClusterIssuer<\/code> \u043a\u0430\u043a <code>resource \"kubernetes_manifest\"<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u0441\u044f \u043a Kubernetes \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>provider \"kubernetes\"<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">cannot create REST client: no client config<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u044c <code>resource \"kubernetes_manifest\"<\/code> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u0441\u044b\u043b\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0435\u0441\u0440\u0443\u0441 \u2014 <a href=\"https:\/\/github.com\/hashicorp\/terraform-provider-kubernetes\/issues\/1380\" rel=\"nofollow noopener noreferrer\">https:\/\/github.com\/hashicorp\/terraform-provider-kubernetes\/issues\/1380<\/a><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b <code>ClusterIssuer.yaml.tpl<\/code> \u0438 \u0431\u0443\u0434\u0435\u043c \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 <code>templatefile<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0432\u0441\u0435\u0433\u043e 1 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e email_letsencrypt.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0448\u043b\u0438 \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/683844\/\"> https:\/\/habr.com\/ru\/post\/683844\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0417\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u0435 DNS \u0434\u043e\u043c\u0435\u043d\u0430 \u043d\u0430 reg.ru.<\/li>\n<li>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 DNS \u0437\u043e\u043d\u043e\u0439 \u0432 Yandex DNS c \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Kubernetes \u0432 Yandex Cloud.<\/li>\n<li>\u0420\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0443\u0435\u043c \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 IP \u0430\u0434\u0440\u0435\u0441.<\/li>\n<li>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Jenkins c \u043f\u043e\u043c\u043e\u0449\u044c\u044e terraform \u043c\u043e\u0434\u0443\u043b\u044f helm_release.<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 ClusterIssue(Issue) \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f letsencypt \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430.<\/li>\n<\/ul>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-337365","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337365","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=337365"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337365\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=337365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=337365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=337365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}