Is there any terraform module to create folders within a Bucket (GCP) - google-cloud-platform

Is there any terraform module to create folders within a Bucket (GCP) ?
That is to say, I already know that with the module google_storage_bucket we can create GCS buckets in GCP.
But, is there any way to create folders within a bucket (GCP) by using terraform ?
thanks,

So a quick answer to your question is: yes. You can use Terraform to effectively make an empty "directory" in a bucket. Here's how:
resource "google_storage_bucket" "storage_bucket" {
name = "my-really-awesome-test-bucket"
location = "us-east4"
project = "my-really-awesome-project"
}
resource "google_storage_bucket_object" "content_folder" {
name = "empty_directory/"
content = "Not really a directory, but it's empty."
bucket = "${google_storage_bucket.storage_bucket.name}"
}
Notice that you're creating an object with a trailing / at the end of the name. The content goes nowhere and is just there because the module requires it. And now when you log into the GCP console, you'll see the empty "directory" in the bucket and you can upload new objects into it.
But there's some other stuff going on here that you should know. Google Cloud Storage uses a flat file-system. This means that when you upload an object to the service, you aren't really creating a directory structure and storing your file inside. Instead you are creating a single file with the entire path (ex: '/bucket_name/directory1/directory2/filename') as the entire file name. It's actually more technical than this, but that's a rough explanation.

Object storage is completely flat. There are no folders. When you see a folder in the UI or output from a command, it's just metadata describing how to show it to you.

Related

Terraform:- can we create " data source" in a seperate file like local or variables?

I want to seperate data form main code and use them in seperate file similar to local.tf or variables.tf, however even in the docs there is no reference.
use case
I am trying to create access logging for s3 bucket. Target bucket is not managed by s3 so I want to make sure that it exists before using it via data source
resource "aws_s3_bucket" "artifact" {
bucket = "jatin-123"
}
data "aws_s3_bucket" "selected" {
bucket = "bucket.test.com"
}
resource "aws_s3_bucket_logging" "artifacts_server_access_logs" {
for_each = local.env
bucket = data.aws_s3_bucket.selected.id
target_bucket = local.s3_artifact_access_logs_bucket_name
target_prefix = "${aws_s3_bucket.artifact[each.key].id}/"
}
Yes, you can have data sources in whatever file you want.
Terraform basically does not care about the file composition and their names and just lumps all .tf files in the same directory into one big blob.
Yes, of course, you can have. For organization purposes, you SHOULD use different files. When you have a simple project it's easy to check your code or even troubleshoot within a single file, but when you start to deploy more infrastructure will be a nightmare. So my advice is to start your "small" projects by splitting the through different files.
Here is my suggestion for you, regarding your example:
base.auto.tfvars
Here you can put variables that will be used along all the project.
E.g: region = us-east-1
project = web-appliance
s3.auto.tfvars
Variables that you will use in your s3 bucket
s3.tf
The code for S3 creation
datasource.tf
Here you will put all the datasources that you need in your project.
provider.tf
The configuration for your provider(s). In your example, aws provider
versions.tf
The versions of your providers

Google CLoud Transfer Job is creating one extra folder

I have created a Transfer Job to import some of my website's static resources to Google storage.
The job was supposed to import the data in a bucket named www.pretty-story.com.
It is importing from a tsv file located here.
For instance the first url is :
https://www.pretty-story.com/wp-includes/js/jquery/jquery.min.js
so I would have expected the job to create the folder structure starting with wp-includes.
But instead the job created this folder structure www.pretty-story.com\wp-includes\js\jquery.
Therefore the complete path (including my bucket name) is :
www.pretty-story.com\www.pretty-story.com\wp-includes\js\jquery.
How can I tell the data transfer job to use the bucket as first folder, instead of creating a subfolder with the same name ?
According to https://cloud.google.com/storage-transfer/docs/create-url-list:
When an object located at http(s)://[HOSTNAME]:[PORT]/[URL_PATH] is transferred to Cloud Storage, the name of the object in Cloud Storage is [HOSTNAME]/[URL_PATH].
You don't have an option to skip the [HOSTNAME]/ part of this, so what you are asking is not possible.
If the amount of data involved is reasonable, I recommend downloading it to a workstation and using gsutil to copy it into a bucket without the hostname prefix.

