ノート:
- このチュートリアルでは、Oracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントに例の値を使用します。演習を完了するときは、これらの値をクラウド環境に固有の値に置き換えます。
Enable Terraform State File Locking with Amazon S3 Compatible Backend in OCI
イントロダクション
クラウド・コンピューティングの動的な世界において、Infrastructure as Code(IaC)は、インフラストラクチャを効果的に管理しようとする組織にとって重要なアプローチとして出現しました。IaC’s key advantage lies in its ability to promote consistency, automation, version control, and collaboration, making it an indispensable element of cloud-native IT strategies.
Terraformは、著名なIaCツールとして際立っており、インフラストラクチャ・オブジェクトとその依存関係の描写をterraform.tfstate
という名前の構成ファイルに格納します。複数のチーム・メンバーがクラウド・インフラストラクチャを管理しているコラボレーション環境では、terraform.tfstate
をローカルに格納することは困難になります。これに対処するために、Terraformには「リモート・バックエンド」と呼ばれる機能があり、共有の場所に状態ファイルを格納できます。一部のバックエンドはtfstateロックをサポートしていますが、plan
またはapply
操作はデータの整合性を確保し、競合を回避するために実行されます。
This tutorial will focus on how to set up the S3 compatible backend and ScyllaDB’s DynamoDB-compatible API to enable state file locking.
目的
-
Docker Composeを使用してScyllaDBをインスタンスにデプロイします。
-
Configure Terraform S3 compatible backend to support
tfstate
file locking.
前提条件
-
OCI Bucket with versioning enabled to store the
terraform.tfstate
file. -
Terraformバージョンは、1.6.4インストール済より大きくする必要があります。
アプローチ1: 自動デプロイメント
下の「Oracle Cloudにデプロイ」をクリックし、必要な詳細を入力して「適用」をクリックします。
アプローチ2: 手動デプロイメント
Task 1: Setup ScyllaDB and enable DynamoDB-compatible API
We will create an ARM based instance, install Docker, and configure and run ScyllaDB.
タスク1.1: 新規インスタンスのプロビジョニング
-
Navigate to the Instances page in the OCI Console and click Create Instance.
-
次の推奨事項を考慮して、必要な構成パラメータを入力します。
-
イメージ:
Oracle Linux 8
-
シェイプ:
VM.Standard.A1.Flex (1 OCPU, 6 GB RAM)
-
Primary VNIC:
Public Subnet & Assign Public IPv4 Address
(will be used for SSH connectivity)
Note down the public and private IP address of the instance.
-
タスク1.2: Dockerのインストール
-
Connect to the Instance via SSH.
$ ssh opc@<public-ip-address-of-the-instance>
-
Docker Engine、containerdおよび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
-
Reconnect the SSH session and validate the successful installation of 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.
タスク1.3: 顧客秘密キーの生成
The customer secret key is required to access OCI Object Storage using the S3-Compatible API.
-
Navigate to your user profile page in the OCI Console and select Customer secret keys.
-
新しいキーを生成し、秘密キー値をコピーして、「閉じる」をクリックします。
-
アクセス・キー値(このリストの2番目の列と顧客秘密キー)をコピーします。
タスク1.4: ScyllaDBの構成および起動
-
デプロイメント・ディレクトリ
s3-lock
を作成します。mkdir s3-lock cd s3-lock
-
次のコマンドを使用して、
.env
を作成します。AWS_ACCESS_KEY_ID='<ACCESS_KEY>' AWS_SECRET_ACCESS_KEY='<SECRET_KEY>' TF_STATE_TABLE='s3-locking-demo'
ノート:
.env
ファイルは、Docker構成でScyllaDBを設定するために使用されます。 -
次のコマンドを使用して、
scylladb
ディレクトリにファイルscylladb.Dockerfile
を作成します。FROM scylladb/scylla:latest RUN echo "alternator_enforce_authorization: true" >> /etc/scylla/scylla.yaml ENTRYPOINT ["/docker-entrypoint.py"]
-
次のコマンドを使用して、
s3-lock
ディレクトリにdocker-compose.yaml
ファイルを作成します。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"
-
ディレクトリ構造を確認します。
$ tree -a . . ├── docker-compose.yaml ├── .env └── scylladb └── scylladb.Dockerfile 1 directory, 3 files
-
ScyllaDBサービスを開始します。
docker compose up -d
-
ポート
8000
へのインバウンド接続を許可します。sudo firewall-cmd --add-port 8000/tcp --permanent
-
ScyllaDBへの接続を検証します。
-
python3-pip
およびboto3
パッケージをインストールします。sudo yum install -y python3-pip python3 -m pip install --user boto3
-
次のコマンドを使用してファイル
script.py
を作成します。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"])
-
次のコマンドを使用して、スクリプトを実行します。
python3 script.py
スクリプト実行で
s3-locking-demo ACTIVE
が返された場合、期待どおりに動作しています。 -
Task 2: Configure OCI API Gateway to secure connections to the ScyllaDB DynamoDB-compatible API
In this task, we will configure OCI API Gateway to take advantage of the TLS encryption between the users and the ScyllaDB.
Task 2.1: Create a new API Gateway
-
Navigate to the API Gateway page in the OCI Console and click Create Gateway.
-
名前:
s3-locking
-
タイプ:
public
-
Network: Same VCN and Subnet as the ScyllaDB instance
-
証明書:
Default (*.oci.oci-customer.com)
-
-
Write down the hostname associated with the new created API Gateway. The hostname is displayed in the Gateway information tab when you click the new created API Gateway resource.
例:
fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
Task 2.2: Create a new API Gateway deployment
-
新しいデプロイメントを作成します。
-
Click the new created API Gateway, and in the left-side menu, click Deployments under Resources.
-
「デプロイメントの作成」をクリックし、次の情報を使用して新しいデプロイメントを作成します。
-
基本情報
-
名前:
default
-
パス接頭辞:
/
-
-
認証: 認証なし
-
ルート
-
パス:
/{requested_path*}
-
メソッド:
ANY
-
バックエンド・タイプ:
HTTP
-
URL:
http://<private_ip_address_of_the_instance>:8000/${request.path[requested_path]}
-
-
-
「ルート・リクエスト・ポリシー」、「ヘッダー変換」に移動し、「追加」をクリックします。
-
アクション:
Set
-
動作:
Overwrite
-
ヘッダー名:
Host
-
値:
<API Gateway hostname>
(例:fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com
)
-
-
新しいデプロイメントの詳細を確認し、「作成」をクリックします。
-
-
ポート
8000
へのイングレスおよびエグレス接続を許可するサブネット・セキュリティ・リストを設定します。-
Get the CIDR block allocated to the subnet in use, using the following steps.
-
次のステップを使用して、インスタンスで使用されるサブネットに関連付けられているセキュリティ・リストを識別します。
-
サブネットにすでに関連付けられているデフォルトのセキュリティ・リストをクリックし、次のルールを追加します。
-
イングレス
-
Source CIDR:
0.0.0.0/0
-
プロトコル:
TCP
-
宛先ポート範囲:
443
-
説明:
Ingress Access to the API Gateway
-
-
イングレス
-
Source CIDR:
<subnet CIDR>
-
プロトコル:
TCP
-
宛先ポート範囲:
8000
-
説明:
Ingress connection to the ScyllaDB
-
-
送信
-
Destination CIDR:
<subnet CIDR>
-
プロトコル:
TCP
-
宛先ポート範囲:
8000
-
説明:
Egress connection from the API Gateway backend to ScyllaDB
-
-
-
Task 2.3: Validate the connection to the ScyllaDB via the API Gateway
-
Update the
endpoint_url
in the filescript.py
to use the API Gateway hostname.たとえば:endpoint_url = "https://fj4etyuvz3s57jdsadsadsadsa.apigateway.eu-frankfurt-1.oci.customer-oci.com"
-
スクリプトを実行して、パブリック・エンドポイントへの接続をテストします。
python3 script.py s3-locking-demo ACTIVE
Task 3: Test terraform.tfstate
file locking when using S3-Compatible API
terraformコードを実行するインスタンスで、次のステップを実行します。
-
次の行をコピーして、ファイル
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 the S3 backend.
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 } }
-
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!
-
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.
-
terraform.tfstate
ファイルのロックをテストします。タスク3.4の実行中にterraform plan
またはterraform apply
を実行しようとすると、リクエストは拒否されます。$ 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.
-
Manage entries in the ScyllaDB tables using DynamoDB API.DynamoDB表のエントリをリストする必要がある場合、またはエントリを手動で削除する必要がある場合は、
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)
ノート: その他の機能は、このスクリプトで使用できます。
関連リンク
確認
- 著者 - Andrei Ilas (プリンシパル・クラウド・アーキテクト)
その他の学習リソース
docs.oracle.com/learnの他のラボをご覧いただくか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。
製品ドキュメントは、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.