Criando Configurações

Usando o Terraform, você pode descrever recursos de infraestrutura utilizando o formato HCL (HashiCorp Configuration Language) nos arquivos de configuração do Terraform (consulte Configuration Syntax). Os arquivos de configuração do Terraform podem usar um destes dois formatos: linguagem específica do domínio Terraform (formato HashiCorp Configuration Language [HCL]), que é o método recomendado, ou o formato JSON, se os arquivos precisarem ser legíveis por máquina. Arquivos de configuração que usam o formato HCL terminam com a extensão de arquivo .tf; aqueles que usam o formato JSON terminam com a extensão de arquivo .tf.json. O formato Terraform é legível por seres humanos, enquanto o formato JSON é legível por máquina.

Use as configurações do Terraform para definir recursos do OCI (Oracle Cloud Infrastructure), definições de variáveis, origens de dados e muito mais. O Terraform, então, converterá as configurações do OCI em um conjunto de chamadas de API em pontos finais de API do OCI. O segredo para criar a configuração do Terraform é entender como abstrair a infraestrutura desejada conceitualmente na sintaxe de configuração do Terraform.

Importante

Embora a API do Oracle Cloud Infrastructure use minúsculas concatenadas (camelCase) amplamente, o Terraform não suporta esse formato em arquivos de configuração. Por esse motivo, nas configurações você vê sublinhados em vez de letras maiúsculas como separadores. Por exemplo, onde a API usa availabilityDomain, a configuração do Terraform usa availability_domain.

Requisitos do Arquivo de Configuração

Os arquivos de configuração do Terraform (.tf) têm requisitos específicos, dependendo dos componentes definidos no arquivo. Por exemplo, você pode ter o provedor Terraform definido em um arquivo (provider.tf), as variáveis definidas em outro arquivo (variables.tf) e as origens de dados definidas ainda em um terceiro arquivo.

Observação

Para obter exemplo de arquivos de configuração, consulte Exemplos do Provedor Oracle Cloud Infrastructure do Terraform.

Definições do Provedor

O exemplo a seguir de uso da sintaxe do Terraform ilustra os requisitos de uma definição do provedor Terraform do OCI e também mostra definições de variáveis associadas. A definição do provedor depende de variáveis para que o próprio arquivo de configuração não contenha dados confidenciais. A inclusão de dados confidenciais cria um risco de segurança durante a troca ou o compartilhamento de arquivos de configuração.

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

provider "oci" {
   tenancy_ocid = "${var.tenancy_ocid}"
   user_ocid = "${var.user_ocid}"
   fingerprint = "${var.fingerprint}"
   private_key_path = "${var.private_key_path}"
   region = "${var.region}"
}

O atributo region especifica a região geográfica na qual os recursos do provedor são criados. Para alcançar várias regiões em uma única configuração, você simplesmente cria uma definição de provedor para cada região e as diferencia usando um alias de provedor, conforme mostrado no exemplo a seguir. Observe que somente um provedor, chamado "oci", é definido, e também a definição do provedor oci é informada duas vezes, uma para a região us-phoenix-1 (com o alias "phx") e outra para a região us-ashburn-1 (com o alias "iad").

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "compartment_ocid" {}

provider "oci" {
   region = "us-phoenix-1"
   alias = "phx"
   tenancy_ocid = "${var.tenancy_ocid}"
   user_ocid = "${var.user_ocid}"
   fingerprint = "${var.fingerprint}"
   private_key_path = "${var.private_key_path}"
}

provider "oci" {
   region = "us-ashburn-1"
   alias = "iad"
   tenancy_ocid = "${var.tenancy_ocid}"
   user_ocid = "${var.user_ocid}"
   fingerprint = "${var.fingerprint}"
   private_key_path = "${var.private_key_path}"
}

Para obter mais informações, consulte Configuração do Provedor.

Definições de Variáveis

Variáveis no Terraform representam parâmetros para os módulos do Terraform. Em definições de variável, cada bloco configura uma única variável de entrada, e cada definição pode utilizar qualquer um ou todos os três argumentos opcionais:

  • type (opcional): define o tipo de variável como um dos três valores permitidos: string, list e map. Se esse argumento não for usado, o tipo de variável será inferido com base em default. Se nenhum valor default for informado, o tipo será assumido como string.
  • default (opcional): define o valor padrão da variável. Se nenhum valor padrão for fornecido, o chamador deverá fornecer um valor, ou o Terraform gerará um erro.
  • description (opcional): uma descrição legível por seres humanos da variável.

Veja a seguir exemplos de várias definições de variáveis. Algumas definições incluem parâmetros opcionais.

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "AD" {
    default     = "1"
    description = "Availability Domain"
}

variable "CPUCoreCount" {
    default = "2"
    type    = string
}

Para obter mais informações, consulte Variáveis de Entrada.

Configuração de Saída

