/terraform-yc-s3

Primary LanguageHCLMIT LicenseMIT

Object Storage (S3) Terraform module for Yandex.Cloud

Features

  • Create an service account with storage.admin permissions to create a Bucket.
  • Create a KMS key for encryption.
  • Create a HTTPS certificate for bucket.
  • Create the Bucket.
  • Apply the Bucket Policy.
  • Apply the Bucket Policy for Yandex Cloud Console.
  • Apply CORS rules.
  • Apply predefined acl or grant permissions.
  • Enable website hosting.
  • Enable versioning and object lock.
  • Enable objects lifecycle.
  • Enable logging.
  • Enable server-side encryption.

Service account

The module allows you to configure a service account using a storage_admin_service_account variable.
By default, the variable is set to an empty map. In this case, the module will automatically:

  • create a service account with the storage-admin name prefix
  • create a static access key for the account
  • grant storage.admin permissions to the created service account

You can specify the name of the service account to be created or change the name prefix.

You can also specify an existing service account with storage.admin permissions to create a bucket.

An existing service account must be in the same folder where the bucket will be created.

In this case, the module will NOT automatically create a service account, will NOT create a static access key, and will NOT be given storage.admin permissions to the service account.

Bucket policy

By default, bucket policy is not enabled.
You can set the policy in a policy variable. Bucket policy for the Yandex Cloud Console can only be set in a separate policy_console variable.
There are several use cases here:

  • If policy_console is enabled and policy is enabled, access will be configured both from Yandex Cloud Console and from other sources.

  • If policy is enabled, but policy_console is not enabled, then the policy will be set. Access to the bucket from Yandex Cloud Console will be denied.

  • If policy_console is enabled, but policy is not enabled, then only access from Yandex Cloud Console will be configured.

An allowing rule for the storage admin service account will be automatically added to the policy in all cases so that Terraform does not lose access to the bucket.

When policy_console is enabled but no principals are defined, then all principals can have access.

policy_console = {
  enabled = true
}

Server-side encryption

By default, bucket encryption is not enabled. The module allows you to enable bucket encryption using a server_side_encryption_configuration variable.

server_side_encryption_configuration = {
  enabled = true
}

In this case, a KMS key will be automatically generated, the service account will granted kms.keys.encrypterDecrypter permissions, and bucket encryption will be enabled.

If an existing service account is used, then kms.keys.encrypterDecrypter permissions will NOT be automatically granted to it.

The parameters of the KMS key that will be automatically generated can be defined in the sse_kms_key_configuration variable.

You can also specify an existing KMS key.

An existing KMS key must be in the same folder where the bucket will be created.

server_side_encryption_configuration = {
  enabled = true
  kms_master_key_id = "abjitgs2vjxxxxxxxxxx"
}

HTTPS certificate for bucket.

By default, https certificate for bucket is not enabled.
The module allows you to set an existing certificate from Yandex Cloud Certificate Manager.

https = {
  existing_certificate_id = "crtitgs2vjxxxxxxxxxx"
}

The module also allows you to create a managed Let's Encrypt certificate in Yandex Cloud Certificate Manager.
In this case, you must specify the list of certificate domains and the ID of the public Yandex Cloud DNS zone in which the corresponding records for validation will be created.

https = {
  certificate = {
    domains = ["one.example.com", "two.example.com"]
    public_dns_zone_id = "dnsitgs2vjxxxxxxxxxx"
  }
}

You can also define other certificate options such as name, name prefix, description, etc.

How to configure Terraform to use a module

  • Install YC CLI
  • Add environment variables for terraform auth in Yandex.Cloud
export YC_TOKEN=$(yc iam create-token)
export YC_CLOUD_ID=$(yc config get cloud-id)
export YC_FOLDER_ID=$(yc config get folder-id)
  • The module requires the mandatory configuration of the AWS provider, otherwise there will be an error.
    Create a provider.tf file with the following content:
provider "aws" {
  skip_region_validation      = true
  skip_credentials_validation = true
  skip_requesting_account_id  = true
}

Best practices

The recommended bucket configuration is shown in the example hardening

Examples

See examples section

Requirements

Name Version
terraform >= 1.3.0
aws 5.1.0
random 3.5.1
yandex 0.92

Providers

Name Version
aws 5.1.0
random 3.5.1
yandex 0.92

Modules

No modules.

Resources

