Observação:
- Este tutorial requer acesso ao Oracle Cloud. Para se inscrever em uma conta gratuita, consulte Conceitos básicos do Oracle Cloud Infrastructure Free Tier.
- Ele usa valores de exemplo para credenciais, tenancy e compartimentos do Oracle Cloud Infrastructure. Ao concluir seu laboratório, substitua esses valores por valores específicos do seu ambiente de nuvem.
Ativar Bloqueio de Arquivo de Estado do Terraform com Backend Compatível com Amazon S3 no OCI
Introdução
No mundo dinâmico da computação em nuvem, a Infraestrutura como Código (IaC) surgiu como uma abordagem crucial para as organizações que buscam gerenciar efetivamente sua infraestrutura. A principal vantagem da IaC está em sua capacidade de promover consistência, automação, controle de versão e colaboração, tornando-a um elemento indispensável das estratégias de TI nativas da nuvem.
O Terraform se destaca como uma ferramenta IaC proeminente, ele armazena uma representação de seus objetos de infraestrutura e suas dependências em um arquivo de configuração chamado terraform.tfstate. Em um ambiente colaborativo em que vários membros da equipe gerenciam a infraestrutura de nuvem, armazenar o terraform.tfstate localmente se torna um desafio. Para resolver isso, o Terraform oferece um recurso chamado "Backend Remoto" para ativar o armazenamento do arquivo de estado em um local compartilhado. Alguns dos backends suportam bloqueio tfstate enquanto as operações plan ou apply são executadas para garantir a integridade dos dados e evitar conflitos.
Este tutorial se concentrará em como configurar o backend compatível com S3 e a API compatível com DynamoDB do ScyllaDB para ativar o bloqueio de arquivos de estado.
Objetivos
-
Implante ScyllaDB em uma instância usando o Docker Compose.
-
Configure o backend compatível com S3 do Terraform para suportar o bloqueio de arquivos
tfstate.
Pré-requisitos
-
Inscreva-se ou Acesse sua conta do Oracle Cloud.
-
Bucket do OCI com controle de versão ativado para armazenar o arquivo
terraform.tfstate. -
A versão do Terraform deve estar acima da versão 1.6.4 instalada.
Abordagem 1: Implantação Automática
Clique abaixo em Implantar no Oracle Cloud, informe os detalhes necessários e clique em Aplicar.
Abordagem 2: Implantação Manual
Tarefa 1: Configurar ScyllaDB e ativar a API compatível com DynamoDB
Criaremos uma instância baseada em ARM, instalaremos o Docker e configuraremos e executaremos o ScyllaDB.
Tarefa 1.1: Provisionar uma nova instância
-
Navegue até a página Instâncias na Console do OCI e clique em Criar Instância.
-
Informe os parâmetros de configuração necessários considerando as recomendações abaixo.
-
Imagem:
Oracle Linux 8 -
Forma:
VM.Standard.A1.Flex (1 OCPU, 6 GB RAM) -
VNIC Principal:
Public Subnet & Assign Public IPv4 Address(será usado para conectividade SSH)
Anote o endereço IP público e privado da instância.
-
Tarefa 1.2: Instalar o Docker
-
Conecte-se à Instância via SSH.
$ ssh opc@<public-ip-address-of-the-instance> -
Instale o Docker Engine, containerd e o Docker Compose.
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl start docker.service sudo systemctl enable docker.service sudo usermod -aG docker opc -
Reconecte a sessão SSH e valide a instalação bem-sucedida do Docker.
docker run hello-world # Unable to find image 'hello-world:latest' locally # latest: Pulling from library/hello-world # 70f5ac315c5a: Pull complete # Digest: sha256:3155e04f30ad5e4629fac67d6789f8809d74fea22d4e9a82f757d28cee79e0c5 # Status: Downloaded newer image for hello-world:latest # Hello from Docker! # This message shows that your installation appears to be working correctly.
Tarefa 1.3: Gerar Chave Secreta do Cliente
A chave secreta do cliente é necessária para acessar o OCI Object Storage usando a API Compatível com S3.
-
Navegue até a página de perfil do usuário na Console do OCI e selecione Chaves secretas do cliente.
-
Gere uma nova chave, copie o valor da chave secreta e clique em Fechar.
-
Copie o valor da chave de acesso (segunda coluna nesta lista com as chaves secretas do cliente).
Tarefa 1.4: Configurar e iniciar ScyllaDB
-
Crie o diretório de implantação
s3-lock.mkdir s3-lock cd s3-lock -
Crie o
.envusando o comando a seguir.AWS_ACCESS_KEY_ID='<ACCESS_KEY>' AWS_SECRET_ACCESS_KEY='<SECRET_KEY>' TF_STATE_TABLE='s3-locking-demo'Observação: o arquivo
.envserá usado pelo Docker para configurar ScyllaDB. -
Crie um arquivo
scylladb.Dockerfileno diretórioscylladbusando o comando a seguir.FROM scylladb/scylla:latest RUN echo "alternator_enforce_authorization: true" >> /etc/scylla/scylla.yaml ENTRYPOINT ["/docker-entrypoint.py"] -
Crie o arquivo
docker-compose.yamlno diretórios3-lockusando o comando a seguir.version: "3.3" services: scylladb: build: dockerfile: scylladb.Dockerfile context: ./scylladb image: "local-scylla:latest" container_name: "scylladb" restart: always command: ["--alternator-port=8000", "--alternator-write-isolation=always"] ports: - "8000:8000" - "9042:9042" scylladb-load-user: image: "scylladb/scylla:latest" container_name: "scylladb-load-user" depends_on: - scylladb entrypoint: /bin/bash -c "sleep 60 && echo loading cassandra keyspace && cqlsh scylladb -u cassandra -p cassandra \ -e \"INSERT INTO system_auth.roles (role,can_login,is_superuser,member_of,salted_hash) \ VALUES ('${AWS_ACCESS_KEY_ID}',True,False,null,'${AWS_SECRET_ACCESS_KEY}');\"" scylladb-create-table: image: "amazon/aws-cli" container_name: "create_table" depends_on: - scylladb env_file: .env entrypoint: /bin/sh -c "sleep 70 && aws dynamodb create-table --table-name ${TF_STATE_TABLE} \ --attribute-definitions AttributeName=LockID,AttributeType=S \ --key-schema AttributeName=LockID,KeyType=HASH --billing-mode=PAY_PER_REQUEST \ --region 'None' --endpoint-url=http://scylladb:8000" -
Revise a estrutura de diretório.
$ tree -a . . ├── docker-compose.yaml ├── .env └── scylladb └── scylladb.Dockerfile 1 directory, 3 files -
Inicie o serviço ScyllaDB.
docker compose up -d -
Permita conexões de entrada com a porta
8000.sudo firewall-cmd --add-port 8000/tcp --permanent -
Valide a conexão com ScyllaDB.
-
Instale os pacotes
python3-pipeboto3.sudo yum install -y python3-pip python3 -m pip install --user boto3 -
Crie o arquivo
script.pyusando o comando a seguir.import boto3 endpoint_url = 'http://localhost:8000' aws_access_key_id = '<ACCESS_KEY>' aws_secret_access_key = '<SECRET_KEY>' table_name = "s3-locking-demo" client = boto3.client('dynamodb', endpoint_url=endpoint_url, region_name="None", aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key) response = client.describe_table(TableName=table_name) print(response["Table"]["TableName"], response["Table"]["TableStatus"]) -
Execute o script usando o comando a seguir.
python3 script.py
Se a execução do script retornar
s3-locking-demo ACTIVE, ela estará funcionando conforme esperado. -
Tarefa 2: Configurar o Gateway de API do OCI para proteger conexões com a API compatível com ScyllaDB DynamoDB
Nesta tarefa, configuraremos o Gateway de API do OCI para aproveitar a criptografia TLS entre os usuários e o ScyllaDB.
Tarefa 2.1: Criação de um novo Gateway de API
-
Navegue até a página API Gateway na Console do OCI e clique em Criar Gateway.
-
Nome:
s3-locking -
Tipo:
public -
Rede: A mesma VCN e Sub-rede da instância ScyllaDB
-
Certificado:
Default (*.oci.oci-customer.com)
-
-
Anote o nome do host associado ao novo Gateway de API criado. O nome do host é exibido na guia Informações do gateway quando você clica no novo recurso do Gateway de API criado.
Por exemplo:
fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
Tarefa 2.2: Criação de uma nova implantação do Gateway de API
-
Criar uma nova implantação.
-
Clique no novo Gateway de API criado e, no menu esquerdo, clique em Implantações em Recursos.
-
Clique em Criar Implantação e crie uma nova implantação usando as informações a seguir.
-
Informações Básicas
-
Nome:
default -
Prefixo do caminho:
/
-
-
Autenticação: Sem Autenticação
-
Rotas
-
Caminho:
/{requested_path*} -
Métodos:
ANY -
Tipo de Backend:
HTTP -
URL:
http://<private_ip_address_of_the_instance>:8000/${request.path[requested_path]}
-
-
-
Vá para Políticas de Solicitação de Roteamento, Transformações de Cabeçalho e clique em Adicionar.
-
Ação:
Set -
Comportamento:
Overwrite -
Header Name:
Host -
Valores:
<API Gateway hostname>(Por exemplo:fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com)
-
-
Verifique os detalhes da nova implantação e clique em Criar.
-
-
Configure a lista de segurança de sub-rede para permitir conexão de entrada e saída com a porta
8000.-
Obtenha o bloco CIDR alocado para a sub-rede em uso, usando as etapas a seguir.
-
Identifique a lista de segurança associada à sub-rede usada pela instância usando as etapas a seguir.
-
Clique na lista de segurança padrão já associada à sub-rede e adicione as regras a seguir.
-
Entrada
-
CIDR de Origem:
0.0.0.0/0 -
Protocolo:
TCP -
Intervalo de Portas de Destino:
443 -
Descrição:
Ingress Access to the API Gateway
-
-
Entrada
-
CIDR de Origem:
<subnet CIDR> -
Protocolo:
TCP -
Faixa de Portas de Destino:
8000 -
Descrição:
Ingress connection to the ScyllaDB
-
-
Saída
-
CIDR de Destino:
<subnet CIDR> -
Protocolo:
TCP -
Faixa de Portas de Destino:
8000 -
Descrição:
Egress connection from the API Gateway backend to ScyllaDB
-
-
-
Tarefa 2.3: Validar a conexão com o ScyllaDB por meio do Gateway de API
-
Atualize o
endpoint_urlno arquivoscript.pypara usar o nome de host do Gateway de API. Por exemplo:endpoint_url = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com" -
Execute o script para testar a conexão com o ponto final público.
python3 script.py s3-locking-demo ACTIVE
Tarefa 3: Testar o bloqueio do arquivo terraform.tfstate ao usar a API Compatível com S3
Executaremos as etapas a seguir na instância em que queremos executar o código terraform.
-
Copie as linhas a seguir e crie o arquivo
main.tf.resource "null_resource" "hello_world" { provisioner "local-exec" { command = "echo Hello World" } provisioner "local-exec" { command = "echo 'sleeping for 30 seconds';sleep 30;echo 'done';" } triggers = { run_always = "${timestamp()}" } } -
Configure o backend S3.
terraform { backend "s3" { bucket = "<bucket-name>" # e.g.: bucket = "sample-bucket" region = "<oci-region>" # e.g.: region = "eu-frankfurt-1" skip_region_validation = true skip_credentials_validation = true skip_metadata_api_check = true # skip_requesting_account_id = true # skip_s3_checksum = true force_path_style = true # use_path_style = true # insecure = true # For best practice on how to set credentials access: https://developer.hashicorp.com/terraform/language/settings/backends/s3#access_key access_key = "<ACCESS_KEY>" secret_key = "<SECRET_KEY>" # endpoints = { # # To determine <objectostrage_namespace> access: https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/understandingnamespaces.htm # s3 = "https://<objectstorage_namespace>.compat.objectstorage.<oci-region>.oraclecloud.com" # # e.g.: s3 = https://axaxnpcrorw5.compat.objectstorage.eu-frankfurt-1.oraclecloud.com # # ScyllaDB TLS endpoint, configured using the API Gateway: # dynamodb = "https://<API_Gateway_hostname>" # # e.g.: dynamodb = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com" # } # ScyllaDB TLS endpoint, configured using the API Gateway: dynamodb_endpoint = "https://<API_Gateway_hostname>" # e.g.: dynamodb_endpoint = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com" key = "demo.tfstate" # the name of the tfstate file dynamodb_table = "s3-locking-demo" # the name of the table in the ScyllaDB } } -
Inicialize o diretório de trabalho com o comando
terraform init.$ terraform init Initializing the backend... Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... - Finding latest version of hashicorp/null... - Installing hashicorp/null v3.2.2... - Installed hashicorp/null v3.2.2 (signed by HashiCorp) Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! -
Execute
terraform apply.$ terraform apply 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: # null_resource.hello_world will be created + resource "null_resource" "hello_world" { + id = (known after apply) + triggers = { + "run_always" = (known after apply) } } Plan: 1 to add, 0 to change, 0 to destroy. 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 null_resource.hello_world: Creating... null_resource.hello_world: Provisioning with 'local-exec'... null_resource.hello_world (local-exec): Executing: ["/bin/sh" "-c" "echo Hello World"] null_resource.hello_world (local-exec): Hello World null_resource.hello_world: Provisioning with 'local-exec'... null_resource.hello_world (local-exec): Executing: ["/bin/sh" "-c" "echo 'sleeping for 30 seconds';sleep 30;echo 'done';"] null_resource.hello_world (local-exec): sleeping for 30 seconds null_resource.hello_world: Still creating... [10s elapsed] null_resource.hello_world: Still creating... [20s elapsed] null_resource.hello_world: Still creating... [30s elapsed] null_resource.hello_world (local-exec): done null_resource.hello_world: Creation complete after 30s [id=5722520729023050684] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. -
Teste o bloqueio do arquivo
terraform.tfstate. Se você tentar executarterraform planouterraform applydurante a execução da tarefa 3.4, sua solicitação será rejeitada.$ terraform apply ╷ │ Error: Error acquiring the state lock │ │ Error message: operation error DynamoDB: PutItem, https response error StatusCode: 400, RequestID: , │ ConditionalCheckFailedException: Failed condition. │ Lock Info: │ ID: 69309f13-d9fc-8c6b-9fbe-73639b340539 │ Path: sample-bucket/demo.tfstate │ Operation: OperationTypeApply │ Who: use │ Version: 1.6.4 │ Created: 2023-12-14 11:31:30.291168816 +0000 UTC │ Info: │ │ │ Terraform acquires a state lock to protect the state from being written │ by multiple users at the same time. Please resolve the issue above and try │ again. For most commands, you can disable locking with the "-lock=false" │ flag, but this is not recommended. -
Gerencie entradas nas tabelas ScyllaDB usando a API DynamoDB. Se você precisar listar as entradas na tabela DynamoDB ou remover manualmente as entradas, poderá adicionar as seguintes linhas no final do arquivo
script.py.scan_response = client.scan( TableName=table_name, ) print(scan_response) entry_to_delete = input("what is the LockID value you would like to delete? ") delete_response = client.delete_item( Key={ 'LockID': { 'S': f'{entry_to_delete}', }, }, TableName=table_name ) print(delete_response)Observação: mais recursos estão disponíveis neste script.
Links Relacionados
Agradecimentos
- Autor - Andrei Ilas (Arquiteto de Nuvem Principal)
Mais Recursos de Aprendizagem
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Enable Terraform State File Locking with Amazon S3 Compatible Backend in OCI
F90992-01
January 2024
Copyright © 2024, Oracle and/or its affiliates.