Nota
- Questa esercitazione richiede l'accesso a Oracle Cloud. Per iscriverti a un account gratuito, consulta Inizia a utilizzare Oracle Cloud Infrastructure Free Tier.
- Utilizza valori di esempio per le credenziali, la tenancy e i compartimenti di Oracle Cloud Infrastructure. Al termine del laboratorio, sostituisci questi valori con quelli specifici del tuo ambiente cloud.
Abilita il blocco dei file di stato Terraform con il backend compatibile con Amazon S3 in OCI
Introduzione
Nel mondo dinamico del cloud computing, Infrastructure as Code (IaC) è emerso come un approccio cruciale per le organizzazioni che cercano di gestire efficacemente la propria infrastruttura. Il vantaggio principale di IaC risiede nella sua capacità di promuovere coerenza, automazione, controllo delle versioni e collaborazione, rendendolo un elemento indispensabile delle strategie IT cloud native.
Terraform si distingue come un importante strumento IaC e memorizza una rappresentazione degli oggetti dell'infrastruttura e delle relative dipendenze in un file di configurazione denominato terraform.tfstate
. In un ambiente collaborativo in cui più membri del team gestiscono l'infrastruttura cloud, memorizzare localmente terraform.tfstate
diventa difficile. Per risolvere questo problema, Terraform offre una funzione denominata "Backend remoto" per abilitare la memorizzazione del file di stato in una posizione condivisa. Alcuni backend supportano il blocco dello stato tf mentre vengono eseguite le operazioni plan
o apply
per garantire l'integrità dei dati e prevenire i conflitti.
Questa esercitazione si concentrerà su come impostare il backend compatibile con S3 e l'API compatibile con DynamoDB di ScyllaDB per abilitare il blocco dei file di stato.
Obiettivi
-
Distribuire ScyllaDB in un'istanza utilizzando Docker Compose.
-
Configurare il backend compatibile con Terraform S3 per supportare il blocco dei file
tfstate
.
Prerequisiti
-
Bucket OCI con controllo delle versioni abilitato per memorizzare il file
terraform.tfstate
. -
La versione di Terraform deve essere successiva alla installazione della versione 1.6.4.
Approccio 1: Distribuzione automatica
Fare clic di seguito su Distribuisci in Oracle Cloud, immettere i dettagli richiesti e fare clic su Applica.
Approccio 2: Distribuzione manuale
Task 1: impostare ScyllaDB e abilitare l'API compatibile con DynamoDB
Creeremo un'istanza basata su ARM, installeremo Docker ed eseguiremo ScyllaDB.
Task 1.1: eseguire il provisioning di una nuova istanza
-
Passare alla pagina Istanze in OCI Console e fare clic su Crea istanza.
-
Immettere i parametri di configurazione richiesti considerando i suggerimenti riportati di seguito.
-
Immagine:
Oracle Linux 8
-
Forma:
VM.Standard.A1.Flex (1 OCPU, 6 GB RAM)
-
VNIC primaria:
Public Subnet & Assign Public IPv4 Address
(verrà utilizzata per la connettività SSH)
Prendere nota dell'indirizzo IP pubblico e privato dell'istanza.
-
Task 1.2: Installa Docker
-
Connettersi all'istanza tramite SSH.
$ ssh opc@<public-ip-address-of-the-instance>
-
Installa Docker Engine, containerd e 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
-
Riconnettere la sessione SSH e convalidare l'installazione riuscita del 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.
Task 1.3: Genera chiave segreta cliente
La chiave segreta del cliente è necessaria per accedere allo storage degli oggetti OCI utilizzando l'API compatibile S3.
-
Passare alla pagina del profilo utente in OCI Console e selezionare Chiavi segrete cliente.
-
Generare una nuova chiave, copiare il valore della chiave segreta e fare clic su Chiudi.
-
Copiare il valore della chiave di accesso (seconda colonna in questo elenco con le chiavi segrete del cliente).
Task 1.4: configurare e avviare ScyllaDB
-
Creare la directory di distribuzione
s3-lock
.mkdir s3-lock cd s3-lock
-
Creare
.env
utilizzando il comando seguente.AWS_ACCESS_KEY_ID='<ACCESS_KEY>' AWS_SECRET_ACCESS_KEY='<SECRET_KEY>' TF_STATE_TABLE='s3-locking-demo'
Nota: il file
.env
verrà utilizzato dalla composizione Docker per impostare ScyllaDB. -
Creare un file
scylladb.Dockerfile
nella directoryscylladb
utilizzando il comando seguente.FROM scylladb/scylla:latest RUN echo "alternator_enforce_authorization: true" >> /etc/scylla/scylla.yaml ENTRYPOINT ["/docker-entrypoint.py"]
-
Creare il file
docker-compose.yaml
nella directorys3-lock
utilizzando il comando seguente.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"
-
Esaminare la struttura della directory.
$ tree -a . . ├── docker-compose.yaml ├── .env └── scylladb └── scylladb.Dockerfile 1 directory, 3 files
-
Avviare il servizio ScyllaDB.
docker compose up -d
-
Consentire connessioni in entrata alla porta
8000
.sudo firewall-cmd --add-port 8000/tcp --permanent
-
Convalida la connessione a ScyllaDB.
-
Installare i pacchetti
python3-pip
eboto3
.sudo yum install -y python3-pip python3 -m pip install --user boto3
-
Creare il file
script.py
utilizzando il comando seguente.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"])
-
Eseguire lo script utilizzando il comando seguente.
python3 script.py
Se l'esecuzione dello script restituisce
s3-locking-demo ACTIVE
, funziona come previsto. -
Task 2: configurare il gateway API OCI per proteggere le connessioni all'API compatibile con ScyllaDB DynamoDB
In questo task, configureremo OCI API Gateway per sfruttare la cifratura TLS tra gli utenti e ScyllaDB.
Task 2.1: creare un nuovo gateway API
-
Passare alla pagina Gateway API nella console OCI e fare clic su Crea gateway.
-
Nome:
s3-locking
-
Tipo:
public
-
Rete: la stessa VCN e la stessa subnet dell'istanza ScyllaDB
-
Certificato:
Default (*.oci.oci-customer.com)
-
-
Prendere nota del nome host associato al nuovo gateway API creato. Il nome host viene visualizzato nella scheda Informazioni gateway quando si fa clic sulla nuova risorsa gateway API creata.
Ad esempio:
fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
Task 2.2: Creare una nuova distribuzione del gateway API
-
Consente di creare una nuova distribuzione.
-
Fare clic sul nuovo gateway API creato e nel menu a sinistra fare clic su Distribuzioni in Risorse.
-
Fare clic su Crea distribuzione e creare una nuova distribuzione utilizzando le informazioni riportate di seguito.
-
Informazioni di base
-
Nome:
default
-
Prefisso percorso:
/
-
-
Autenticazione: nessuna autenticazione
-
Instradamenti
-
Percorso:
/{requested_path*}
-
Metodi:
ANY
-
Tipo di backend:
HTTP
-
URL:
http://<private_ip_address_of_the_instance>:8000/${request.path[requested_path]}
-
-
-
Andare a Criteri richiesta percorso, Trasformazioni intestazione e fare clic su Aggiungi.
-
Azione:
Set
-
Comportamento:
Overwrite
-
Nome intestazione:
Host
-
Valori:
<API Gateway hostname>
(ad esempio:fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
)
-
-
Rivedere i dettagli della nuova distribuzione e fare clic su Crea.
-
-
Impostare la lista di sicurezza della subnet per consentire la connessione in entrata e in uscita alla porta
8000
.-
Recupera il blocco CIDR allocato alla subnet in uso, utilizzando i passi riportati di seguito.
-
Identificare la lista di sicurezza associata alla subnet utilizzata dall'istanza utilizzando i passi riportati di seguito.
-
Fare clic sulla lista di sicurezza predefinita già associata alla subnet e aggiungere le regole riportate di seguito.
-
Ingresso
-
CIDR di origine:
0.0.0.0/0
-
Protocollo:
TCP
-
Intervallo di porte di destinazione:
443
-
Descrizione:
Ingress Access to the API Gateway
-
-
Ingresso
-
CIDR di origine:
<subnet CIDR>
-
Protocollo:
TCP
-
Intervallo di porte di destinazione:
8000
-
Descrizione:
Ingress connection to the ScyllaDB
-
-
Uscita
-
CIDR di destinazione:
<subnet CIDR>
-
Protocollo:
TCP
-
Intervallo di porte di destinazione:
8000
-
Descrizione:
Egress connection from the API Gateway backend to ScyllaDB
-
-
-
Task 2.3: convalidare la connessione a ScyllaDB tramite il gateway API
-
Aggiornare
endpoint_url
nel filescript.py
per utilizzare il nome host del gateway API. Ad esempio:endpoint_url = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com"
-
Eseguire lo script per eseguire il test della connessione all'endpoint pubblico.
python3 script.py s3-locking-demo ACTIVE
Task 3: eseguire il test del blocco del file terraform.tfstate
quando si utilizza l'API compatibile con S3
Verrà eseguita la seguente procedura sull'istanza in cui si desidera eseguire il codice terraform.
-
Copiare le righe seguenti e creare il file
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()}" } }
-
Configurare il 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 } }
-
Inizializzare la directory di lavoro con il 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!
-
Eseguire
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.
-
Eseguire il test del blocco del file
terraform.tfstate
. Se si tenta di eseguireterraform plan
oterraform apply
durante l'esecuzione del task 3.4, la richiesta verrà rifiutata.$ 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.
-
Gestire le voci nelle tabelle ScyllaDB utilizzando l'API DynamoDB. Se è necessario elencare le voci nella tabella DynamoDB o rimuovere manualmente le voci, è possibile aggiungere le righe seguenti alla fine del file
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: ulteriori funzioni sono disponibili in questo script.
Collegamenti correlati
Conferme
- Autore - Andrei Ilas (Principal Cloud Architect)
Altre risorse di apprendimento
Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare Oracle Learning Explorer.
Per la documentazione del prodotto, visitare 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.