One place for hosting & domains

      Cara Mengonversi Jenis Data di Python 3


      Pengantar

      Dalam Python, jenis data digunakan untuk mengklasifikasikan satu jenis data tertentu, menentukan nilai-nilai yang dapat Anda tetapkan pada jenisnya dan operasi yang dapat Anda lakukan padanya. Ketika melakukan pemrograman, ada saatnya kita perlu mengonversi nilai dengan jenis yang berbeda untuk memanipulasi nilai dengan cara yang berbeda. Misalnya, kita mungkin perlu menggabungkan nilai numerik dengan string, atau mewakili tempat desimal di dalam angka yang diinisialisasi sebagai nilai integer.

      Tutorial ini akan memandu Anda mengenai konversi angka, string, tupel, dan daftar, serta memberikan contoh untuk membantu Anda membiasakan diri dengan kasus penggunaan yang berbeda-beda.

      Mengonversi Jenis Angka

      Dalam Python, ada dua jenis angka: integer dan angka pecahan atau float. Terkadang, Anda mengerjakan kode orang lain dan perlu mengonversi integer ke float atau sebaliknya, atau Anda mungkin menemukan bahwa Anda telah menggunakan integer sedangkan yang Anda perlukan adalah float. Python memiliki metode bawaan yang memungkinkan Anda untuk mengubah integer ke float dan float ke integer dengan mudah.

      Mengonversi Integer ke Float

      Metode Python float() akan mengonversi integer ke float. Untuk menggunakan fungsi ini, tambahkan bilangan integer di dalam tanda kurung:

      float(57)
      

      Dalam kasus ini, 57 akan dikonversi menjadi 57.0.

      Anda juga dapat menggunakan ini dengan variabel. Mari kita nyatakan f sama dengan 57, lalu cetak float yang baru:

      f = 57
      print(float(f))
      

      Output

      57.0

      Dengan menggunakan fungsi float(), kita dapat mengonversi integer ke float.

      Mengonversi Float ke Integer

      Python juga memiliki fungsi bawaan untuk mengonversi float menjadi integer: int().

      Fungsi int() bekerja mirip seperti fungsi float(): Anda dapat menambahkan angka pecahan di dalam tanda kurung untuk mengonversinya menjadi integer:

      int(390.8)
      

      Dalam kasus ini, 390.8 akan dikonversi menjadi 390.

      Anda juga dapat menggunakan ini dengan variabel. Mari kita nyatakan b sama dengan 125.0, dan c sama dengan 390.8, lalu cetak float yang baru:

      b = 125.0
      c = 390.8
      
      print(int(b))
      print(int(c))
      

      Output

      125 390

      Ketika mengonversi float menjadi integer dengan fungsi int(), Python memotong desimal dan sisa pecahan untuk menciptakan integer. Meskipun mungkin kita ingin membulatkan 390,8 ke atas menjadi 391, Python tidak akan melakukannya melalui fungsi int().

      Angka yang Dikonversi melalui Pembagian

      Dalam Python 3, hasil pembagian yang relevan dikonversi dari integer ke float ketika melakukan pembagian, meskipun ini tidak diterapkan dalam Python 2. Maka dari itu, ketika Anda membagi 5 dengan 2, dalam Python 3 Anda akan mendapatkan angka pecahan sebagai jawabannya (2.5):

      a = 5 / 2
      print(a)
      

      Output

      2.5

      Dalam Python 2, karena berhadapan dengan dua integer, Anda justru akan menerima integer sebagai jawaban: 5 / 2 = 2. Baca “Python 2 vs Python 3: Pertimbangan Praktis” untuk informasi lebih lanjut tentang perbedaan antara Python 2 dan Python 3.

      Mengonversi dengan String

      String adalah rangkaian dari satu karakter atau lebih (huruf, angka, simbol). String adalah bentuk umum dari data di program komputer, dan kita mungkin perlu mengonversi string ke angka atau angka ke string dengan cukup sering, terutama ketika kita mengambil data yang dihasilkan pengguna.

      Mengonversi Angka ke String

      Kita dapat mengonversi angka ke string menggunakan metode str(). Kita akan memasukkan angka atau variabel ke dalam tanda kurung dari metode tersebut, lalu nilai numerik itu akan dikonversi menjadi nilai string.

      Pertama-tama, mari kita bahas tentang mengonversi integer. Untuk mengonversi integer 12 menjadi suatu nilai string, Anda dapat memasukkan 12 ke dalam metode str():

      str(12)
      

      Ketika menjalankan str(12) di dalam shell Python interaktif dengan perintah python di jendela terminal, Anda akan menerima keluaran berikut:

      Output

      '12'

      Tanda kutip di antara angka 12 menandakan bahwa kini angka tersebut bukan lagi integer, melainkan nilai string.

      Dengan variabel, kita dapat mulai melihat seberapa praktisnya melakukan konversi integer menjadi string. Katakanlah kita ingin melacak kemajuan pemrograman harian pengguna dan memasukkan jumlah baris kode yang mereka tulis dalam kurun waktu tertentu. Kita ingin menunjukkan umpan balik ini kepada pengguna dan kita akan mencetak nilai string serta integer di saat bersamaan:

      user = "Sammy"
      lines = 50
      
      print("Congratulations, " + user + "! You just wrote " + lines + " lines of code.")
      

      Ketika menjalankan kode ini, kita menerima pesan kesalahan berikut:

      Output

      TypeError: Can't convert 'int' object to str implicitly

      Kita tidak dapat menggabungkan string dan integer dalam Python, sehingga kita harus mengonversi variabel lines itu menjadi nilai string:

      user = "Sammy"
      lines = 50
      
      print("Congratulations, " + user + "! You just wrote " + str(lines) + " lines of code.")
      

      Sekarang, saat menjalankan kode, kita menerima keluaran berikut yang memberikan selamat kepada pengguna kita terkait kemajuan mereka:

      Output

      Congratulations, Sammy! You just wrote 50 lines of code.

      Jika kita ingin mengonversi float menjadi string, alih-alih integer menjadi string, kita mengikuti langkah-langkah dan format yang sama. Ketika kita memasukkan float ke dalam metode str(), nilai string dari float akan dikembalikan. Kita dapat menggunakan baik nilai float itu sendiri atau suatu variabel:

      print(str(421.034))
      
      f = 5524.53
      print(str(f))
      

      Output

      421.034 5524.53

      Kita dapat menguji untuk memastikan bahwa prosesnya benar dengan menggabungkannya bersama suatu string:

      f = 5524.53
      print("Sammy has " + str(f) + " points.")
      

      Output

      Sammy has 5524.53 points.

      Kita dapat merasa yakin float kita telah dikonversi dengan benar menjadi suatu string karena penggabungan telah dilakukan tanpa pesan kesalahan.

      Mengonversi String ke Angka

      String dapat dikonversi menjadi angka dengan metode int() dan float().

      Jika string Anda tidak memiliki tempat desimal, kemungkinan besar Anda ingin mengonversinya menjadi integer dengan metode int().

      Mari kita gunakan contoh pengguna Sammy yang melacak baris kode yang ditulis setiap hari. Kita mungkin ingin memanipulasi nilai-nilai tersebut dengan matematika untuk memberikan umpan balik yang lebih menarik bagi pengguna, tetapi nilai-nilai itu saat ini disimpan di dalam string:

      lines_yesterday = "50"
      lines_today = "108"
      
      lines_more = lines_today - lines_yesterday
      
      print(lines_more)
      

      Output

      TypeError: unsupported operand type(s) for -: 'str' and 'str'

      Karena dua nilai numerik disimpan dalam string, kita menerima pesan kesalahan. Operan - untuk pengurangan bukanlah operan yang valid untuk dua nilai string.

      Mari kita modifikasi kodenya untuk menyertakan metode int() yang akan mengonversi string menjadi integer, dan memungkinkan kita melakukan operasi matematika dengan nilai-nilai yang awalnya adalah string.

      lines_yesterday = "50"
      lines_today = "108"
      
      lines_more = int(lines_today) - int(lines_yesterday)
      
      print(lines_more)
      

      Output

      58

      Variabel lines_more secara otomatis merupakan integer, dan sama dengan nilai numerik 58 di dalam contoh ini.

      Kita juga dapat mengonversi angka dalam contoh di atas menjadi nilai float dengan metode float() menggantikan metode int(). Alih-alih menerima keluaran 58, kita akan menerima keluaran 58.0, yang merupakan float.

      Pengguna Sammy menghasilkan poin dalam nilai desimal

      total_points = "5524.53"
      new_points = "45.30"
      
      new_total_points = total_points + new_points
      
      print(new_total_points)
      

      Output

      5524.5345.30

      Dalam kasus ini, menggunakan operan + dengan dua string adalah operasi yang valid, tetapi ini menggabungkan dua string alih-alih menambahkan dua nilai numerik bersama. Jadi, keluaran kita terlihat aneh karena hanya menempatkan dua nilai berdampingan.

      Kita ingin mengonversi string ini menjadi float sebelum melakukan operasi matematika dengan metode float():

      total_points = "5524.53"
      new_points = "45.30"
      
      new_total_points = float(total_points) + float(new_points)
      
      print(new_total_points)
      

      Output

      5569.83

      Karena kita telah mengonversi dua string menjadi float, kita menerima hasil yang diharapkan yang menambahkan 45.30 ke 5524.53.

      Jika kita mencoba mengonversi nilai string dengan tempat desimal menjadi suatu integer, kita akan menerima pesan kesalahan:

      f = "54.23"
      print(int(f))
      

      Output

      ValueError: invalid literal for int() with base 10: '54.23'

      Jika kita memasukkan nilai desimal dalam suatu string ke metode int(), kita akan menerima pesan kesalahan karena nilai tersebut tidak akan terkonversi menjadi integer.

      Mengonversi string menjadi angka memungkinkan kita untuk memodifikasi jenis data yang digunakan secara cepat sehingga kita dapat melakukan operasi pada nilai numerik yang awalnya adalah string.

      Mengonversi ke Tupel dan Daftar

      Anda dapat menggunakan metode list() dan tuple() untuk mengonversi nilai yang diberikan kepada mereka menjadi jenis data daftar dan tupel secara berurutan. Dalam Python:

      • daftar adalah rangkaian berurutan yang dapat bermutasi dari elemen yang terkandung dalam tanda kurung persegi [ ].
      • tupel adalah rangkaian berurutan yang tak dapat bermutasi dari elemen yang terkandung dalam tanda kurung ( ).

      Mengonversi ke Tupel

      Mari kita mulai dengan mengonversi daftar menjadi tupel. Mengonversi daftar menjadi tupel dapat memungkinkan optimisasi terhadap program yang kita ciptakan, karena ini adalah jenis data yang tidak dapat bermutasi. Ketika kita menggunakan metode tuple(), metode ini akan menampilkan versi tupel dari nilai yang diberikan kepadanya.

      print(tuple(['pull request', 'open source', 'repository', 'branch']))
      

      Output

      ('pull request', 'open source', 'repository', 'branch')

      Kita lihat bahwa tupel dicetak dalam keluaran, karena itemnya kini terkandung di dalam tanda kurung alih-alih tanda kurung persegi.

      Mari kita gunakan tuple() dengan variabel yang mewakili suatu daftar:

      sea_creatures = ['shark', 'cuttlefish', 'squid', 'mantis shrimp']
      print(tuple(sea_creatures))
      

      Output

      ('shark', 'cuttlefish', 'squid', 'mantis shrimp')

      Sekali lagi, kita lihat bahwa nilai daftar berubah menjadi nilai tupel, yang diindikasikan oleh tanda kurung. Kita dapat mengonversi jenis data yang dapat melakukan iterasi ke tupel, termasuk string:

      print(tuple('Sammy'))
      

      Output

      ('S', 'a', 'm', 'm', 'y')

      Karena kita dapat melakukan iterasi melalui string, kita dapat mengonversinya menjadi tupel dengan metode tuple(). Namun, kita akan menerima pesan kesalahan dengan jenis data yang tidak dapat melakukan iterasi seperti integer dan float:

      print(tuple(5000))
      

      Output

      TypeError: 'int' object is not iterable

      Meskipun memungkinkan untuk mengonversi integer menjadi string lalu mengonversinya menjadi tupel, seperti dalam tuple(str(5000)), opsi terbaiknya adalah memilih kode yang dapat dibaca dibandingkan konversi yang rumit.

      Mengonversi ke Daftar

      Mengonversi nilai untuk membuat daftar, khususnya tupel, dapat berguna ketika Anda perlu memiliki versi yang dapat bermutasi dari nilai itu.

      Kita akan menggunakan metode list() untuk mengonversi tupel berikut menjadi suatu daftar. Karena sintaks untuk membuat daftar menggunakan tanda kurung, pastikan untuk menyertakan tanda kurung dari metode list() tersebut, dan dalam kasus ini metode print() juga:

      print(list(('blue coral', 'staghorn coral', 'pillar coral')))
      

      Output

      ['blue coral', 'staghorn coral', 'pillar coral']

      Tanda kurung memberikan sinyal bahwa daftar telah dikembalikan dari nilai tupel asli yang diberikan melalui metode list().

      Agar kode lebih mudah dibaca, kita dapat menghilangkan salah satu dari pasangan tanda kurung menggunakan variabel:

      coral = ('blue coral', 'staghorn coral', 'pillar coral')
      list(coral)
      

      Jika kita mencetak list(coral), kita akan menerima keluaran yang sama seperti di atas.

      Sama seperti tupel, string dapat dikonversi menjadi daftar:

      print(list('shark'))
      

      Output

      ['s', 'h', 'a', 'r', 'k']

      Di sini, string 'shark' dikonversi menjadi daftar, yang memberikan versi yang dapat bermutasi dari nilai aslinya.

      Kesimpulan

      Tutorial Python ini menunjukkan cara mengonversi beberapa jenis data asli yang penting menjadi jenis data lainnya, terutama melalui metode bawaan. Mampu mengonversi jenis data dalam Python memberi Anda fleksibilitas tambahan saat menulis program Anda.



      Source link

      How To Protect Sensitive Data in Terraform


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Terraform provides automation to provision your infrastructure in the cloud. To do this, Terraform authenticates with cloud providers (and other providers) to deploy the resources and perform the planned actions. However, the information Terraform needs for authentication is very valuable, and generally, is sensitive information that you should always keep secret since it unlocks access to your services. For example, you can consider API keys or passwords for database users as sensitive data.

      If a malicious third party were to acquire the sensitive information, they would be able to breach the security systems by presenting themselves as a known trusted user. In turn, they would be able to modify, delete, and replace the resources and services that are available under the scope of the obtained keys. To prevent this from happening, it is essential to properly secure your project and safeguard its state file, which stores all the project secrets.

      By default, Terraform stores the state file locally in the form of unencrypted JSON, allowing anyone with access to the project files to read the secrets. While a solution to this is to restrict access to the files on disk, another option is to store the state remotely in a backend that encrypts the data automatically, such as DigitalOcean Spaces.

      In this tutorial, you’ll hide sensitive data in outputs during execution and store your state in a secure cloud object storage, which encrypts data at rest. You’ll use DigitalOcean Spaces in this tutorial as your cloud object storage. You’ll also use tfmask, which is an open source program written in Go that dynamically censors values in the Terraform execution log output.

      Prerequisites

      • A DigitalOcean Personal Access Token, which you can create via the DigitalOcean control panel. Instructions to do that can be found in this link: How to Generate a Personal Access Token.
      • Terraform installed on your local machine and a project set up with the DigitalOcean provider. Complete Step 1 and Step 2 of the How To Use Terraform with DigitalOcean tutorial, and be sure to name the project folder terraform-sensitive, instead of loadbalance. During Step 2, do not include the pvt_key variable and the SSH key resource.
      • A DigitalOcean Space with API keys (access and secret). To learn how to create a DigitalOcean Space and API keys, see How To Create a DigitalOcean Space and API Key.

      Note: This tutorial has specifically been tested with Terraform 0.13.

      Marking Outputs as sensitive

      In this step, you’ll hide outputs in code by setting their sensitive parameter to true. This is useful when secret values are part of the Terraform output that you’re storing indefinitely, or you need to share the output logs beyond your team for analysis.

      Assuming you are in the terraform-sensitive directory, which you created as part of the prerequisites, you’ll define a Droplet and an output showing its IP address. You’ll store it in a file named droplets.tf, so create and open it for editing by running:

      Add the following lines:

      terraform-sensitive/droplets.tf

      resource "digitalocean_droplet" "web" {
        image  = "ubuntu-18-04-x64"
        name   = "web-1"
        region = "fra1"
        size   = "s-1vcpu-1gb"
      }
      
      output "droplet_ip_address" {
        value = digitalocean_droplet.web.ipv4_address
      }
      

      This code will deploy a Droplet called web-1 in the fra1 region, running Ubuntu 18.04 on 1GB RAM and one CPU core. Here you’ve given the droplet_ip_address output a value and you’ll receive this in the Terraform log.

      To deploy this Droplet, execute the code by running the following command:

      • terraform apply -var "do_token=${DO_PAT}"

      The actions Terraform will take will be the following:

      Output

      An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web will be created + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-1" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

      Enter yes when prompted. You’ll receive the following output:

      Output

      digitalocean_droplet.web: Creating... ... digitalocean_droplet.web: Creation complete after 33s [id=216255733] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = your_droplet_ip_address

      You will find that the IP address is in the output. If you’re sharing this output with others, or in case it will be publicly available because of automated deployment processes, it’s important to take actions to hide this data in the output.

      To censor it, you’ll need to set the sensitive attribute of the droplet_ip_address output to true.

      Open droplets.tf for editing:

      Add the highlighted line:

      terraform-sensitive/droplets.tf

      resource "digitalocean_droplet" "web" {
        image  = "ubuntu-18-04-x64"
        name   = "web-1"
        region = "fra1"
        size   = "s-1vcpu-1gb"
      }
      
      output "droplet_ip_address" {
        value = digitalocean_droplet.web.ipv4_address
        sensitive = true
      }
      

      Save and close the file when you’re done.

      Apply the project again by running:

      • terraform apply -var "do_token=${DO_PAT}"

      The output will be:

      Output

      digitalocean_droplet.web: Refreshing state... [id=216255733] Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = <sensitive>

      You’ve now explicitly censored the IP address—the value of the output. Censoring outputs is useful in situations when the Terraform logs would be in a public space, or when you want them to remain hidden, but not delete them from the code. You’ll also want to censor outputs that contain passwords and API tokens, as they are sensitive info as well.

      You’ve now hidden the values of the defined outputs by marking them as sensitive. In the next step, you’ll configure Terraform to store your project’s state in the encrypted cloud, instead of locally.

      Storing State in an Encrypted Remote Backend

      The state file stores all information about your deployed infrastructure containing all its internal relationships and secrets. By default, it’s stored in plaintext, locally on the disk. Storing it remotely, in the cloud, provides a higher level of security. If the cloud storage service supports encryption at rest, it will store the state file in an encrypted state at all times, so that potential attackers won’t be able to gather information from it. Storing the state file encrypted remotely is different from marking outputs as sensitive—this way, all secrets are securely stored in the cloud, which only changes how Terraform stores data, not when it’s displayed.

      You’ll now configure your project to store the state file in a DigitalOcean Space. As a result it will be encrypted at rest and protected with TLS in transit.

      By default, the Terraform state file is called terraform.tfstate and is located in the root of every initialized directory. You can view its contents by running:

      The contents of the file will be similar to this:

      {
        "version": 4,
        "terraform_version": "0.13.1",
        "serial": 3,
        "lineage": "926017f6-d7be-e1fa-99e4-f2a988026ed4",
        "outputs": {
          "droplet_ip_address": {
            "value": "...",
            "type": "string",
            "sensitive": true
          }
        },
        "resources": [
          {
            "mode": "managed",
            "type": "digitalocean_droplet",
            "name": "web",
            "provider": "provider["registry.terraform.io/digitalocean/digitalocean"]",
            "instances": [
              {
                "schema_version": 1,
                "attributes": {
                  "backups": false,
                  "created_at": "...",
                  "disk": 25,
                  "id": "216255733",
                  "image": "ubuntu-18-04-x64",
                  "ipv4_address": "...",
                  "ipv4_address_private": "10.135.0.3",
                  "ipv6": false,
                  "ipv6_address": "",
                  "ipv6_address_private": null,
                  "locked": false,
                  "memory": 1024,
                  "monitoring": false,
                  "name": "web-1",
                  "price_hourly": 0.00744,
                  "price_monthly": 5,
                  "private_networking": true,
                  "region": "fra1",
                  "resize_disk": true,
                  "size": "s-1vcpu-1gb",
                  "ssh_keys": null,
                  "status": "active",
                  "tags": [],
                  "urn": "do:droplet:216255733",
                  "user_data": null,
                  "vcpus": 1,
                  "volume_ids": [],
                  "vpc_uuid": "fc52519c-dc84-11e8-8b13-3cfdfea9f160"
                },
                "private": "..."
              }
            ]
          }
        ]
      }
      
      

      The state file contains all the resources you’ve deployed, as well as all outputs and their computed values. Gaining access to this file is enough to compromise the entire deployed infrastructure. To prevent that from happening, you can store it encrypted in the cloud.

      Terraform supports multiple backends, which are storage and retrieval mechanisms for the state. Examples are: local for local storage, pg for the Postgres database, and s3 for S3 compatible storage, which you’ll use to connect to your Space.

      The back-end configuration is specified under the main terraform block, which is currently in provider.tf. Open it for editing by running:

      Add the following lines:

      terraform-sensitive/provider.tf

      terraform {
        required_providers {
          digitalocean = {
            source = "digitalocean/digitalocean"
            version = "1.22.2"
          }
        }
      
        backend "s3" {
          key      = "state/terraform.tfstate"
          bucket   = "your_space_name"
          region   = "us-west-1"
          endpoint = "https://spaces_endpoint"
          skip_region_validation      = true
          skip_credentials_validation = true
          skip_metadata_api_check     = true
        }
      }
      
      variable "do_token" {}
      
      provider "digitalocean" {
        token = var.do_token
      }
      

      The s3 back-end block first specifies the key, which is the location of the Terraform state file on the Space. Passing in state/terraform.tfstate means that you will store it as terraform.tfstate under the state directory.

      The endpoint parameter tells Terraform where the Space is located and bucket defines the exact Space to connect to. The skip_region_validation and skip_credentials_validation disable validations that are not applicable to DigitalOcean Spaces. Note that region must be set to a conforming value (such as us-west-1), which has no reference to Spaces.

      Remember to put in your bucket name and the Spaces endpoint, including the region, which you can find in the Settings tab of your Space. When you are done customizing the endpoint, save and close the file.

      Next, put the access and secret keys for your Space in environment variables, so you’ll be able to reference them later. Run the following commands, replacing the highlighted placeholders with your key values:

      • export SPACE_ACCESS_KEY="your_space_access_key"
      • export SPACE_SECRET_KEY="your_space_secret_key"

      Then, configure Terraform to use the Space as its backend by running:

      • terraform init -backend-config "access_key=$SPACE_ACCESS_KEY" -backend-config "secret_key=$SPACE_SECRET_KEY"

      The -backend-config argument provides a way to set back-end parameters at runtime, which you are using here to set the Space keys. You’ll be asked if you wish to copy the existing state to the cloud, or start anew:

      Output

      Initializing the backend... Do you want to copy existing state to the new backend? Pre-existing state was found while migrating the previous "local" backend to the newly configured "s3" backend. No existing state was found in the newly configured "s3" backend. Do you want to copy this state to the new "s3" backend? Enter "yes" to copy and "no" to start with an empty state.

      Enter yes when prompted. The rest of the output will be the following:

      Output

      Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... - Using previously-installed digitalocean/digitalocean v1.22.2 Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.

      Your project will now store its state in your Space. If you receive an error, double-check that you’ve provided the correct keys, endpoint, and bucket name.

      Your project is now storing state in your Space. The local state file has been emptied, which you can check by showing its contents:

      There will be no output, as expected.

      You can try modifying the Droplet definition and applying it to check that the state is still being correctly managed.

      Open droplets.tf for editing:

      Modify the highlighted lines:

      terraform-sensitive/droplets.tf

      resource "digitalocean_droplet" "web" {
        image  = "ubuntu-18-04-x64"
        name   = "test-droplet"
        region = "fra1"
        size   = "s-1vcpu-1gb"
      }
      
      output "droplet_ip_address" {
        value = digitalocean_droplet.web.ipv4_address
        sensitive = false
      }
      

      Save and close the file, then apply the project by running:

      • terraform apply -var "do_token=${DO_PAT}"

      You will receive the following output:

      Output

      An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # digitalocean_droplet.web will be updated in-place ~ resource "digitalocean_droplet" "web" { backups = false created_at = "2020-11-11T18:43:03Z" disk = 25 id = "216419273" image = "ubuntu-18-04-x64" ipv4_address = "159.89.21.92" ipv4_address_private = "10.135.0.4" ipv6 = false locked = false memory = 1024 monitoring = false ~ name = "web-1" -> "test-droplet" price_hourly = 0.00744 price_monthly = 5 private_networking = true region = "fra1" resize_disk = true size = "s-1vcpu-1gb" status = "active" tags = [] urn = "do:droplet:216419273" vcpus = 1 volume_ids = [] vpc_uuid = "fc52519c-dc84-11e8-8b13-3cfdfea9f160" } Plan: 0 to add, 1 to change, 0 to destroy. ...

      Enter yes when prompted, and Terraform will apply the new configuration to the existing Droplet, meaning that it’s correctly communicating with the Space its state is stored on:

      Output

      digitalocean_droplet.web: Modifying... [id=216419273] digitalocean_droplet.web: Still modifying... [id=216419273, 10s elapsed] digitalocean_droplet.web: Modifications complete after 12s [id=216419273] Apply complete! Resources: 0 added, 1 changed, 0 destroyed. Outputs: droplet_ip_address = your_droplet_ip_address

      You’ve configured the s3 backend for your project, so that you’re storing the state encrypted in the cloud, in a DigitalOcean Space. In the next step, you’ll use tfmask, a tool that will dynamically censor all sensitive outputs and information in Terraform logs.

      Using tfmask in CI/CD Environments

      In this section, you’ll download tfmask and use it to dynamically censor sensitive data from the whole output log Terraform generates when executing a command. It will censor the variables and parameters whose values are matched by a RegEx expression that you provide.

      Dynamically matching their names is possible when they follow a pattern (for example, contain the word password or secret). The advantage of using tfmask over only marking the outputs as sensitive, is that it also censors matched parts of the resource declarations that Terraform prints out while executing. It’s imperative you hide them when the execution logs may be public, such as in automated CI/CD environments, which may often list execution logs publicly.

      Compiled binaries of tfmask are available at its releases page on GitHub. For Linux, run the following command to download it:

      • sudo curl -L https://github.com/cloudposse/tfmask/releases/download/0.7.0/tfmask_linux_amd64 -o /usr/bin/tfmask

      Mark it as executable by running:

      • sudo chmod +x /usr/bin/tfmask

      tfmask works on the outputs of terraform plan and terraform apply by masking the values of all variables whose names are matched by a RegEx expression that you specify. The regex expression and the character with which the actual values will be replaced, you supply using environment variables called TFMASK_CHAR and TFMASK_VALUES_REGEX, respectively.

      You’ll now use tfmask to censor the name and ipv4_address of the Droplet that Terraform would deploy. First, you’ll need to set the mentioned environment variables by running:

      • export TFMASK_CHAR="*"
      • export TFMASK_VALUES_REGEX="(?i)^.*(ipv4_address|name).*$"

      This regex expression will match all strings starting with ipv4_address or name, and will not be case sensitive.

      To make Terraform plan an action for your Droplet, modify its definition:

      Modify the Droplet’s name:

      terraform-sensitive/droplets.tf

      resource "digitalocean_droplet" "web" {
        image  = "ubuntu-18-04-x64"
        name   = "web"
        region = "fra1"
        size   = "s-1vcpu-1gb"
      }
      
      output "droplet_ip_address" {
        value = digitalocean_droplet.web.ipv4_address
        sensitive = false
      }
      

      Save and close the file.

      Because you’ve changed an attribute of the Droplet, Terraform will show its full definition in its output. Plan the configuration, but pipe it to tfmask to censor variables according to the regex expression:

      • terraform plan -var "do_token=${DO_PAT}" | tfmask

      You’ll receive output similar to the following:

      Output

      ... digitalocean_droplet.web: Refreshing state... [id=216419273] ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: ~ update in-place Terraform will perform the following actions: # digitalocean_droplet.web will be updated in-place ~ resource "digitalocean_droplet" "web" { backups = false created_at = "2020-11-11T18:43:03Z" disk = 25 id = "216419273" image = "ubuntu-18-04-x64" ipv4_address = "************" ipv4_address_private = "**********" ipv6 = false locked = false memory = 1024 monitoring = false ~ name = "**********************************" price_hourly = 0.00744 price_monthly = 5 private_networking = true region = "fra1" resize_disk = true size = "s-1vcpu-1gb" status = "active" tags = [] urn = "do:droplet:216419273" vcpus = 1 volume_ids = [] vpc_uuid = "fc52519c-dc84-11e8-8b13-3cfdfea9f160" } Plan: 0 to add, 1 to change, 0 to destroy. ...

      Note that tfmask has censored the values for name, ipv4_address, and ipv4_address_private using the character you specified in the TFMASK_CHAR environment variable, because they match the regex expression.

      This way of value censoring in the Terraform logs is very useful for CI/CD, where the logs may be publicly available. The benefit of tfmask is that you have full control over what variables to censor (using the regex expression). You can also specify keywords that you want to censor, which may not currently exist, but you are anticipating using in the future.

      You can destroy the deployed resources by running the following command and entering yes when prompted:

      • terraform destroy -var "do_token=${DO_PAT}"

      Conclusion

      In this article, you’ve worked with a couple of ways to hide and secure sensitive data in your Terraform project. The first measure, using sensitive to hide values from the outputs, is useful when only logs are accessible, but the values themselves stay present in the state stored on disk.

      To remedy that, you can opt to store the state file remotely, which you’ve achieved with DigitalOcean Spaces. This allows you to make use of encryption at rest. You also used tfmask, a tool that censors values of variables—matched using a regex expression—during terraform plan and terraform apply.

      You can also check out Hashicorp Vault to store secrets and secret data. It can be integrated with Terraform to inject secrets in resource definitions, so you’ll be able to connect your project with your existing Vault workflow. You may want to check out our tutorial on How To Build a Hashicorp Vault Server Using Packer and Terraform on DigitalOcean.

      For more on using Terraform, read other articles in our How To Manage Infrastructure with Terraform series.



      Source link

      Open for Business: INAP’s London Data Center


      Back in August of 2018, INAP announced a multiyear alliance with Colt Data Centre Services, which included the build-out of a standalone, self-contained Tier 3-equivalent data center space in Colt’s North London facility. This London data center offers our extensive portfolio of high-density colocation, cloud and network services in this space, including Performance IP®, our patented automated route optimization engine.

      This state-of-the-art facility features the robust capabilities you’d expect of a premium, Tier 3-design data center, including:

      • 1 MW total power, 33 MVA power capacity and up to 12 kW of power per rack
      • 350 tons of cooling capacity
      • Carrier-neutral with a wide variety of options (Colt, CenturyLink, BT, Verizon, Zayo, SSE, Virgin Media, AT&T, Vodafone)
      • Key card access, 24/7/365 onsite personnel and video surveillance with 30-day video retention
      • PCI DSS, SOC 2 Type II and ISO 9001, 14001 and 27001 certifications

      Interested in learning more? Download the London data center spec sheet [PDF].


      Interested in learning more?

      CHAT NOW

       

      This post was originally published Dec. 13, 2018

      INAP


      READ MORE



      Source link