Leaseweb Object Storage with Tofu
Guide on managing Leaseweb Object Storage with OpenTofu for S3-compatible buckets, including setup and lifecycle policies.
- tags
- #Tofu #Leaseweb #Terraform
- categories
- Infrastructure as Code
- published
- last updated
- reading time
- 3 minutes
Leasewebs Object Storage is one of many AWS S3 European alternatives. But, their dashboard only allows you to manage users and groups (with policies), everything else must be done on third party tools.

Leaseweb Object Storage Dashboard
Being S3 compatible, we can use OpenTofu (or Terraform) with the AWS provider to manage buckets and their respective access and lifecycle policies. Let’s check it then.
Provider
To setup the AWS provider, we need to set some configurations
So our provider configuration would be something like this:
1provider "aws" {
2 region = "nl-01"
3 access_key = var.s3_access_key
4 secret_key = var.s3_secret_key
5
6 # LSW implementation has no STS service
7 skip_credentials_validation = true
8 skip_requesting_account_id = true
9 # the AWS region is unknown to AWS hence skipping is needed.
10 skip_region_validation = true
11 endpoints {
12 s3 = "https://nl.object-storage.io"
13 }
14}
Resources
The bucket and respective policy creation aren’t any different than using AWS S3.
1resource "aws_s3_bucket" "this" {
2 bucket_prefix = "my-awesome-bucket-"
3}
4
5resource "aws_s3_bucket_policy" "this" {
6 bucket = aws_s3_bucket.this.id
7 policy = jsonencode({
8 Statement = [
9 {
10 Action = [
11 "s3:*"
12 ]
13 Effect = "Allow"
14 Principal = {
15 AWS = ["arn:aws:iam::00000000000000000000:user/my-user"]
16 }
17 Resource = ["arn:aws:s3:::${aws_s3_bucket.this.id}/*"]
18 }
19 ]
20 })
21}
The lifecycle policy is a bit different, we need to force transition_default_minimum_object_size to a empty string, otherwise it will fail to create the policy. This happens because LeaseWeb doesn’t have storage classes.
1resource "aws_s3_bucket_lifecycle_configuration" "this" {
2 bucket = aws_s3_bucket.this.id
3
4 # LSW needs this in order for tofu to work
5 transition_default_minimum_object_size = ""
6 rule {
7 id = "daily"
8 filter {
9 tag {
10 key = "retention"
11 value = "daily"
12 }
13 }
14
15 expiration {
16 days = 30
17 }
18
19 status = "Enabled"
20 }
21
22}
ARN
Because Leaseweb doesn’t support STS, we are unable to fetch the account id via Tofu. The way I got mine was by using S3 Manager.

S3 Manager object listing
Full example
1variable "s3_access_key" {
2 type = string
3 description = "S3 Access Key"
4 sensitive = true
5}
6
7variable "s3_secret_key" {
8 type = string
9 description = "S3 Secret Key"
10 sensitive = true
11}
12
13
14provider "aws" {
15 region = "nl-01"
16 access_key = var.s3_access_key
17 secret_key = var.s3_secret_key
18
19 # LSW implementation has no STS service
20 skip_credentials_validation = true
21 skip_requesting_account_id = true
22 # the AWS region is unknown to AWS hence skipping is needed.
23 skip_region_validation = true
24 endpoints {
25 s3 = "https://nl.object-storage.io"
26 }
27}
28
29resource "aws_s3_bucket" "this" {
30 bucket_prefix = "my-awesome-bucket-"
31}
32
33resource "aws_s3_bucket_policy" "this" {
34 bucket = aws_s3_bucket.this.id
35 policy = jsonencode({
36 Statement = [
37 {
38 Action = [
39 "s3:*"
40 ]
41 Effect = "Allow"
42 Principal = {
43 AWS = ["arn:aws:iam::00000000000000000000:user/my-user"]
44 }
45 Resource = ["arn:aws:s3:::${aws_s3_bucket.this.id}/*"]
46 }
47 ]
48 })
49}
50
51resource "aws_s3_bucket_lifecycle_configuration" "this" {
52 bucket = aws_s3_bucket.this.id
53
54 # LSW needs this in order for tofu to work
55 transition_default_minimum_object_size = ""
56 rule {
57 id = "daily"
58 filter {
59 tag {
60 key = "retention"
61 value = "daily"
62 }
63 }
64
65 expiration {
66 days = 30
67 }
68
69 status = "Enabled"
70 }
71
72}