Note:
- Este tutorial requiere acceso a Oracle Cloud. Para registrarse en una cuenta gratuita, consulte Introducción a la cuenta gratuita de Oracle Cloud Infrastructure.
- Utiliza valores de ejemplo para credenciales, arrendamiento y compartimentos de Oracle Cloud Infrastructure. Al finalizar el laboratorio, sustituya estos valores por otros específicos del entorno en la nube.
Activación del bloqueo de archivos de Terraform State con backend compatible con Amazon S3 en OCI
Introducción
En el dinámico mundo de la computación en la nube, la infraestructura como código (IaC) se ha convertido en un enfoque crucial para las organizaciones que buscan gestionar eficazmente su infraestructura. La ventaja clave de IaC radica en su capacidad para promover la consistencia, la automatización, el control de versiones y la colaboración, lo que la convierte en un elemento indispensable de las estrategias de TI nativas de la nube.
Terraform se destaca como una herramienta IaC destacada, almacena una representación de los objetos de infraestructura y sus dependencias en un archivo de configuración denominado terraform.tfstate
. En un entorno de colaboración en el que varios miembros del equipo gestionan la infraestructura en la nube, almacenar terraform.tfstate
localmente se convierte en un reto. Para solucionarlo, Terraform ofrece una función denominada "backend remoto" para permitir el almacenamiento del archivo de estado en una ubicación compartida. Algunos de los backends admiten el bloqueo tfstate mientras se ejecutan las operaciones plan
o apply
para garantizar la integridad de los datos y evitar conflictos.
Este tutorial se centrará en cómo configurar el backend compatible con S3 y la API compatible con DynamoDB de ScyllaDB para activar el bloqueo de archivos de estado.
Objetivos
-
Despliegue ScyllaDB en una instancia mediante Docker Compose.
-
Configure el backend compatible con Terraform S3 para soportar el bloqueo de archivos
tfstate
.
Requisitos
-
Cubo de OCI con control de versiones activado para almacenar el archivo
terraform.tfstate
. -
La versión de Terraform debe estar por encima de la 1.6.4 instalada.
Enfoque 1: Despliegue automático
Haga clic en Desplegar en Oracle Cloud, introduzca los detalles necesarios y haga clic en Aplicar.
Enfoque 2: Despliegue manual
Tarea 1: Configurar ScyllaDB y activar la API compatible con DynamoDB
Crearemos una instancia basada en ARM, instalaremos Docker y configuraremos y ejecutaremos ScyllaDB.
Tarea 1.1: Aprovisionamiento de una nueva instancia
-
Navegue a la página Instancias de la consola de OCI y haga clic en Crear instancia.
-
Escriba los parámetros de configuración necesarios teniendo en cuenta las siguientes recomendaciones.
-
Imagen:
Oracle Linux 8
-
Unidad:
VM.Standard.A1.Flex (1 OCPU, 6 GB RAM)
-
VNIC principal:
Public Subnet & Assign Public IPv4 Address
(se utilizará para la conectividad SSH)
Anote la dirección IP pública y privada de la instancia.
-
Tarea 1.2: Instalación de Docker
-
Conéctese a la instancia mediante SSH.
$ ssh opc@<public-ip-address-of-the-instance>
-
Instale el motor de Docker, containerd y 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
-
Vuelva a conectar la sesión SSH y valide la instalación correcta de 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.
Tarea 1.3: Generar clave secreta de cliente
La clave secreta de cliente es necesaria para acceder a OCI Object Storage mediante la API compatible con S3.
-
Navegue a la página de perfil de usuario en la consola de OCI y seleccione Claves secretas de cliente.
-
Genere una nueva clave, copie el valor de la clave secreta y haga clic en Cerrar.
-
Copie el valor de la clave de acceso (la segunda columna de esta lista con las claves secretas del cliente).
Tarea 1.4: Configurar e iniciar ScyllaDB
-
Cree el directorio de despliegue
s3-lock
.mkdir s3-lock cd s3-lock
-
Cree
.env
con el siguiente comando.AWS_ACCESS_KEY_ID='<ACCESS_KEY>' AWS_SECRET_ACCESS_KEY='<SECRET_KEY>' TF_STATE_TABLE='s3-locking-demo'
Nota: El archivo
.env
lo utilizará la redacción de Docker para configurar ScyllaDB. -
Cree un archivo
scylladb.Dockerfile
en el directorioscylladb
mediante el siguiente comando.FROM scylladb/scylla:latest RUN echo "alternator_enforce_authorization: true" >> /etc/scylla/scylla.yaml ENTRYPOINT ["/docker-entrypoint.py"]
-
Cree el archivo
docker-compose.yaml
en el directorios3-lock
mediante el siguiente comando.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 la estructura de directorios.
$ tree -a . . ├── docker-compose.yaml ├── .env └── scylladb └── scylladb.Dockerfile 1 directory, 3 files
-
Inicie el servicio ScyllaDB.
docker compose up -d
-
Permitir conexiones entrantes al puerto
8000
.sudo firewall-cmd --add-port 8000/tcp --permanent
-
Valide la conexión a ScyllaDB.
-
Instale el paquete
python3-pip
yboto3
.sudo yum install -y python3-pip python3 -m pip install --user boto3
-
Cree el archivo
script.py
con el siguiente comando.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"])
-
Ejecute el script con el comando siguiente.
python3 script.py
Si la ejecución del script devuelve
s3-locking-demo ACTIVE
, funciona como se esperaba. -
Tarea 2: Configuración de OCI API Gateway para proteger las conexiones a la API compatible con ScyllaDB DynamoDB
En esta tarea, configuraremos OCI API Gateway para aprovechar el cifrado TLS entre los usuarios y ScyllaDB.
Tarea 2.1: Creación de una nueva instancia de API Gateway
-
Vaya a la página Gateway de API en la consola de OCI y haga clic en Crear gateway.
-
Nombre:
s3-locking
-
Tipo:
public
-
Red: la misma VCN y subred que la instancia ScyllaDB
-
Certificado:
Default (*.oci.oci-customer.com)
-
-
Anote el nombre de host asociado al nuevo gateway de API creado. El nombre de host se muestra en el separador Información de gateway al hacer clic en el nuevo recurso de gateway de API creado.
Por ejemplo:
fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
Tarea 2.2: Creación de un nuevo despliegue de API Gateway
-
Crear un nuevo despliegue.
-
Haga clic en el nuevo gateway de API creado y, en el menú de la izquierda, haga clic en Despliegues en Recursos.
-
Haga clic en Crear despliegue y cree un nuevo despliegue con la siguiente información.
-
Información básica
-
Nombre:
default
-
Prefijo de Ruta de Acceso:
/
-
-
Autenticación: sin autenticación
-
Rutas
-
Ruta:
/{requested_path*}
-
Métodos:
ANY
-
Tipo de backend:
HTTP
-
URL:
http://<private_ip_address_of_the_instance>:8000/${request.path[requested_path]}
-
-
-
Vaya a Políticas de solicitud de ruta, Transformaciones de cabecera y haga clic en Agregar.
-
Acción:
Set
-
Comportamiento:
Overwrite
-
Nombre de cabecera:
Host
-
Valores:
<API Gateway hostname>
(por ejemplo:fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
)
-
-
Revise los detalles del nuevo despliegue y haga clic en Crear.
-
-
Configure la lista de seguridad de subred para permitir la conexión de entrada y salida al puerto
8000
.-
Obtenga el bloque CIDR asignado a la subred en uso mediante los siguientes pasos.
-
Identifique la lista de seguridad asociada a la subred que utiliza la instancia mediante los siguientes pasos.
-
Haga clic en la lista de seguridad por defecto ya asociada a la subred y agregue las siguientes reglas.
-
Ingress
-
CIDR de origen:
0.0.0.0/0
-
Protocolo:
TCP
-
Rango de puertos de destino:
443
-
Descripción:
Ingress Access to the API Gateway
-
-
Ingress
-
Source CIDR:
<subnet CIDR>
-
Protocolo:
TCP
-
Destination Port Range:
8000
-
Descripción:
Ingress connection to the ScyllaDB
-
-
Salida
-
Destination CIDR:
<subnet CIDR>
-
Protocolo:
TCP
-
Destination Port Range:
8000
-
Descripción:
Egress connection from the API Gateway backend to ScyllaDB
-
-
-
Tarea 2.3: Validar la conexión a ScyllaDB mediante API Gateway
-
Actualice
endpoint_url
en el archivoscript.py
para utilizar el nombre de host de API Gateway. Por ejemplo:endpoint_url = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com"
-
Ejecute el script para probar la conexión al punto final público.
python3 script.py s3-locking-demo ACTIVE
Tarea 3: Probar el bloqueo de archivos terraform.tfstate
al utilizar la API compatible con S3
Ejecutaremos los siguientes pasos en la instancia en la que queremos ejecutar el código terraform.
-
Copie las siguientes líneas y cree el archivo
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 el 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 } }
-
Inicialice el directorio de trabajo con el 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!
-
Ejecute
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.
-
Pruebe el bloqueo de archivos
terraform.tfstate
. Si intenta ejecutarterraform plan
oterraform apply
durante la ejecución de la tarea 3.4, la solicitud se rechazará.$ 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.
-
Gestione entradas en las tablas ScyllaDB mediante la API DynamoDB. Si necesita mostrar las entradas de la tabla DynamoDB o eliminar manualmente las entradas, puede agregar las siguientes líneas al final del archivo
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)
Nota: Hay más funciones disponibles en este script.
Enlaces relacionados
Agradecimientos
- Autor: Andrei Ilas (Arquitecto principal de la nube)
Más recursos de aprendizaje
Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en Oracle Learning Explorer.
Para obtener documentación sobre el producto, visite 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.