# დასახელების კონვენცია

## ზოგადი კონვენცია

{% hint style="info" %}
არ არსებობს მიზეზი იმისა თუ რატომ არ უნდა გაყვეთ ამ დასახელების კონვენციას :)
{% endhint %}

{% hint style="info" %}
გაითვალისწინეთ რომ ღრუბლოვან რესურსებს (cloud resources) ხშირად აქვთ აკრძალვები დაშვებულ სახელებში. ზოგიერთი რესურსს მაგალითად არ შეუძლია შეიცავდეს - ს. ამ წიგნში მოყვანილი კონვენციები თავისთავად ეხება Terraform სახელებს.&#x20;
{% endhint %}

1. გამოიყენეთ `_` (underscore) `-` (dash) მაგიერ ყველგან (რესურსების დასახელებაში, მონაცემთა წყაროს სახელებში, ცვლადების სახელეში და ა.შ.).
2. უკეთესია გამოიყენოთ lowercase ასოები და ციფრები (მიუხედავად UTF-8 მხარდაჭერისა).

## რესურსისა და მონახემთა წყაროების არგუმენტები

1. ნუ გამოიყენებთ რესურსის ტიპს რესურსის სახელში (ნაწილობრივ თუ სრულად):

{% hint style="success" %}

```
`resource "aws_route_table" "public" {}`
```

{% endhint %}

{% hint style="danger" %}

```
`resource "aws_route_table" "public_route_table" {}`
```

{% endhint %}

{% hint style="danger" %}

```
`resource "aws_route_table" "public_aws_route_table" {}`
```

{% endhint %}