Name Type
random_string.unique_id resource
yandex_cm_certificate.this resource
yandex_dns_recordset.this resource
yandex_iam_service_account.storage_admin resource
yandex_iam_service_account_static_access_key.storage_admin resource
yandex_kms_symmetric_key.this resource
yandex_resourcemanager_folder_iam_member.kms_storage_admin_sa resource
yandex_resourcemanager_folder_iam_member.storage_admin resource
yandex_storage_bucket.this resource
aws_iam_policy_document.this data source
yandex_client_config.client data source
yandex_iam_service_account.existing_account data source

Inputs

Name Description Type Default Required
acl (Optional) The predefined ACL to apply. Defaults to private. Conflicts with grant object.
To change ACL after creation, service account with storage.admin role should be used, though this role is not necessary to create a bucket with any ACL.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/acl#predefined-acls.
string null no
anonymous_access_flags (Optional) Object provides various access to objects.
For more information see https://cloud.yandex.com/en/docs/storage/operations/buckets/bucket-availability.

Configuration attributes:
list - (Optional) Allows to read objects in bucket anonymously.
read - (Optional) Allows to list object in bucket anonymously.
config_read - (Optional) Allows to list bucket configuration anonymously.

It will try to create bucket using IAM-token in provider config, not using access_key.
object({
list = optional(bool)
read = optional(bool)
config_read = optional(bool)
})
null no
bucket_name (Required) The name of the bucket. string null no
cors_rule (Optional) List of objets containing rules for Cross-Origin Resource Sharing.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/cors.

Configuration attributes:
allowed_headers - (Optional) Specifies which headers are allowed.
allowed_methods - (Required) Specifies which methods are allowed. Can be GET, PUT, POST, DELETE or HEAD (case sensitive).
allowed_origins - (Required) Specifies which origins are allowed.
expose_headers - (Optional) Specifies expose header in the response.
max_age_seconds - (Optional) Specifies time in seconds that browser can cache the response for a preflight request.
list(object({
allowed_headers = optional(set(string))
allowed_methods = set(string)
allowed_origins = set(string)
expose_headers = optional(set(string))
max_age_seconds = optional(number)
}))
[] no
default_storage_class (Optional) Storage class which is used for storing objects by default.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/storage-class.

Available values are: STANDARD, COLD, ICE. Default is STANDARD.
It will try to create bucket using IAM-token in provider block, not using access_key.
string "STANDARD" no
folder_id (Optional) The ID of the Yandex Cloud Folder that the resources belongs to.

Allows to create bucket in different folder.
It will try to create bucket using IAM-token in provider config, not using access_key.
If omitted, folder_id specified in provider config and access_key is used.
string null no
force_destroy (Optional) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are NOT recoverable. bool false no
grant (Optional) List of objects for an ACL policy grant. Conflicts with acl variable.
To manage grant argument, service account with storage.admin role should be used.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/acl#permissions-types.

Configuration attributes:
id - (Optional) Permission recipient ID.
type - (Required) Permission recipient type.
uri - (Optional) System group URI.
permissions - (Required) List of assigned permissions.
list(object({
id = optional(string)
type = string
uri = optional(string)
permissions = set(string)
}))
[] no
https (Optional) Object manages https certificate for bucket.
For more information see https://cloud.yandex.com/en/docs/storage/operations/hosting/certificate.

At least one of certificate, existing_certificate_id must be specified.

Configuration attributes:
existing_certificate_id - (Optional) Id of an existing certificate in Yandex Cloud Certificate Manager, that will be used for the bucket.
certificate - (Optional) Object allows to manage the parameters for generating a managed HTTPS certificate in Yandex Cloud Certificate Manager.

The certificate object supports the following attributes:
domains - (Required) Domains for this certificate.
public_dns_zone_id - (Required) The id of the DNS zone in which record set will reside.
dns_records_ttl - (Optional) The time-to-live of DNS record set (seconds). Default value is 300.
name - (Optional) Certificate name. Conflicts with name_prefix.
name_prefix - (Optional) Prefix of the certificate name. A unique certificate name will be generated using the prefix. Default value is s3-https-certificate. Conflicts with name.
description - (Optional) Certificate description.
labels - (Optional) Labels to assign to certificate.
deletion_protection - (Optional) Prevents certificate deletion. Default value is false.

It will try to create bucket using IAM-token in provider config, not using access_key.
object({
existing_certificate_id = optional(string)
certificate = optional(object({
domains = set(string)
public_dns_zone_id = string
dns_records_ttl = optional(number, 300)
name = optional(string)
name_prefix = optional(string)
description = optional(string, "Certificate for S3 static website.")
labels = optional(map(string))
deletion_protection = optional(bool, false)
}))
})
null no
lifecycle_rule (Optional) List of objects with configuration of object lifecycle management.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/lifecycles.

