Skip to content

aws-ia/terraform-aws-storagegateway

Repository files navigation

AWS Storage Gateway Terraform module

This repository contains Terraform code which creates resources required to run Storage Gateway (https://aws.amazon.com/storagegateway/) in AWS and on premises.

AWS Storage Gateway is available in 4 types:

  • Amazon S3 File Gateway (FILE_S3)
  • Amazon FSx File Gateway (FILE_FSX_SMB)
  • Tape Gateway (VTL)
  • Volume Gateway (CACHED, STORED)

The module requires a Gateway type to be declared. The default is configured to FILE_S3 as an example. For more details regarding the Storage Gateway types and their respective arguments can be found here.

Usage with VMware S3 File Gateway module

Prerequisites

  • The VMware module requires the vSphere provider to be setup with a service account user name and password that has the necessary permissions in vCenter to create a VM. This is found in the settings.tf file.
provider "vsphere" {
  allow_unverified_ssl = var.allow_unverified_ssl
  vsphere_server       = var.vsphere_server
  user                 = var.vsphere_user
  password             = var.vsphere_password
}

Note that var.allow_unverified_ssl is a boolean that can be set to true to disable SSL certificate verification. This should be used with care as it could allow an attacker to intercept your authentication token. The default value is set to false but can be changed to true for testing purposes only.

The module also requires connectivity to your vCenter server. Therefore, it needs to be deployed from a virtual machine that can reach the vCenter APIs. You may also Terraform Cloud Agents if you use already use Terraform Cloud. This allows the modules to be deployed remotely.

module "vsphere" {
  source     = "aws-ia/storagegateway/aws//modules/vmware-sgw"
  datastore  = var.datastore
  datacenter = var.datacenter
  network    = var.network
  cluster    = var.cluster
  host       = var.host
  name       = "my-s3fgw"
}

The virtual machine IP address needs to be passed to next module as the gateway IP address. In addition, the module also requires domain user name and passwords for the storage gateway to join the domain.

Note that in order to protect sensitive data such as domain credentials etc., certain variables are marked as sensitive. It is general best practice to never store credentials and secrets in git repositories. For more information about protecting sensitive variables refer to this documentation. Also as a best practice consider the use of services such as AWS Secrets Manager, Hashicorp Vault or Terraform Cloud to dynamically inject your secrets.

Also note that the domain password despite being a sensitive variable can be still found in the Terraform state file. Follow this guidance to protect state file from unauthorized access.

module "sgw" {
  source             = "aws-ia/storagegateway/aws//modules/aws-sgw"
  name               = "my-sgw"
  gateway_ip_address = module.vsphere.vm_ip
  join_smb_domain    = true
  domain_name        = var.domain_name
  domain_username    = var.domain_username
  domain_password    = var.domain_password
  domain_controllers = var.domain_controllers
  gateway_type       = "FILE_S3"       
}

Note that variable "join_smb_domain" is set to true by default and therefore optional. To create a Storage Gateway that is not joined to the domain set "join_smb_domain" to false.

Example :

module "sgw" {
  source             = "aws-ia/storagegateway/aws//modules/aws-sgw"
  name               = "my-sgw"
  gateway_ip_address = module.vsphere.vm_ip
  join_smb_domain    = false
  gateway_type       = "FILE_S3"       
}

Refer to to the S3 NFS Storage Gateway example for VMware for an end to end example: s3-nfs-filegateway-vmware

Usage with Amazon EC2 File Gateway module

module "ec2_sgw" {
  source     = "aws-ia/storagegateway/aws//modules/ec2-sgw"
  vpc_id               = "vpc-abcdef123456"
  subnet_id            = "subnet-abcdef123456"
  name                 = "my-storage-gateway"
  availability_zone    = data.aws_availability_zones.available.names[0]
  aws_region           = var.aws_region
}

Once the EC2 Gateway is deployed, the public IP address of the EC2 instance needs to be passed to next module as the gateway IP address.

module "sgw" {
  depends_on         = [module.ec2_sgw]
  source             = "aws-ia/storagegateway/aws//modules/aws-sgw"
  gateway_name       = "my-storage-gateway"
  gateway_ip_address = module.ec2_sgw.public_ip
  join_smb_domain    = false
  gateway_type       = "FILE_S3"
}

Setting up S3 buckets for S3 File Gateway

module "s3_bucket" {
  source                   = "terraform-aws-modules/s3-bucket/aws"
  version                  = ">=3.5.0"
  bucket                   = "bucket-name"
  control_object_ownership = true
  object_ownership         = "BucketOwnerEnforced"
  block_public_acls        = true
  block_public_policy      = true
  ignore_public_acls       = true
  restrict_public_buckets  = true

  server_side_encryption_configuration = {
    rule = {
      apply_server_side_encryption_by_default = {
        kms_master_key_id = "kms_key_id"
        sse_algorithm     = "aws:kms"
      }
    }
  }
  logging = {
    target_bucket = "log-delivery-bucket"
    target_prefix = "log/"
  }

  versioning = {
    enabled = false
  }
}

Note that versioning is set to false by default for the S3 bucket for the file share for Storage Gateway. Enabling S3 Versioning can increase storage costs within Amazon S3. Please see here for further information on whether S3 Versioning is right for your workload.

Setting up SMB File shares

module "smb_share" {
  source        = "aws-ia/storagegateway/aws//modules/s3-smb-share"
  share_name    = "smb_share_name"
  gateway_arn   = module.sgw.storage_gateway.arn
  bucket_arn    = module.s3_bucket.s3_bucket_arn
  role_arn      = "iam-role-for-sgw-s3"
  log_group_arn = "log-group-arn"
}

Setting up NFS File shares

module "nfs_share" {
  source        = "aws-ia/storagegateway/aws//modules/s3-nfs-share"
  share_name    = "nfs_share_name"
  gateway_arn   = module.sgw.storage_gateway.arn
  bucket_arn    = module.s3_bucket.s3_bucket_arn
  role_arn      = "iam-role-for-sgw-s3"
  log_group_arn = "log-group-arn"
  client_list   = ["10.0.0.0/24","10.0.1.0/24"]
}

The examples also includes "aws_kms_key" resource block to create a KMS key. For production deployments, you should pass in a key policy that restricts the use of the key based on your access requirements. Refer to this link for information.

Networking Considerations

Storage Gateway interface VPC Endpoint configuration for EC2 Gateway

The Storage Gateway module allows you to optionally create an interface VPC Endpoint for Storage Gateway by setting create_vpc_endpoint = true. You can use this endpoint to activate your gateway and to transfer data to AWS storage services without communicating over the public internet.

Example with VPC endpoint configuration:

module "ec2_sgw" {
  source     = "aws-ia/storagegateway/aws//modules/ec2-sgw"
  gateway_name                       = random_pet.name.id
  gateway_ip_address                 = module.ec2_sgw.public_ip
  join_smb_domain                    = false
  gateway_type                       = "FILE_S3"
  create_vpc_endpoint                = true
  create_vpc_endpoint_security_group = true #if false define vpc_endpoint_security_group_id
  vpc_id                             = module.vpc.vpc_id
  vpc_endpoint_subnet_ids            = module.vpc.private_subnets
  gateway_private_ip_address         = module.ec2_sgw.private_ip
}

A security group is also needed for the VPC Endpoint. In the above example, the module handles creation of the security group. However, you may use the vpc_endpoint_security_group_id variable to associate an existing Security group with the VPC endpoint. Please see this documentation which shows the Security Group requirements for Storage Gateway VPC endpoint. In this module, the security groups are already pre-configured with the required rules with the private IP address of the storage gateway. The configuration can be found in the file sg.tf file.

S3 gateway VPC Endpoint configuration

We recommend you configure create a separate VPC endpoint for Amazon S3 File Gateway to transfer data through the VPC rather than a NAT Gateway or NAT Instances. This allows for optimized and private routing to S3 and lower cost. In the S3 NFS File gateway example's main.tf, we have created a Gateway VPC endpoint as shown below.

resource "aws_vpc_endpoint" "s3" {
  vpc_id          = module.vpc.vpc_id
  service_name    = "com.amazonaws.${var.aws_region}.s3"
  route_table_ids = module.vpc.private_route_table_ids
}

Storage Gateway Security Group Configuration for EC2 Gateway

You can optionally create the security group and the required rules required for your gateway by setting create_security_group = true. You can also limit access to range of ingress CIDR blocks in your network from where you require access to the storage gateway by modifying ingress_cidr_blocks attributes as shown in the example below.

The module also includes the ingress_cidr_block_activation variable specifically to limit access to the CIDR block of the client machine that activates the storage gateway on port 80. This Security Group rule can be optionally removed once the gateway is activated. The source code of the security group configuration can be found in modules/ec2-sgw/sg.tf file.

module "ec2_sgw" {
  source                        = "aws-ia/storagegateway/aws//modules/ec2-sgw"
  vpc_id                        = var.vpc_id
  subnet_id                     = var.subnet_id
  ingress_cidr_block_activation = "10.0.0.1/32"
  ingress_cidr_blocks           = ["172.16.0.0/24", "172.16.10.0/24"]
  create_security_group         = true
}

To use your own security group, set create_security_group = false and append your own security_group_id attribute as shown in the example below :

As an example :

module "ec2_sgw" {
  source                = "aws-ia/storagegateway/aws//modules/ec2-sgw"
  vpc_id                = var.vpc_id
  subnet_id             = var.subnet_id
  create_security_group = false
  security_group_id     = "sg-12345678"
}

Support & Feedback

Storage Gateway module for Terraform is maintained by AWS Solution Architects. It is not part of an AWS service and support is provided best-effort by the AWS Storage community.

To post feedback, submit feature ideas, or report bugs, please use the Issues section of this GitHub repo.

If you are interested in contributing to the Storage Gateway module, see the Contribution guide.

Requirements

Name Version
terraform >= 1.0.7
aws >= 4.0.0
awscc >= 0.24.0

Providers

Name Version
aws >= 4.0.0

Modules

No modules.

Resources

Name Type
aws_security_group.vpce_sg resource
aws_storagegateway_cache.sgw resource
aws_storagegateway_gateway.mysgw resource
aws_vpc_endpoint.sgw_vpce resource
aws_region.current data source
aws_storagegateway_local_disk.sgw data source

Inputs

Name Description Type Default Required
gateway_ip_address IP Address of the Storage Gateway VM in vSphere string n/a yes
gateway_name Storage Gateway Name string n/a yes
create_vpc_endpoint Create an interface VPC endpoint for the Storage Gateway bool false no
create_vpc_endpoint_security_group Create a Security Group for the VPC Endpoint for Storage Gateway bool false no
disk_node Disk node on the SGW Gateway VM where the cache disk resides on the OS string "/dev/sdb" no
disk_path Disk path on the Storage Gateway VM where the cache disk resides on the OS string "/dev/sdb" no
domain_controllers List of IPv4 addresses, NetBIOS names, or host names of your domain server. If you need to specify the port number include it after the colon (“:”). For example, mydc.mydomain.com:389. list(any) [] no
domain_name The name of the domain that you want the gateway to join string "" no
domain_password The password for the service account on your self-managed AD domain that SGW will use to join to your AD domain string "" no
domain_username The user name for the service account on your self-managed AD domain that SGW use to join to your AD domain string "" no
gateway_private_ip_address Inbound IP address of Gateway VM for Security Group associated with VPC Endpoint. Must be set if create_vpc_endpoint=true string null no
gateway_type Type of the gateway. Valid options are FILE_S3, FILE_FSX_SMB, VTL, CACHED, STORED string "FILE_S3" no
gateway_vpc_endpoint Existing VPC endpoint address to be used when activating your gateway. This variable value will be ignored if setting create_vpc_endpoint=true. string null no
join_smb_domain Setting for controlling whether to join the Storage gateway to an Active Directory (AD) domain for Server Message Block (SMB) file shares. Variables domain_controllers, domain_name, password and username should also be specified to join AD domain. bool true no
organizational_unit The organizational unit (OU) is a container in an Active Directory that can hold users, groups, computers, and other OUs and this parameter specifies the OU that the gateway will join within the AD domain. string "" no
timeout_in_seconds Specifies the time in seconds, in which the JoinDomain operation must complete. The default is 20 seconds. number -1 no
timezone Time zone for the gateway. The time zone is of the format GMT, GMT-hr:mm, or GMT+hr:mm.For example, GMT-4:00 indicates the time is 4 hours behind GMT. Avoid prefixing with 0 string "GMT" no
vpc_endpoint_private_dns_enabled Enable private DNS for VPC Endpoint bool false no
vpc_endpoint_security_group_id Optionally provide an existing Security Group ID to associate with the VPC Endpoint. Must be set if create_vpc_endpoint_security_group=false string null no
vpc_endpoint_subnet_ids Provide existing subnet IDs to associate with the VPC Endpoint. Must provide a valid values if create_vpc_endpoint=true. list(string) null no
vpc_id VPC id for creating a VPC endpoint. Must provide a valid value if create_vpc_endpoint=true. string null no

Outputs

Name Description
storage_gateway Storage Gateway Module
storage_gateway_name Storage Gateway Name