As variáveis de saída fornecem um meio de suportar consultas do usuário final do Terraform. Isso permite que os usuários extraiam dados significativos do volume potencialmente grande de dados associados a uma infraestrutura complexa. Por exemplo, você pode estar interessado somente em alguns valores importantes em determinado momento. Portanto, você define variáveis de saída que permitem extrair exatamente as informações necessárias.

Veja a seguir um exemplo simples no qual apenas algumas variáveis de saída (endereços IP da instância e IDs de volume de inicialização) são definidas:

# Output the private and public IPs of the instance
output "InstancePrivateIPs" {
value = ["${oci_core_instance.TFInstance.*.private_ip}"]
}

output "InstancePublicIPs" {
value = ["${oci_core_instance.TFInstance.*.public_ip}"]
}

# Output the boot volume IDs of the instance
output "BootVolumeIDs" {
  value = ["${oci_core_instance.TFInstance.*.boot_volume_id}"]
}

Para obter mais informações, consulte Variáveis de Saída. Consulte também Configuração de Saída.

Recursos

Recursos são componentes do seu Oracle Cloud Infrastructure. Esses recursos incluem tudo, desde componentes de nível inferior, como servidores físicos e virtuais, a componentes de nível superior, como provedores de e-mail e banco de dados, o seu registro DNS.

Cuidado

Os arquivos de estado do Terraform contêm todos os atributos de recursos especificados como parte dos arquivos de configuração. Se você gerenciar dados sigilosos com o Terraform, como senhas de banco de dados ou de usuário ou chaves privadas de instâncias, trate o próprio arquivo de estado como dados sigilosos. Consulte Dados Sigilosos no Estado para obter mais informações.

Declarando Recursos

Veja a seguir um exemplo simples de uma definição de recurso que ilustra a estrutura básica.

resource "oci_core_virtual_network" "vcn1" {
   cidr_block = "10.0.0.0/16"
   dns_label = "vcn1"
   compartment_id = "${var.compartment_ocid}"
   display_name = "vcn1"
}

A declaração de recurso na primeira linha do exemplo usa a palavra-chave "resource" e usa dois parâmetros, type e name ("oci_core_virtual_network" e "vcn1" no exemplo). A configuração do recurso permanece dentro do bloco de código.

Para obter mais informações, consulte Configuração de Recursos.

Dependências de Recursos

Quando um recurso faz referência a outro dentro de seu bloco de recursos, o Terraform infere automaticamente a dependência do recurso principal no recurso referenciado. Um recurso também pode depender de recursos que não são explicitamente referenciados em seu bloco. Por exemplo, talvez você precise criar políticas para um recurso antes de criar o próprio recurso.

Para definir dependências ocultas que o Terraform não pode inferir automaticamente, você pode usar o metaargumento depends_on no bloco de recursos.

O exemplo a seguir cria os recursos oci_datascience_notebook_session e oci_identity_policy para políticas relacionadas. A adição do metaargumento depends_on ao recurso oci_datascience_notebook_session garante que as políticas sejam criadas primeiro:

resource "oci_datascience_notebook_session" "ods-notebook-session" {
  count = var.enable_ods ? var.ods_number_of_notebooks : 0
 
  #Required
  compartment_id = var.compartment_ocid
  notebook_session_configuration_details {
   #Required
   shape = var.ods_compute_shape
   subnet_id = local.private_subnet_id
 
  #Optional
  block_storage_size_in_gbs = var.ods_storage_size
  }
  project_id = oci_datascience_project.ods-project[0].id
 
  display_name = "${var.ods_notebook_name}-${count.index}"

  depends_on = ["oci_identity_policy.ods-policy"]
 }

resource "oci_identity_policy" "ods-policy" {
  provider = oci.home
  compartment_id = var.compartment_ocid
  description = "Data Science Policies"
  name = var.ods_policy_name
  statements = var.enable_vault ? concat(local.ods_policies , local.vault_policies) : local.ods_policies
 }

Fazendo Referência a Recursos em Outra Pilha (Exportando Valores de Saída de Pilha)

Você pode fazer referência a recursos que existem em outras pilhas. A origem de dados do Terraform remote_state permite ler variáveis de saída dos arquivos de estado.

Por exemplo, ao criar uma configuração do Terraform para um novo aplicativo web, você pode fazer com que o aplicativo web use a sub-rede criada anteriormente com base na pilha de rede, contanto que os valores de sub-rede necessários tenham sido gerados no arquivo de estado da pilha de rede. Na configuração do Terraform para o seu novo aplicativo Web, faça o seguinte:

  • Obtenha o arquivo de estado da pilha de rede existente para o contexto da configuração atual do Terraform.

    A extração do arquivo de estado exporta efetivamente os valores de saída da pilha. Para obter instruções sobre como extrair o arquivo de estado no Resource Manager, consulte Obtendo um Arquivo de Estado da Pilha.

  • Carregue o arquivo de estado extraído para uma origem de dados dos arquivos de estado remoto.

  • Preencha a origem de dados de sub-rede na sua configuração atual com valores das variáveis de saída relevantes do arquivo de estado referenciado.

  • Como opção, imprima as informações de identificação da origem de dados preenchidas para confirmar os valores esperados.