Configuration attributes:
enabled - (Required) Specifies lifecycle rule status.
id - (Optional) Unique identifier for the rule. Must be less than or equal to 255 characters in length.
prefix - (Optional) Object key prefix identifying one or more objects to which the rule applies.
abort_incomplete_multipart_upload_days - (Optional) Specifies the number of days after initiating a multipart upload when the multipart upload must be completed.
expiration - (Optional) Specifies a period in the object's expire.
transition - (Optional) Specifies a period in the object's transitions.
noncurrent_version_expiration - (Optional) Specifies when noncurrent object versions expire.
noncurrent_version_transition - (Optional) Specifies when noncurrent object versions transitions.

At least one of abort_incomplete_multipart_upload_days, expiration, transition, noncurrent_version_expiration, noncurrent_version_transition must be specified.

The expiration object supports the following attributes:
date - (Optional) Specifies the date after which you want the corresponding action to take effect.
days - (Optional) Specifies the number of days after object creation when the specific rule action takes effect.
expired_object_delete_marker - (Optional) On a versioned bucket (versioning-enabled or versioning-suspended bucket), you can add this element in the lifecycle configuration to direct Object Storage to delete expired object delete markers.

The transition object supports the following attributes:
date - (Optional) Specifies the date after which you want the corresponding action to take effect.
days - (Optional) Specifies the number of days after object creation when the specific rule action takes effect.
storage_class - (Required) Specifies the storage class to which you want the object to transition. Can only be COLD or STANDARD_IA.

The noncurrent_version_expiration object supports the following attributes:
days - (Required) Specifies the number of days noncurrent object versions expire.

The noncurrent_version_transition object supports the following attributes:
days - (Required) Specifies the number of days noncurrent object versions transition.
storage_class - (Required) Specifies the storage class to which you want the noncurrent object versions to transition. Can only be COLD or STANDARD_IA.
list(object({
enabled = bool
id = optional(string)
prefix = optional(string)
abort_incomplete_multipart_upload_days = optional(number)
expiration = optional(object({
date = optional(string)
days = optional(number)
expired_object_delete_marker = optional(bool)
}))
transition = optional(object({
date = optional(string)
days = optional(number)
storage_class = string
}))
noncurrent_version_expiration = optional(object({
days = number
}))
noncurrent_version_transition = optional(object({
days = number
storage_class = string
}))
}))
[] no
logging (Optional) Configuration of bucket logging.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/server-logs.

Configuration attributes:
target_bucket - (Required) The name of the bucket that will receive the log objects.
target_prefix - (Optional) To specify a key prefix for log objects.
object({
target_bucket = string
target_prefix = optional(string)
})
null no
max_size (Optional) The size of bucket, in bytes.
For more information see https://cloud.yandex.com/en/docs/storage/operations/buckets/limit-max-volume.

It will try to create bucket using IAM-token in provider block, not using access_key.
number null no
object_lock_configuration (Optional) Configuration of object lock management.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/object-lock.

Configuration attributes:
object_lock_enabled - (Optional) Enable object locking in a bucket. Require versioning to be enabled.
rule - (Optional) Specifies a default locking configuration for added objects. Require object_lock_enabled to be enabled.

The rule object consists of a nested default_retention object, which in turn supports the following attributes:
mode - (Required) Specifies a type of object lock. One of GOVERNANCE or COMPLIANCE (case sensitive).
days - (Optional) Specifies a retention period in days after uploading an object version. It must be a positive integer. You can't set it simultaneously with years.
years - (Optional) Specifies a retention period in years after uploading an object version. It must be a positive integer. You can't set it simultaneously with days.
object({
object_lock_enabled = optional(string, "Enabled")
rule = optional(object({
default_retention = object({
mode = string
days = optional(number)
years = optional(number)
})
}))
})
null no
policy (Optional) Object storage policy.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/policy.

NOTE: Bucket policy for Yandex Cloud Console is defined in a separate policy_console variable.

Configuration attributes:
enabled - (Required) Enable policy.
id - (Optional) General information about the policy. Some Yandex Cloud services require the uniqueness of this value.
version - (Optional) Access policy description version. Possible values is 2012-10-17.
statements - (Optional) List of bucket policy rules.

