Skip to content
Snippets Groups Projects
README.md 7.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Infrastructure as Code project to deploy lab infrastructure and configure instances. Working with Atrium, Gitlab CI, Terraform, Cloud-init, bash scripts and Scaleway.
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    ### How does it work ?
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    The FORGE (Gitlab) manage the Infrastructure with Terraform at any state, plan, creation, modification and destruction with the CI. The FORGE store and will provide the configuration information
    such as credentials to Terraform only during the running state to improve security. Then, informations are destroyed with the Gitlab Agent container.
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    On run state, Terraform will create, modify and destroy infrastructure resources in Scaleway to match the configuration described in the configuration files.
    
    
    **Resources deployed :**
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    | resource-type                    | plan   | inbound port |
    |----------------------------------|--------|--------------|
    | scaleway_instance_ip             |        |              |
    | scaleway_domain_record           |        |              |
    | scaleway_domain_record           |        |              |
    
    | scaleway_instance_security_group |        | 22, 443      |
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    | scaleway_instance_server         | DEV1-L |              |
    
    
    After the resources provisionned with Terraform, Cloud-init will configure the instances by running bash scripts, creating files... And 3 services will be running for each instance.
    
    
    **Running services :**
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    - Atrium (Reverse proxy, TLS encryption and HTTPS to the others hosted services)
    - Code-server
    - Webtop
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    
    After deployment, each resource can be accessed though HTTPS depending on their count number :
    
    - https://desktop-0.rust-0.daag.alpha.grandlyon.com/
    - https://code-0.rust-0.daag.alpha.grandlyon.com/
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    - https://terminal-0.rust-0.daag.alpha.grandlyon.com/
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    - https://rust-0.daag.alpha.grandlyon.com/
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    - https://desktop-1.rust-1.daag.alpha.grandlyon.com/
    - https://code-1.rust-1.daag.alpha.grandlyon.com/
    
    - https://terminal-1.rust-1.daag.alpha.grandlyon.com/
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    - https://rust-1.daag.alpha.grandlyon.com/
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    
    ### Credentials
    
    **Desktop username : abc**
    **Atrium username : admin**
    **Password : <Gitlab Stored>**
    
    ## How to add new resources
    
    You can add Terraform resources directly to the main.tf file.
    Template are available to the link below.
    
    **Terraform Registry for Scaleway provider : https://registry.terraform.io/providers/scaleway/scaleway/latest/docs**
    
    
    ## How to setup configuration file for services
    
    ### cloud-init : file creation
    
    
    In this example, you will find how to create a file to a defined path with cloud-init.
    
    Content inside `%` are meant to be replaced with sed command to be able to use environment variables or user-data.
    
    **Example:**
    
    ```yaml
    write_files:
      - content: |
          hostname: %atrium_hostname%.daag.alpha.grandlyon.com
          debug_mode: false
          letsencrypt_email: %atrium_letsencrypt_email%
          tls_mode: Auto
          apps: # optional : applications served by atrium
            - id: 1
              name: Code %atrium_count_index%
              icon: web_asset
              color: 4292030255
              is_proxy: true
              host: code-%atrium_count_index%
              target: localhost:8080
            - id: 2
              name: Desktop %atrium_count_index%
              icon: web_asset
              color: 4292030255
              is_proxy: true
              host: desktop-%atrium_count_index%
              target: localhost:8081
        path: /root/atrium.yaml
    ```
    
    
    **Bash commands example to replace `%` content :**
    
    ```bash
    sed -i "s/%atrium_hostname%/$(scw-userdata atrium_hostname)/g" /root/atrium.yaml
    sed -i "s/%atrium_letsencrypt_email%/$(scw-userdata atrium_letsencrypt_email)/g" /root/atrium.yaml
    sed -i "s/%atrium_count_index%/$(scw-userdata atrium_count_index)/g" /root/atrium.yaml
    ```
    
    
    ## Downloading file
    
    The example show how to curl a configuration file from repository to a defined path with cloud-init.
    
    
    **Example :**
    
    ```yaml
    runcmd:
    #
    # cloud-init execute cmd before HOME and USER are set.
    #
      - "export HOME=/root"
      - "export USER=root"
    #
    # Install Atrium
    #
      - "curl https://forge.grandlyon.com/systemes-dinformation/alpha/projects/labo-rust/-/raw/develop/instance-scripts/config-files/atrium.yaml -o root/atrium.yaml"
      - "curl https://forge.grandlyon.com/systemes-dinformation/alpha/projects/labo-rust/-/raw/develop/instance-scripts/config-files/atrium.sh | bash"
    ```
    
    
    ## Use Gitlab variables in instances
    
    From my instances, I should be able to access the variables as user-data using the command `scw-userdata <my-variable>` after declaring them in Terraform.
    **Some documentation : https://blog.scaleway.com/introducing-scaleway-cloud-init-support/**
    
    
    **Example : Declare in Terraform**
    
    ```HCL
    user_data = {
        atrium_count_index = count.index
        atrium_hostname = scaleway_domain_record.subdomain_record[count.index].name
        atrium_letsencrypt_email = var.LETSENCRYPT_EMAIL
        user_password = var.USER_PASSWORD
        cloud-init = file("../instance-scripts/cloud-init.yml") // this is not a variable, but the declaration of cloud-init file.
    }
    ```
    
    
    ** Example : Retrieve in instance
    ```bash
    scw-userdata atrium_count_index
    ```
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ## Setup Terraform Locally
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    First, you must setup 2 local files for your variables :
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### variables-local.tf 
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    Create a file **variables-local.tf** containing the following code :
    ```hcl
    variable "FORGE_PROJECT_ID" {
      type        = string
      description = "Forge Project ID"
      default     = "your project id"
      sensitive   = true
    }
    
    variable "FORGE_USERNAME" {
      type        = string
      description = "Forge Username"
      default     = "your username"
      sensitive   = true
    }
    
    variable "FORGE_ACCESS_TOKEN" {
      type        = string
      description = "Forge Access Token"
      default     = "your access token"
      sensitive   = true
    }
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    ```
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### variables-local.tfvars
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    
    Now, you can create a file for your variables information called **variables-local.tfvars** containing the following code :
    ```hcl
    ### SCW variables
    
    SCW_PROJECT_ID         = ""
    SCW_ACCESS_KEY         = ""
    SCW_SECRET_KEY         = ""
    
    INSTANCES_COUNT        = ""
    
    ENVIRONMENT            = ""
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    ```
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### Terraform init - Gitlab remote tfstate
    
    You can grab a init command from your gitlab project on menu Infrastructure > Terraform.
    Select your environment and click the actions button, then you will only need to provide a gitlab project token.
    Command should look like :
    ```bash
    export GITLAB_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN>
    terraform init \
    
        -backend-config="address=https://forge.grandlyon.com/api/v4/projects/<project-id>/terraform/state/<tfstate-name>" \
        -backend-config="lock_address=https://forge.grandlyon.com/api/v4/projects/<project-id>/terraform/state/<tfstate-name>/lock" \
        -backend-config="unlock_address=https://forge.grandlyon.com/api/v4/projects/<project-id>/terraform/state/<tfstate-name>/lock" \
    
    Nathan Rodet's avatar
    Nathan Rodet committed
        -backend-config="username=xxxxxxx" \
        -backend-config="password=$GITLAB_ACCESS_TOKEN" \
        -backend-config="lock_method=POST" \
        -backend-config="unlock_method=DELETE" \
        -backend-config="retry_wait_min=5"
    
    terraform init -var-file=variables-local.tfvars
    ```
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### Terraform plan - With variables file
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ```bash
    terraform plan -var-file=variables-local.tfvars -out=tfplan
    ```
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### Terraform apply - With plan
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ```bash
    terraform apply tfplan
    ```
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ### Terraform destroy - With variables file
    
    Nicolas PERNOUD's avatar
    Nicolas PERNOUD committed
    
    
    Nathan Rodet's avatar
    Nathan Rodet committed
    ```bash
    terraform destroy -var-file=variables-local.tfvars
    ```