1. რესურსის სახელს უნდა ერქვას `this` იმ შემთხვევაში თუ არ არის მეტი აღწერითი და ზოგადი სახელი ხელმისაწვდომი, ან თუ რესურსის მოდული ქმნის მხოლოდ ერთ ასეთი ტიპის რესურსს (მაგალითად, [AWS VPC module](https://github.com/terraform-aws-modules/terraform-aws-vpc) -ში არის მხოლოდ ერთი  `aws_nat_gateway` ტიპის რესურსი და რამოდენიმე  type`aws_route_table` ტიპის რესურსი, ამიტომ `aws_nat_gateway` -ს უნდა დაერქვას `this` და `aws_route_table` -ს უნდა ჰქონდეს მეტი აღწერითი სახელები - როგორიცაა `private`, `public`, `database`).
2. დასახელებებში ყოველთვის გამოიყენეთ მხოლობითი არსებითი სახელები.
3. გამოიყენეთ `-` არგუმენტების მნიშვნელობებსა და იმ ადგილებში სადაც ეს მნიშვნელობები იქნება გამოტანილი საჯაროდ (მაგალითად, RDS instance-ის  DNS სახელში).
4. გამოიყენე არგუმენტი nclude argument `count` / `for_each` რესურსში ან მონაცემთა წყაროს ბლოკში პირველ არგუმენტად დასაწყისში და გამოყავით ახალი ხაზით.&#x20;
5. გამოიყენეთ არგუმენტი `tags,` თუ რესურსს აქვს ამის მხარდაჭერა, `depends_on` და `lifecycle` ბლოკებამდე, თუ არსებობს ამის საჭიროება. ყველა ბლოკი უნდა გამოიყოს ცარიელი ხაზით.&#x20;
6. `count` / `for_each` არგუმენტებში კონდიციების გამოყენებისას, უპირატესობა მიანიჭეთ boolean მნიშვნელობს ვიდრე `length` ან სხვა ტიპის expression-ებს.

## რესურსის(`resource`) კოდის მაგალითები

### `count` / `for_each`U-ის გამოყენება

{% hint style="success" %}
{% code title="main.tf" %}

```hcl
resource "aws_route_table" "public" {
  count = 2

  vpc_id = "vpc-12345678"
  # ... remaining arguments omitted
}

resource "aws_route_table" "private" {
  for_each = toset(["one", "two"])

  vpc_id = "vpc-12345678"
  # ... remaining arguments omitted
}
```

{% endcode %}
{% endhint %}

{% hint style="danger" %}
{% code title="main.tf" %}

```hcl
resource "aws_route_table" "public" {
  vpc_id = "vpc-12345678"
  count  = 2

  # ... remaining arguments omitted
}
```

{% endcode %}
{% endhint %}

### ტეგების (`tags`) განთავსება

{% hint style="success" %}
{% code title="main.tf" %}

```hcl
resource "aws_nat_gateway" "this" {
  count = 2

  allocation_id = "..."
  subnet_id     = "..."

  tags = {
    Name = "..."
  }

  depends_on = [aws_internet_gateway.this]

  lifecycle {
    create_before_destroy = true
  }
}   
```

{% endcode %}
{% endhint %}

{% hint style="danger" %}
{% code title="main.tf" %}

```hcl
resource "aws_nat_gateway" "this" {
  count = 2

  tags = "..."

  depends_on = [aws_internet_gateway.this]

  lifecycle {
    create_before_destroy = true
  }

  allocation_id = "..."
  subnet_id     = "..."
}
```

{% endcode %}
{% endhint %}

### კონდიციები `count`-ში

{% hint style="success" %}
{% code title="outputs.tf" %}

```hcl
resource "aws_nat_gateway" "that" {    # Best
  count = var.create_public_subnets ? 1 : 0
}

resource "aws_nat_gateway" "this" {    # Good
  count = length(var.public_subnets) > 0 ? 1 : 0
}
```

{% endcode %}
{% endhint %}

## ცვლადები

1. ნუ გამოიგონებთ ველოსიპედს რესურსის მოდულებში, გამოიყენეთ:  `name`, `description`, და `default` მნიშვნელობები ცვლადებისთვის ისე როგორც  "Argument Reference" სექციაში არის განსაზღვრული.
2. ცვლადებში ვალიდაციის მხარდაჭერა არის საკმაოდ შეზღუდული (მაგალითად არ აქვს წვდომა სხვა ცვლადებზე). ძირითად შემთხვევბში მიზანშეწონილია  გამოიყენოთ Plan-ი, რადგაც ვალიდაციის ოფცია ხშირ შემთხვევაში არის უშედეგო.
3. ცვლადის სახელებში გამოიყენეთ მრავლობითი ფორმა როდესაც მისი ტიპი არის `list(...)` ან `map(...)`.
4. ცვლადის ბლოკში დაიცავით ელემენტების შემდეგი მიმდევრობა: `description` , `type`, `default`, `validation`.
5. ყოველთვის გამოიყენეთ `description` ყველა ცვლადზე (სამომავლოდ აუცილებლად გამოგადგებათ)
6. უმჯობესია გამოიყენოთ მარტივი ცვლადის ტიპები  (`number`, `string`, `list(...)`, `map(...)`, `any`) ვიდრე სპეციფიური ტიპები როგორიცაა `object()` იმ შემთხვევაში თუ არ გჭირდებათ მკაცრი შეზღუდვები key-ებზე.
7. გამოიყენეთ სპეციფიური ცვლადის ტიპები როგორიცაა `map(map(string))` იმ შემთხვევაში თუ ყველა ელემენტს map-ზე ერთი და იგივე ცვლადის ტიპი (მაგალითად `string`) ან შესაძლოა დაკონვერტირდეს მასში (მაგალითად  `number` შესაძლოა დაკონვერტირდეს `string`-ში).
8. გამოიყენეთ ცვლადის ტიპი `any` რათა გამოტოვოთ ვალიდაცია როდესაც კონკრეტულ შრეზე ან როდესაც რამოდენიმე ცვლადის ტიპი უნდა იქნას მხარდაჭერილი.
9. მნიშვნელობა(Value) `{}` ზოგჯერ არის map ტიპისა მაგრამ ხანდახან არის  object ტიპის. გამოიყენეთ `tomap(...)` რათა შექმნა map იმ შემთხვევაში თუ შეზღუდულია object-ის შექმნა.

## Outputs

Make outputs consistent and understandable outside of its scope (when a user is using a module it should be obvious what type and attribute of the value it returns).

1. The name of output should describe the property it contains and be less free-form than you would normally want.
2. Good structure for the name of output looks like `{name}_{type}_{attribute}` , where:
   1. `{name}` is a resource or data source name without a provider prefix. `{name}` for `aws_subnet` is `subnet`, for`aws_vpc` it is `vpc`.
   2. `{type}` is a type of a resource sources
   3. `{attribute}` is an attribute returned by the output
   4. [See examples](#code-examples-of-output).
3. If the output is returning a value with interpolation functions and multiple resources, `{name}` and `{type}` there should be as generic as possible (`this` as prefix should be omitted). [See example](#code-examples-of-output).
4. If the returned value is a list it should have a plural name. [See example](#use-plural-name-if-the-returning-value-is-a-list).
5. Always include `description` for all outputs even if you think it is obvious.
6. Avoid setting `sensitive` argument unless you fully control usage of this output in all places in all modules.
7. Prefer `try()` (available since Terraform 0.13) over `element(concat(...))` (legacy approach for the version before 0.13)

### `output`კოდის მაგალითი

დააბრუნეთ security group მხოლოდ ერთი ID:

{% hint style="success" %}
{% code title="outputs.tf" %}

```hcl
output "security_group_id" {
  description = "The ID of the security group"
  value       = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
}
```

{% endcode %}
{% endhint %}

ერთი და იმავე ტიპის მრავალი რესურსის არსებობისას, `this` უნდა იყოს გამოტოვებული Output სახელით:

{% hint style="danger" %}
{% code title="outputs.tf" %}

```hcl
output "this_security_group_id" {
  description = "The ID of the security group"
  value       = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
}
```

{% endcode %}
{% endhint %}

### გამოიყენეთ მრავლობითი სახელი, თუ დაბრუნებული მნიშვნელობა არის სია

{% hint style="success" %}
{% code title="outputs.tf" %}

```hcl
output "rds_cluster_instance_endpoints" {
  description = "A list of all cluster instance endpoints"
  value       = aws_rds_cluster_instance.this.*.endpoint
}
```

{% endcode %}
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.terraform-best-practices.com/ka/naming.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