Objects in the statements supports the following attributes:
sid - (Optional) Rule ID.
effect - (Optional) Specifies whether the requested action is denied or allowed. Possible values: Allow, Deny. Defaults to Allow.
actions - (Required) Determines the action to be executed when the policy is triggered.
resources - (Required) Specifies the list of the resources that the action will be performed on. Prefix arn:aws:s3::: can be omitted from resource names.
principal - (Optional) ID of the recipient of the requested permission.
not_principal - (Optional) ID of the entity that will not receive the requested permission.
condition - (Optional) Condition that will be checked.

The principal object supports the following attributes:
type - (Required) Type of the entity. Possible values: *, CanonicalUser.
identifiers - (Required) List of IDs.

The not_principal object supports the following attributes:
type - (Required) Type of the entity. Possible value is CanonicalUser.
identifiers - (Required) List of IDs.

The condition object supports the following attributes:
type - (Required) Condition type.
key - (Required) Specifies the condition whose value will be checked.
values - (Required) List of values.
object({
enabled = bool
statements = optional(list(object({
sid = optional(string)
effect = optional(string)
actions = list(string)
resources = list(string)
principal = optional(object({
type = string
identifiers = list(string)
}))
not_principal = optional(object({
type = string
identifiers = list(string)
}))
condition = optional(object({
type = string
key = string
values = list(any)
}))
})))
})
{
"enabled": false
}
no
policy_console (Optional) Object storage policy for Yandex Cloud Console (Web UI).
For more information see https://cloud.yandex.com/en/docs/storage/concepts/policy#console-access.

Configuration attributes:
enabled - (Required) Enable policy for Yandex Cloud Console.
sid - (Optional) Rule ID.
effect - (Optional) Specifies whether the requested action is denied or allowed. Possible values: Allow, Deny. Defaults to Allow.
principal - (Optional) ID of the recipient of the requested permission.
not_principal - (Optional) ID of the entity that will not receive the requested permission.

The principal object supports the following attributes:
type - (Required) Type of the entity. Possible values: *, CanonicalUser.
identifiers - (Required) List of IDs.

The not_principal object supports the following attributes:
type - (Required) Type of the entity. Possible value is CanonicalUser.
identifiers - (Required) List of IDs.
object({
enabled = bool
sid = optional(string)
effect = optional(string)
principal = optional(object({
type = string
identifiers = list(string)
}))
not_principal = optional(object({
type = string
identifiers = list(string)
}))
})
{
"enabled": false
}
no
server_side_encryption_configuration (Optional) Object with configuration of server-side encryption for the bucket.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/encryption.

Configuration attributes:
enabled - (Required) Enable server-side encryption for the bucket.
sse_algorithm - (Required) The server-side encryption algorithm to use. Single valid value is aws:kms.
kms_master_key_id - (Optional) The KMS master key ID used for the server-side encryption. Allows to specify an existing KMS key for the server-side encryption. If omitted, the KMS key will be generated with parameters in the sse_kms_key_configuration variable.
object({
enabled = bool
sse_algorithm = optional(string, "aws:kms")
kms_master_key_id = optional(string)
})
{
"enabled": false
}
no
sse_kms_key_configuration (Optional) Object with a KMS key configuration.
For more information see https://cloud.yandex.com/en/docs/kms/concepts.

Only used for an auto-generated KMS key.
Will be ignored, if attribute kms_master_key_id is set in variable server_side_encryption_configuration.

Configuration attributes:
name - (Optional) Name of the key. If omitted, Terraform will assign a random, unique name. Conflicts with name_prefix.
name_prefix - (Optional) Prefix of the key name. A unique KMS key name will be generated using the prefix. Conflicts with name.
description - (Optional) Description of the key.
default_algorithm - (Optional) Encryption algorithm to be used with a new key version, generated with the next rotation. Default value is AES_256.
rotation_period - (Optional) Interval between automatic rotations. To disable automatic rotation, omit this parameter. Default value is 8760h (1 year).
deletion_protection - (Optional) Prevents key deletion. Default value is false.
object({
name = optional(string)
name_prefix = optional(string)
description = optional(string, "KMS key for Object storage server-side encryption.")
default_algorithm = optional(string, "AES_256")
rotation_period = optional(string, "8760h")
deletion_protection = optional(bool, false)
})
{} no
storage_admin_service_account (Optional) Allows to manage storage admin service account for the bucket.