Upload object to a sub-directory in GCS bucket with Terraform

resource "google_storage_bucket_object" "picture" {
name = "butterfly01"
source = "/images/nature/garden-tiger-moth.jpg"
bucket = "image-store"
}
What I found in Terraform documentation is uploading an object to a bucket. But i dont see any documentation if we want to upload an object to a sub-directory in the Bucket. Is this possible? Any help would be appreciated. Thanks!
In Google Cloud Storage the directories don't exist: the forward slashes you see are part of the object name, not directories of folders.
In fact you cannot create empty folders in a gcs bucket.
If you want to write the file to gs://image-store/some/arbitrary/path/butterfly01, just add the forward slashes to the name of the object like this:
# Writes to gs://image-store/some/arbitrary/path/butterfly01
resource "google_storage_bucket_object" "picture" {
name = "some/arbitrary/path/butterfly01"
source = "/images/nature/garden-tiger-moth.jpg"
bucket = "image-store"
}
In GCS it is usually better to have a bucket for each purpose than a folder unless you need to have data partitioned in a folder to be used by Spark, Presto, etc.

How to get existing s3 bucket(subdirectory)?

For a CDK app I'm working on, trying to get an existing s3 bucket path and then copy few local files to that bucket. However, I get this error when the code tries to search for the bucket,
Failed to create resource. Command '['python3', '/var/task/aws', 's3', 'sync', '--delete', '/tmp/tmpew0gwu1w/contents', 's3://dir/subdir/']' returned non-zero exit status 1. using the code below,
If anyone could help me with this, that'd be great, not sure if the 'bucket-name' parameter can take bucket path or not.
Line of code is as follows,
IBucket byName = Bucket.fromBucketName(this, "bucket-name", "dir/subdir");
Note: If I try to copy the files to the main directory(dir in this case), it works fine.
The “path” is not part of the bucket name, it’s part of the object’s key (filename). Amazon S3 is an object store and doesn’t have directories like file systems do.
Technically, every object in a bucket is on the top level with the “path” being prefixed to its name.
So if you have something like s3://bucket/path/sub-path/file.txt, the bucket name is bucket and the object key (similar to a filename) is path/sub-path/file.txt with path/sub-path/ being the prefix.
When using the aws s3 sync CLI command, the prefix gets converted into a directory structure on the local drive, and vice versa.
For more details, please refer to How do I use folders in an S3 bucket?

How to create a new folder in S3 using AWS PowerShell

I have a bucket already created but I want to create new folders inside this bucket, not upload data or anything else, just create new folders. How can I do this ?
Thanks
AWS S3 doesn't really have a first class concept of a "folder" or "directory". S3 objects have prefixes, which are segmented by slashes, so there is certainly the appearance of folders, but it is not possible to have a truly empty directory structure.
However, their AWS Console user experience does present content as such, and provides a button to "Create Folder". When using that button, the UI provides the below message:
When you create a folder, S3 console creates an object with the above
name appended by suffix "/" and that object is displayed as a folder
in the S3 console.
You could try using PowerShell's Put Object API/cmdlet to create empty objects named per that instruction. For example, you could create a folder named "my-new-folder" by creating an object named "my-new-folder/".
S3 is object storage; it's not a regular file system. Generally speaking, there is no need to attempt to create folders. Simply upload objects, for example teams/east/falcons/logo.png.
If you really, really want to give the impression that there are folders then you can create zero-sized objects whose names ends in / (or whatever your preferred folder delimiter is). The simplest way to do this is with the AWS S3 console but any SDK will let you do it too (simply issue a PutObject with no body).
I was seaching for this myself and found this.
use -content where content = key then -file or -folder are not needed
$s3Path = "/folder/" + 'subfolder/'
Write-S3Object -BucketName $s3Bucket -Key $s3Path -Content $s3Path