skip to Main Content

Im running a digitalocean droplet and i need to provide a json with the content of a yml in the "user_data" entry like this :

with open("cloud-config.yml", mode="r", encoding="utf-8") as file:
    data = {"name": f"{server_name}",
        "region":"ams3",
        "size":"s-1vcpu-1gb",
        "image": "debian-11-x64 ",
        "ssh_keys": [list_key()[0],#
        list_key()[1]],
        "backups": True,
        "ipv6": True,
        "monitoring": True,
        "user_data": """content of yml""",
        "with_droplet_agent":True,
    }

the content of yml is :

   #cloud-config
    users:
      - name: username
        ssh-authorized-keys:
          - sshkey
        sudo: ['ALL=(ALL) NOPASSWD:ALL']
        groups: sudo
        shell: /bin/bash
    runcmd:
      - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config
      - sed -i -e '$aAllowUsers username' /etc/ssh/sshd_config
      - restart ssh
      - sudo apt -y update
      - sudo apt install -y nano
      - sudo apt install -y rsync
      - sudo apt install -y ufw
      - sudo apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common
      - sudo curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
      - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
      - sudo apt -y update
      - sudo apt-cache policy docker-ce
      - sudo apt install -y docker-ce
      - sudo apt install -y docker-compose
      - sudo groupadd docker
      - sudo usermod -aG docker kr1p
      - newgrp docker
      - sudo setfacl --modify user:kr1p:rw /var/run/docker.sock
      - sudo systemctl start docker
      - sudo systemctl enable docker.service
      - sudo systemctl enable containerd.service
      - sudo fallocate -l 2G /swapfile
      - sudo chmod 600 /swapfile
      - sudo mkswap /swapfile
      - sudo swapon /swapfile
      - sudo cp /etc/fstab /etc/fstab.bak
      - echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
      - sudo sysctl vm.swappiness=50
      - echo 'vm.swappiness=50' | sudo tee -a /etc/sysctl.conf
      - sudo sysctl vm.vfs_cache_pressure=50
      - echo 'vm.vfs_cache_pressure = 50' | sudo tee -a /etc/sysctl.conf
      - sudo mkdir /root/.ssh
      - sudo touch '/root/.ssh/authorized_keys'
      - sudo systemctl restart sshd
      - sudo ufw default deny incoming
      - sudo ufw default allow outgoing
      - sudo ufw allow ssh
      - sudo ufw allow 22
      - sudo ufw allow 80
      - sudo ufw allow 443
      - sudo ufw allow 4000
      - sudo ufw allow 4001
      - sudo ufw allow 4002
      - sudo ufw allow 4003
      - sudo ufw allow 4004
      - sudo ufw allow 4005
      - sudo ufw allow 4006
      - sudo ufw allow 4007
      - sudo ufw allow 4008
      - sudo ufw allow 4009
      - sudo ufw allow 4010
      - echo 'y' | sudo ufw enable

If i copy paste the content of my yml inside triple quotes in my .py script it works. But if I replace the user_data line with

    "user_data": f"{cloudconfig.read()}"

or

"user_data": f"""{cloudconfig.read()}"""

Then it doesnt work.
How come this happens? Is it related to the parsing of n and whitespaces? How can i make it work?

3

Answers


  1. You can use PyYAML to work with yaml file in python.

    First, install it using pip

    pip install pyyaml
    

    Then you can load your yaml file

    import yaml
    with open("cloud-config.yml", mode="rt", encoding="utf-8") as file:
        config = yaml.safe_load(file)
        print(config)
    

    From what I have understood if you need content of YAML and in your data dictionary

    Try doing this:

    data = {"name": f"{server_name}",
            "region":"ams3",
            "size":"s-1vcpu-1gb",
            "image": "debian-11-x64 ",
            "ssh_keys": [list_key()[0],#
            list_key()[1]],
            "backups": True,
            "ipv6": True,
            "user_data": "content of yml",
            "monitoring": True,
            "with_droplet_agent":True,
        }
    
    with open("cloud-config.yml", mode="rt", encoding="utf-8") as file:
        config = yaml.safe_load(file)
        data.update(user_data=yaml.dump(config))
     
    
    Login or Signup to reply.
  2. import json
    
    # what you didn't present us
    server_name = 'stackoverflow.com'
    list_key = lambda: ['key1', 'key2', 'key3']
    
    # merging in your YAML input
    def from_file(path):
        with open(path,'r') as f:
            return f.read()
    
    # your given JSON
    data = {"name": server_name,  # no f-string needed
            "region":"ams3",
            "size":"s-1vcpu-1gb",
            "image": "debian-11-x64 ",
            "ssh_keys": list_key()[:2],  # use slicing to get list of first 2
            "backups": True,
            "ipv6": True,
            "monitoring": True,
            "user_data": from_file('cloud-config.yaml'),  # should replace this value with YAML read from file
            "with_droplet_agent":True,
    }
    
    
    # print merged JSON
    print(json.dumps(data, indent=2))
    

    Suppose your cloud-config.yaml contains:

    hello: world
    list:
        - bananas
        - milk: {free_of: ["lactose", "fat"]}
    amount: 4.2
    

    Then the code prints following JSON (with YAML content as escaped string):

    {
      "name": "stackoverflwo.com",
      "region": "ams3",
      "size": "s-1vcpu-1gb",
      "image": "debian-11-x64 ",
      "ssh_keys": [
        "key1",
        "key2"
      ],
      "backups": true,
      "ipv6": true,
      "monitoring": true,
      "user_data": "hello: worldnlist:n    - bananasn    - milk: {free_of: ["lactose", "fat"]}namount: 4.2n",
      "with_droplet_agent": true
    }
    
    Login or Signup to reply.
  3. Well, it does work for me if I fix variable name to match:

    # note `as cloudcofig` instead of `as file`
    with open("cloud-config.yml", mode="r", encoding="utf-8") as cloudconfig:
        data = {
            "user_data": f"{cloudconfig.read()}"
        }
    print(len(data["user_data"]))
    
    2335
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search