Configuration attributes:
name - (Optional) The name of the service account to be generated. Conflicts with name_prefix and existing_account_id.
name_prefix - (Optional) Prefix of the service account name. A unique service account name will be generated using the prefix. Conflicts with name and existing_account_id.
description - (Optional) Description of the service account to be generated.
existing_account_id - (Optional) Allows to specify an existing service account ID to manage the bucket. The service account must have storage.admin permissions in the folder. Conflicts with name and name_prefix.
existing_account_access_key - (Optional) The access key of an existing service account to use when applying changes. If omitted, storage_access_key specified in provider config is used.
existing_account_secret_key - (Optional) The secret key of an existing service account to use when applying changes. If omitted, storage_secret_key specified in provider config is used.

By default, if the object is not set in the input variables of the module, a service account will be automatically generated with the name prefix storage-admin,
an access key will be automatically generated with random name, and the role of storage.admin will be assigned to the generated service account.
object({
name = optional(string)
name_prefix = optional(string)
description = optional(string, "Service account for Object storage admin.")
existing_account_id = optional(string)
existing_account_access_key = optional(string)
existing_account_secret_key = optional(string)
})
{} no
tags (Optional) Object for setting tags (or labels) for bucket.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/tags.
map(string) {} no
versioning (Optional) Enable versioning.
Once you version-enable a bucket, it can never return to an unversioned state. You can, however, suspend versioning on that bucket. Disabled by default.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/versioning.

Configuration attributes:
enabled - (Required) Enable versioning.
object({
enabled = bool
})
null no
website (Optional) Object for static web-site hosting or redirect configuration.
For more information see https://cloud.yandex.com/en/docs/storage/concepts/hosting.

Configuration attributes:
index_document - (Required, unless using redirect_all_requests_to) Storage returns this index document when requests are made to the root domain or any of the subfolders.
error_document - (Optional) An absolute path to the document to return in case of a 4XX error.
routing_rules - (Optional) List of json arrays containing routing rules describing redirect behavior and when redirects are applied. For more information see https://cloud.yandex.com/en/docs/storage/s3/api-ref/hosting/upload#request-scheme.
redirect_all_requests_to - (Optional) A hostname to redirect all website requests for this bucket to. Hostname can optionally be prefixed with a protocol (http:// or https://) to use when redirecting requests. The default is the protocol that is used in the original request. When set, other website configuration attributes will be skiped.

The routing_rules object supports the following attributes:
condition - (Optional) Object used for conditions that trigger the redirect. If a routing rule doesn't contain any conditions, all the requests are redirected.
redirect - (Required) Object for configure redirect a request to a different page, different host, or change the protocol.

The condition object supports the following attributes:
key_prefix_equals - (Optional) Sets the name prefix for the request-originating object.
http_error_code_returned_equals - (Optional) Specifies the error code that triggers a redirect.

The redirect object supports the following attributes:
protocol - (Optional) In the Location response header, a redirect indicates the protocol scheme (http or https) to be used.
host_name - (Optional) In the Location response header, a redirect indicates the host name to be used.
replace_key_prefix_with - (Optional) Specifies the name prefix of the object key replacing key_prefix_equals in the redirect request. Incompatible with replace_key_with.
replace_key_with - (Optional) Specifies the object key to be used in the Location header. Incompatible with replace_key_prefix_with.
http_redirect_code - (Optional) In the Location response header, a redirect specifies the HTTP redirect code. Possible values: any 3xx code.

The default value for index_document is used in case, when a website object is specified in the module input variables,
but the index_document or redirect_all_requests_to are not set.
object({
index_document = optional(string, "index.html")
error_document = optional(string)
routing_rules = optional(list(object({
condition = optional(object({
key_prefix_equals = optional(string)
http_error_code_returned_equals = optional(string)
}))
redirect = object({
protocol = optional(string)
host_name = optional(string)
replace_key_prefix_with = optional(string)
replace_key_with = optional(string)
http_redirect_code = optional(string)
})
})))
redirect_all_requests_to = optional(string)
})
null no

Outputs

Name Description
bucket_domain_name The bucket domain name.
bucket_name The name of the bucket.
cm_certificate_id Certificate ID of the generated HTTPS certificate in Yandex Cloud Certificate Manager
kms_master_key_id The KMS master key ID used for the server-side encryption.
storage_admin_access_key Static access key of the autogenerated Object storage admin service account.
storage_admin_secret_key Static secret key of the autogenerated Object storage admin service account.
storage_admin_service_account_id Service account ID of the Object storage admin.
website_domain The domain of the website endpoint.
website_endpoint The website endpoint.