[Yandex Cloud documentation](../../../index.md) > [Yandex Object Storage](../../index.md) > [Tutorials](../index.md) > [Setting up static website hosting in a Yandex Object Storage bucket with Yandex Cloud CDN access](index.md) > Terraform

# Setting up static website hosting in a Yandex Object Storage bucket with Yandex Cloud CDN access using Terraform


To set up the infrastructure for [website hosting in a bucket with Yandex Cloud CDN access](index.md) using Terraform:

1. [Get your cloud ready](#before-you-begin).
1. [Add a certificate to Certificate Manager](#add-certificate).
1. [Create your infrastructure](#deploy).
1. [Test the CDN](#check-cdn).

If you no longer need the resources you created, [delete them](#clear-out).


## Get your cloud ready {#before-begin}

Sign up for Yandex Cloud and create a [billing account](../../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../../billing/quickstart/index.md) and [link](../../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../../resource-manager/concepts/resources-hierarchy.md).


### Required paid resources {#paid-resources}

The infrastructure support cost for a bucket-hosted site with CDN access includes:
* A fee for outgoing traffic from CDN servers (see [Cloud CDN pricing](../../../cdn/pricing.md)).
* Fee for data storage in Object Storage, data operations, and outbound traffic (see [Object Storage pricing](../../pricing.md)).
* Fee for public DNS requests and [DNS zones](../../../dns/concepts/dns-zone.md) if using [Yandex Cloud DNS](../../../dns/index.md) (see [Cloud DNS pricing](../../../dns/pricing.md)).


## Add a certificate to Certificate Manager {#add-certificate}

Certificates from [Yandex Certificate Manager](../../../certificate-manager/index.md) are supported. You can [issue a new Let's Encrypt® certificate](../../../certificate-manager/operations/managed/cert-create.md) or [upload one of your own](../../../certificate-manager/operations/import/cert-create.md).

The certificate must be located in the same [folder](../../../resource-manager/concepts/resources-hierarchy.md#folder) as your CDN resource.

For a Let's Encrypt® certificate, pass an [ownership check](../../../certificate-manager/operations/managed/cert-validate.md) for the domain specified in the certificate.


## Create your infrastructure {#deploy}

With [Terraform](https://www.terraform.io/), you can quickly create a cloud infrastructure in Yandex Cloud and manage it using configuration files. These files store the infrastructure description written in HashiCorp Configuration Language (HCL). If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.

Terraform is distributed under the [Business Source License](https://github.com/hashicorp/terraform/blob/main/LICENSE). The [Yandex Cloud provider for Terraform](https://github.com/yandex-cloud/terraform-provider-yandex) is distributed under the [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/) license.

For more information about the provider resources, see the relevant documentation on the [Terraform](https://www.terraform.io/docs/providers/yandex/index.html) website or [its mirror](../../../terraform/index.md).

To create an infrastructure using Terraform:
1. [Install Terraform](../../../tutorials/infrastructure-management/terraform-quickstart.md#install-terraform), [get the credentials](../../../tutorials/infrastructure-management/terraform-quickstart.md#get-credentials), and specify the source for installing Yandex Cloud (see [Configure your provider](../../../tutorials/infrastructure-management/terraform-quickstart.md#configure-provider), step 1).
1. Set up your infrastructure description files:

   {% list tabs group=infrastructure_description %}

   - Ready-made configuration {#ready}

     1. Clone the repository with configuration files.

        ```bash
        git clone https://github.com/yandex-cloud-examples/yc-s3-cdn-hosting.git
        ```

     1. Navigate to the repository directory. It should now contain the following files:
        * `index.html`: Website home page file.
        * `yc-cdn-hosting.tf`: New infrastructure configuration.
        * `yc-cdn-hosting.auto.tfvars`: User data file.

   - Manually {#manual}

     1. Create a folder for configuration files.
     1. In the folder, create:
        1. The home page file for the website, `index.html`:

           {% cut "index.html" %}
           
           ```html
           <!DOCTYPE html>
           <html>
             <head>
               <title>My site</title>
             </head>
             <body>
               <p>The site is working</p>
             </body>
           </html>
           ```
           
           {% endcut %}

        1. `yc-cdn-hosting.tf` configuration file:

           {% cut "yc-cdn-hosting.tf" %}

           ```hcl
           # Declaring variables with sensitive data
           
           variable "folder_id" {
             type = string
           }
           
           variable "domain" {
             type = string
           }
           
           variable "cert_id" {
             type = string
           }
           
           # Configuring the provider
           
           terraform {
             required_providers {
               yandex = {
                 source = "yandex-cloud/yandex"
               }
             }
             required_version = ">=0.136.0"
           }
           
           # Getting TLS certificate info
           
           data "yandex_cm_certificate" "example_by_id" {
             certificate_id = var.cert_id
           }
           
           # Creating a bucket
           
           resource "yandex_storage_bucket" "main-bucket" {
             bucket    = var.domain
             folder_id = var.folder_id
             max_size  = "1073741824"
             website {
               index_document = "index.html"
             }
             https {
               certificate_id = data.yandex_cm_certificate.example_by_id.id
             }
           
             depends_on = [data.yandex_cm_certificate.example_by_id]
           }
           
           # Configuring access permissions for a bucket
           
           resource "yandex_storage_bucket_grant" "my_grant_main" {
             bucket = yandex_storage_bucket.main-bucket.id
             grant {
               uri         = "http://acs.amazonaws.com/groups/global/AllUsers"
               permissions = ["READ"]
               type        = "Group"
             }
             depends_on = [yandex_storage_bucket.main-bucket]
           }
           
           # Upload an object to a bucket
           
           resource "yandex_storage_object" "index-page" {
             bucket     = yandex_storage_bucket.main-bucket.id
             key        = "index.html"
             source     = "index.html"
             depends_on = [yandex_storage_bucket_grant.my_grant_main]
           }
           
           # Creating a DNS zone
           
           resource "yandex_dns_zone" "zone1" {
             name   = "mydnszone"
             zone   = "${var.domain}."
             public = true
           }
           
           # Creating a DNS record
           
           resource "yandex_dns_recordset" "rs1" {
             zone_id     = yandex_dns_zone.zone1.id
             name        = "cdn"
             type        = "CNAME"
             ttl         = 600
             data        = ["${data.yandex_cdn_resource.my_resource.provider_cname}"]
             description = "CDN CNAME record"
             depends_on  = [yandex_cdn_resource.my_resource]
           }
           
           # Getting CDN resource info
           
           data "yandex_cdn_resource" "my_resource" {
             resource_id = yandex_cdn_resource.my_resource.id
           }
           
           # Creating an origin group
           
           resource "yandex_cdn_origin_group" "my_group" {
             name     = "updates-origin-group"
             use_next = true
             origin {
               source = "${var.domain}.website.yandexcloud.net"
             }
           }
           
           # Creating a CDN resource
           
           resource "yandex_cdn_resource" "my_resource" {
             cname             = "cdn.${var.domain}"
             active            = true
             origin_protocol   = "http"
             origin_group_name = yandex_cdn_origin_group.my_group.name
             options {
               custom_host_header     = "${var.domain}.website.yandexcloud.net"
               redirect_http_to_https = true
             }
             ssl_certificate {
               type                   = "certificate_manager"
               certificate_manager_id = data.yandex_cm_certificate.example_by_id.id
             }
           }
           ```

           {% endcut %}

        1. `yc-cdn-hosting.auto.tfvars` user data file:

           {% cut "yc-cdn-hosting.auto.tfvars" %}

           ```hcl
           folder_id = "<folder_ID>"
           domain    = "<domain_name>"
           cert_id   = "<TLS_certificate_ID>"
           ```

           {% endcut %}

   {% endlist %}

   Learn more about the properties of Terraform resources in the relevant provider guides:
   * [TLS certificate](../../../certificate-manager/concepts/managed-certificate.md): [yandex_cm_certificate](../../../terraform/data-sources/cm_certificate.md) data source.
   * [Bucket](../../concepts/bucket.md): [yandex_storage_bucket](../../../terraform/resources/storage_bucket.md).
   * [Configuring](../../operations/buckets/edit-acl.md) access permissions for a bucket using [ACL Object Storage](../../concepts/acl.md): [yandex_storage_bucket_grant](../../../terraform/resources/storage_bucket_grant.md).
   * [Object](../../concepts/object.md): [yandex_storage_object](../../../terraform/resources/storage_object.md).
   * [DNS zone](../../../dns/concepts/dns-zone.md): [yandex_dns_zone](../../../terraform/resources/dns_zone.md).
   * [DNS resource record](../../../dns/concepts/resource-record.md): [yandex_dns_recordset](../../../terraform/resources/dns_recordset.md).
   * [CDN resource](../../../cdn/concepts/resource.md): [yandex_cdn_resource](../../../terraform/resources/cdn_resource.md).
   * [Origin group](../../../cdn/concepts/origins.md#groups): [yandex_cdn_origin_group](../../../terraform/resources/cdn_origin_group.md).

1. In the `yc-cdn-hosting.auto.tfvars` file, set the following user-defined properties:
   * `folder_id`: [Folder ID](../../../resource-manager/operations/folder/get-id.md).
   * `domain`: Primary domain name, e.g., `example.com`. 
       To use domain names in the public DNS zone, you need to delegate it to authoritative name servers. Specify `ns1.yandexcloud.net` and `ns2.yandexcloud.net` server addresses in your registrar's account settings.
   * `cert_id`: Certificate Manager TLS certificate ID, with domain ownership verified.

1. Create the resources:

   1. In the terminal, navigate to the configuration file directory.
   1. Make sure the configuration is correct using this command:
   
      ```bash
      terraform validate
      ```
   
      If the configuration is valid, you will get this message:
   
      ```bash
      Success! The configuration is valid.
      ```
   
   1. Run this command:
   
      ```bash
      terraform plan
      ```
   
      You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
   1. Apply the configuration changes:
   
      ```bash
      terraform apply
      ```
   
   1. Type `yes` and press **Enter** to confirm the changes.

{% note warning %}

After the CDN resource is set up, it may take up to 15 minutes for it to go live.

Make sure the new CDN resource is fully functional before proceeding with the next steps.

{% endnote %}


## Test the CDN {#check-cdn}

Wait for the DNS records to get updated (this may take several hours).

Check if the website is accessible: use the new URL, `cdn.example.com`, to open it. You should be redirected to the `https://cdn.example.com` website with a TLS certificate from Certificate Manager already connected and content sourced from Cloud CDN.


## How to delete the resources you created {#clear-out}

To stop paying for the resources you created:

1. Open the `yc-cdn-hosting.tf` file and delete your infrastructure description from it.
1. Apply the changes:

    1. In the terminal, navigate to the configuration file directory.
    1. Make sure the configuration is correct using this command:
    
       ```bash
       terraform validate
       ```
    
       If the configuration is valid, you will get this message:
    
       ```bash
       Success! The configuration is valid.
       ```
    
    1. Run this command:
    
       ```bash
       terraform plan
       ```
    
       You will see a list of resources and their properties. No changes will be made at this step. Terraform will show any errors in the configuration.
    1. Apply the configuration changes:
    
       ```bash
       terraform apply
       ```
    
    1. Type `yes` and press **Enter** to confirm the changes.


#### See also {#see-also}

* [Setting up static website hosting in a Yandex Object Storage bucket with Yandex Cloud CDN access](console.md)