Observação

Além das permissões necessárias para as operações do Gerenciador de Recursos, você precisará de permissões apropriadas para os tipos de recursos que está referenciando no compartimento em questão. Neste exemplo, você precisa de permissões de leitura para recursos de rede no compartimento onde eles estão localizados.

A parte da configuração do Terraform a seguir faz referência a uma sub-rede em outra pilha:

# The following example assumes that the source stack (defined by `stack_id`) has output a value named `subnet_id`
# Terraform v0.12 is assumed

variable "stack_id" {}

# Pull the state file of the existing Resource Manager stack (the network stack) into this context
data "oci_resourcemanager_stack_tf_state" "stack1_tf_state" {
  stack_id   = "${var.stack_id}"
  local_path = "stack1.tfstate"
}

# Load the pulled state file into a remote state data source
data "terraform_remote_state" "external_stack_remote_state" {
  backend = "local"
  config = {
    path = "${data.oci_resourcemanager_stack_tf_state.stack1_tf_state.local_path}"
  }
}

# Populate a data source in this configuration using a value from the remote state data source
data "oci_core_subnet" "subnet1" {
  subnet_id = "${data.terraform_remote_state.external_stack_remote_state.outputs.subnet_id}"
}

# Print the values of the populated data source
output "print-subnet1" {
  value = "${data.oci_core_subnet.subnet1}"
}

Origens de Dados

As origens de dados representam views somente para leitura da infraestrutura existente destinada a um uso semântico nas configurações do Terraform. Este é um exemplo simples de uma configuração de origem de dados para ilustrar a estrutura básica:

# Gets a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
  compartment_id = "${var.tenancy_ocid}"
}

# Get DB node list
data "oci_database_db_nodes" "DBNodeList" {
  compartment_id = "${var.compartment_ocid}"
  db_system_id = "${oci_database_db_system.TFDBNode.id}"
}

# Get DB node details
data "oci_database_db_node" "DBNodeDetails" {
  db_node_id = "${lookup(data.oci_database_db_nodes.DBNodeList.db_nodes[0], "id")}"
}

# Gets the OCID of the first (default) vNIC
data "oci_core_vnic" "DBNodeVnic" {
  vnic_id = "${data.oci_database_db_node.DBNodeDetails.vnic_id}"
}

Para obter mais informações, consulte Configuração da Origem de Dados.

Filtrando Origens de Dados

As origens de dados que retornam listas de recursos suportam a semântica de filtragem. Para usar um filtro, inclua esse bloco na sua definição de origem de dados:

filter {
    name = ""
    values = [""]
}

O valor name corresponde ao nome qualificado da propriedade para filtragem e as listas values podem conter um ou mais valores a serem filtrados.

As propriedades aninhadas e os elementos de mapa podem ser tratados qualificando o nome da propriedade com o nome da propriedade principal. O exemplo r1 fornecerá todas as instâncias que tiverem a imagem source_type. O exemplo r2 fornecerá todas as instâncias que contiverem uma tag definida com o valor "42" para a chave CostCenter no namespace Operations.

data "oci_core_instances" "r1" {
  ...
  filter {
    name = "source_details.source_type"
    values = ["image"]
  }
}

data "oci_core_instances" "r2" {
  ...
  filter {
    name = "defined_tags.Operations.CostCenter"
    values = ["42"]
  }
}

Diversos values funcionam como filtro do tipo OR. No exemplo de forma a seguir, a origem de dados resultante conteria as formas de VM Padrão 1.1 e Padrão 1.2:

data "oci_core_shape" "t" {
  ...
  filter {
    name = "name"
    values = ["VM.Standard1.1", "VM.Standard1.2"]
  }
}

Vários blocos de filtros podem ser compostos para formar comparações do tipo AND. O exemplo a seguir retornará uma origem de dados contendo instâncias em execução no primeiro AD de uma região:

data "oci_core_instances" "s" {
    ...
  filter {
    name = "availability_domain"
    values = ["\\w*-AD-1"]
    regex = true
  }

  filter {
    name = "state"
    values = ["RUNNING"]
  }
}

Como mostrado acima, os filtros também podem empregar expressões regulares. A definição de regex = true faz com que cada item na lista values seja tratado como expressão regular. As barras invertidas em strings de caracteres especiais de expressão regular precisam ter escape com outra barra, mostrada acima como a primeira \ antes de \w em "\\w*-AD-1".

Observação

O drill em listas de objetos estruturados não é suportado no momento. Se essas propriedades forem direcionadas, nenhum resultado será retornado da origem de dados.

Serviço Functions

O Terraform oferece várias funções incorporadas que você pode usar em seus arquivos de configuração. Essas funções permitem que você modifique strings, execute cálculos com valores numéricos, gerencie coleções e muito mais.

Para obter mais informações, consulte Funções.