AWS::CloudFormation::Init - AWS CloudFormation

AWS::CloudFormation::Init

Use o tipo AWS::CloudFormation::Init para incluir metadados em uma instância do Amazon EC2 para o script auxiliar cfn-init. Se seu modelo chamar o script cfn-init, o script procurará metadados de recurso com raiz na chave de metadados AWS::CloudFormation::Init. Para mais informações sobre o cfn-init, consulte cfn-init.

O cfn-init oferece suporte a todos os tipos de metadados para sistemas Linux. Ele oferece suporte a tipos de metadados para Windows com as condições que são descritas nas seções a seguir.

Para obter um exemplo de uso do AWS::CloudFormation::Init e do script auxiliar cfn-init para a criação de uma pilha do Linux, consulte Implantar aplicações no Amazon EC2. Para obter um exemplo de pilha do Windows, consulte Bootstrapping de pilhas do Windows do AWS CloudFormation.

Sintaxe

A configuração é separada em seções. O trecho do modelo a seguir mostra como você pode anexar metadados para cfn-init a um recurso de instância do EC2 no modelo.

Os metadados são organizados em chaves de configuração, que você pode agrupar em configsets. Você pode especificar um configset ao chamar o cfn-init em seu modelo. Se você não especificar um configset, o cfn-init procurará uma única chave de configuração chamada config.

nota

O script auxiliar cfn-init processa essas seções da configuração na seguinte ordem: pacotes, grupos, usuários, origens, arquivos, comandos e serviços. Se você precisar de outra ordem, separe suas seções em diferentes chaves de configuração e, em seguida, use um configset que especifique a ordem em que as chaves de configuração devem ser processadas.

JSON

"Resources": { "MyInstance": { "Type": "AWS::EC2::Instance", "Metadata" : { "AWS::CloudFormation::Init" : { "config" : { "packages" : { : }, "groups" : { : }, "users" : { : }, "sources" : { : }, "files" : { : }, "commands" : { : }, "services" : { : } } } }, "Properties": { : } } }

YAML

Resources: MyInstance: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: config: packages: : groups: : users: : sources: : files: : commands: : services: : Properties: :
nota

As seções apresentadas a seguir contêm exemplos de scripts escritos em linguagens de script em shell do tipo Unix, como Bash. Para criar scripts para o PowerShell, certifique-se de estar familiarizado com a linguagem do PowerShell. A sintaxe do PowerShell é diferente da sintaxe dos shells do tipo Unix, portanto, é necessário estar familiarizado com a forma de utilizar o PowerShell.

Configsets

Se você quiser criar mais de uma chave de configuração e fazer com que o cfn-init as processe em uma ordem específica, crie um configset que contenha as chaves de configuração na ordem desejada.

Configset único

O trecho do modelo a seguir cria configsets chamados ascending e descending, cada um contendo duas chaves de configuração.

JSON

"AWS::CloudFormation::Init" : { "configSets" : { "ascending" : [ "config1" , "config2" ], "descending" : [ "config2" , "config1" ] }, "config1" : { "commands" : { "test" : { "command" : "echo \"$CFNTEST\" > test.txt", "env" : { "CFNTEST" : "I come from config1." }, "cwd" : "~" } } }, "config2" : { "commands" : { "test" : { "command" : "echo \"$CFNTEST\" > test.txt", "env" : { "CFNTEST" : "I come from config2" }, "cwd" : "~" } } } }

YAML

AWS::CloudFormation::Init: configSets: ascending: - "config1" - "config2" descending: - "config2" - "config1" config1: commands: test: command: "echo \"$CFNTEST\" > test.txt" env: CFNTEST: "I come from config1." cwd: "~" config2: commands: test: command: "echo \"$CFNTEST\" > test.txt" env: CFNTEST: "I come from config2" cwd: "~"

Chamadas de cfn-init relacionadas

A chamadas para cfn-init do exemplo a seguir fazem referência aos configsets de exemplo anteriores. As chamadas de exemplo são abreviadas para oferecer clareza, consulte cfn-init para obter a sintaxe completa.

  • Se uma chamada para cfn.init especificar o configset ascending:

    cfn-init -c ascending

    O script processará o config1 e, em seguida, o config2 e o arquivo test.txt conterá o texto I come from config2.

  • Se uma chamada para cfn.init especificar o configset descending:

    cfn-init -c descending

    O script processará o config2 e, em seguida, o config1 e o arquivo test.txt conterá o texto I come from config1.

Vários configsets

Você pode criar vários configsets e chamar uma série deles usando o script cfn-init. Cada configset pode conter uma lista de chaves de configuração ou referências a outros configsets. Por exemplo, o trecho do modelo a seguir cria três configsets. O primeiro configset, test1, contém uma chave de configuração chamada 1. O segundo configset, test2, contém uma referência ao configset test1 e uma chave de configuração chamada 2. O terceiro configset, padrão, contém uma referência ao configset test2.

JSON

"AWS::CloudFormation::Init" : { "configSets" : { "test1" : [ "1" ], "test2" : [ { "ConfigSet" : "test1" }, "2" ], "default" : [ { "ConfigSet" : "test2" } ] }, "1" : { "commands" : { "test" : { "command" : "echo \"$MAGIC\" > test.txt", "env" : { "MAGIC" : "I come from the environment!" }, "cwd" : "~" } } }, "2" : { "commands" : { "test" : { "command" : "echo \"$MAGIC\" >> test.txt", "env" : { "MAGIC" : "I am test 2!" }, "cwd" : "~" } } } }

YAML

AWS::CloudFormation::Init: 1: commands: test: command: "echo \"$MAGIC\" > test.txt" env: MAGIC: "I come from the environment!" cwd: "~" 2: commands: test: command: "echo \"$MAGIC\" >> test.txt" env: MAGIC: "I am test 2!" cwd: "~" configSets: test1: - "1" test2: - ConfigSet: "test1" - "2" default: - ConfigSet: "test2"

Chamadas de cfn-init relacionadas

As seguintes chamadas para cfn-init fazem referência aos configSets declarados no trecho do modelo anterior. As chamadas de exemplo são abreviadas para oferecer clareza, consulte cfn-init para obter a sintaxe completa.

  • Se você especificar apenas test1:

    cfn-init -c test1

    o cfn-init processará apenas a chave de configuração 1.

  • Se você especificar apenas test2:

    cfn-init -c test2

    o cfn-init processará a chave de configuração 1 e, em seguida, processará a chave de configuração 2.

  • Se você especificar o configset default (ou nenhum configset):

    cfn-init -c default

    Você terá o mesmo comportamento que resultaria da epecificação do configset test2.

Comandos

Você pode usar a chave de comandos para executar comandos na instância do EC2. Os comandos são processados em ordem alfabética por nome.

Chave Obrigatório Descrição

command

Obrigatório

Uma matriz ou uma string que especifica o comando a ser executado. Se você usar uma matriz, não precisará de caracteres de espaço de escape ou de aspas para parâmetros de comandos. Não use a matriz para especificar vários comandos.

env

Opcional

Define variáveis de ambiente para o comando. Essa propriedade substitui, em vez de anexar, o ambiente existente.

cwd

Opcional

O diretório de trabalho.

teste

Opcional

Um comando de teste que determina se o cfn-init executa comandos que são especificados na chave do comando. Se o teste for aprovado, o cfn-init executará os comandos. O script cfn-init executa o teste em um interpretador de comandos, como Bash ou cmd.exe. A aprovação de um teste depende do código de saída que o interpretador retorna.

No Linux, o comando de teste deve retornar um código de saída de 0 para o teste ser aprovado. No Windows, o comando de teste deve retornar um %ERRORLEVEL% de 0.

ignoreErrors

Opcional

Um valor booleano que determina se cfn-init continuará a ser executado se o comando contido na chave do comando falhar (retorna um valor diferente de zero). Defina como true se você quiser que o cfn-init continue a executar, mesmo que o comando falhe. Defina como false se quiser que o cfn-init pare de executar se o comando falhar. O valor padrão é false.

waitAfterCompletion

Opcional

Apenas para sistemas Windows. Especifica o tempo de espera (em segundos) depois que um comando foi concluído no caso do comando provocar uma reinicialização. O valor padrão é 60 segundos e um valor de "para sempre" instrui o cfn-init a sair e retomar apenas depois que a reinicialização for concluída. Defina este valor como 0 se você não quiser aguardar cada comando.

Exemplo

O trecho do exemplo a seguir chama o comando echo se o arquivo ~/test.txt não existir.

JSON

"commands" : { "test" : { "command" : "echo \"$MAGIC\" > test.txt", "env" : { "MAGIC" : "I come from the environment!" }, "cwd" : "~", "test" : "test ! -e ~/test.txt", "ignoreErrors" : "false" }, "test2" : { "command" : "echo \"$MAGIC2\" > test2.txt", "env" : { "MAGIC2" : "I come from the environment!" }, "cwd" : "~", "test" : "test ! -e ~/test2.txt", "ignoreErrors" : "false" } }

YAML

commands: test: command: "echo \"$MAGIC\" > test.txt" env: MAGIC: "I come from the environment!" cwd: "~" test: "test ! -e ~/test.txt" ignoreErrors: "false" test2: command: "echo \"$MAGIC2\" > test2.txt" env: MAGIC2: "I come from the environment!" cwd: "~" test: "test ! -e ~/test2.txt" ignoreErrors: "false"

Arquivos

Você pode usar a chave files para criar arquivos na instância do EC2. O conteúdo pode estar embutido no modelo ou o conteúdo pode ser obtido de um URL. Os arquivos são gravados em disco em ordem lexicográfica. A tabela a seguir lista as chaves com suporte.

Chave Descrição

content

Uma sequência ou um objeto JSON formatado corretamente. Se você usar um objeto JSON como seu conteúdo, o JSON será gravado em um arquivo no disco. Todas as funções intrínsecas, como Fn::GetAtt ou Ref são avaliadas antes do objeto JSON ser gravado em disco. Ao criar um symlink, especifique o destino do symlink, como o conteúdo.

nota

Se você criar um symlink, o script auxiliar modificará as permissões do arquivo de destino. No momento, você não pode criar um symlink sem modificar as permissões do arquivo de destino.

origem

Um URL do qual carregar o arquivo. Essa opção não pode ser especificada com a chave de conteúdo.

encoding

O formato de codificação. Usado apenas se o conteúdo for uma sequência. A codificação não será aplicada se você estiver usando uma origem.

Valores válidos: plain | base64

group

O nome do grupo que possui este arquivo. Sem suporte para sistemas Windows.

owner

O nome do usuário que possui este arquivo. Sem suporte para sistemas Windows.

modo

Um valor octal de seis dígitos que representa o modo para este arquivo. Sem suporte para sistemas Windows. Use os primeiros três dígitos para symlinks e os três últimos dígitos para configurar permissões. Para criar um symlink, especifique 120xxx, em que xxx define as permissões do arquivo de destino. Para especificar permissões para um arquivo, use os últimos três dígitos, como 000644.

authentication

O nome de um método de autenticação a ser usado. Isso substitui qualquer autenticação padrão. Você pode usar essa propriedade para selecionar um método de autenticação que você define com o recurso AWS::CloudFormation::Authentication.

context

Especifica um contexto para arquivos que devem ser processados como modelos Mustache. Para usar essa chave, você deve ter instalado o aws-cfn-bootstrap 1.3–11 ou posterior, além de pystache.

Exemplos

O trecho do exemplo a seguir cria um arquivo chamado setup.mysql como parte de uma instalação maior.

JSON

"files" : { "/tmp/setup.mysql" : { "content" : { "Fn::Join" : ["", [ "CREATE DATABASE ", { "Ref" : "DBName" }, ";\n", "CREATE USER '", { "Ref" : "DBUsername" }, "'@'localhost' IDENTIFIED BY '", { "Ref" : "DBPassword" }, "';\n", "GRANT ALL ON ", { "Ref" : "DBName" }, ".* TO '", { "Ref" : "DBUsername" }, "'@'localhost';\n", "FLUSH PRIVILEGES;\n" ]]}, "mode" : "000644", "owner" : "root", "group" : "root" } }

YAML

files: /tmp/setup.mysql: content: !Sub | CREATE DATABASE ${DBName}; CREATE USER '${DBUsername}'@'localhost' IDENTIFIED BY '${DBPassword}'; GRANT ALL ON ${DBName}.* TO '${DBUsername}'@'localhost'; FLUSH PRIVILEGES; mode: "000644" owner: "root" group: "root"

O modelo completo está disponível em: https://s3.amazonaws.com/cloudformation-templates-us-east-1/Drupal_Single_Instance.template

O trecho do exemplo a seguir cria um symlink /tmp/myfile2.txt que aponta para um arquivo /tmp/myfile1.txt existente. As permissões do arquivo de destino /tmp/myfile1.txt são definidas pelo valor do modo 644.

JSON

"files" : { "/tmp/myfile2.txt" : { "content" : "/tmp/myfile1.txt", "mode" : "120644" } }

YAML

files: /tmp/myfile2.txt: content: "/tmp/myfile1.txt" mode: "120644"

Modelos do Mustache são usados principalmente para criar arquivos de configuração. Por exemplo, você pode armazenar um arquivo de configuração em um bucket do S3 e interpolar Refs e GetAtts no modelo, em vez de usar Fn::Join. O trecho do exemplo a seguir resulta em "Content for test9" para /tmp/test9.txt.

JSON

"files" : { "/tmp/test9.txt" : { "content" : "Content for {{name}}", "context" : { "name" : "test9" } } }

YAML

files: /tmp/test9.txt: content: "Content for {{name}}" context: name: "test9"

Ao trabalhar com modelos do Mustache, observe o seguinte:

  • A chave de contexto deve estar presente para os arquivos a serem processados.

  • A chave de contexto deve ser um mapa de chave/valor, mas pode estar aninhada.

  • Você pode processar arquivos com conteúdo embutido usando a chave de conteúdo e arquivos remotos usando a chave de origem.

  • O suporte ao Mustache depende da versão do pystache. A versão 0.5.2 oferece suporte à especificação do Mustache 1.1.2.

Grupos

Você pode usar a chave de grupos para criar grupos do Linux/UNIX e para atribuir IDs de grupos. A chave de grupos não tem suporte em sistemas Windows.

Para criar um grupo, adicione um novo par de chave/valor que mapeie um novo nome de grupo para um ID de grupo opcional. A chave de grupos pode conter um ou mais nomes de grupos. A tabela a seguir lista as chaves disponíveis.

Chave Descrição

gid

Um número de ID de grupo.

Se um ID de grupo for especificado e o grupo já existir por nome, a criação do grupo não terá êxito. Se outro grupo tiver o ID de grupo especificado, o sistema operacional poderá rejeitar a criação do grupo.

Exemplo: { "gid" : "23" }

Trecho de exemplo

O trecho a seguir especifica um grupo chamado groupOne sem atribuição de um ID de grupo e um grupo chamado groupTwo que especificou um valor de ID de grupo de 45.

JSON

"groups" : { "groupOne" : {}, "groupTwo" : { "gid" : "45" } }

YAML

groups: groupOne: {} groupTwo: gid: "45"

Pacotes

Você pode usar a chave de pacotes para fazer download e instalar aplicativos e componentes pré-empacotados. Em sistemas Windows, a chave de pacotes oferece suporte ao instalador MSI.

Formatos de pacote com suporte

Atualmente, o script cfn-init oferece suporte aos seguintes formatos de pacote: apt, msi, python, rpm, rubygems, yum e Zypper. Os pacotes são processados na seguinte ordem: rpm, yum/apt/zypper e, em seguida, rubygems e python. Não há nenhuma ordem entre rubygems e python, e não há garantia de que os pacotes dentro de cada gerenciador sejam instalados em qualquer ordem.

Como especificar versões

Dentro de cada gerenciador de pacotes, cada pacote é especificado como um nome de pacote e uma lista de versões. A versão pode ser uma sequência, uma lista de versões ou uma sequência ou lista vazia. Uma sequência ou lista vazia indica que você deseja a versão mais recente. Para o gerenciador de rpm, a versão é especificada como um caminho para um arquivo no disco ou um URL.

Se você especificar uma versão de um pacote, o cfn-init tentará instalar essa versão, mesmo que uma versão mais recente do pacote já esteja instalada na instância. Alguns gerenciadores de pacotes oferecem suporte a várias versões, mas outros não. Verifique a documentação do seu gerenciador de pacotes para mais informações. Se você não especificar uma versão e uma versão do pacote já estiver instalada, o script cfn-init não instalará uma nova versão – ele pressuporá que você quer manter e usar a versão atual.

Trechos de exemplo

RPM, yum, Rubygems e Zypper

O trecho a seguir especifica um URL da versão para rpm, solicita as versões mais recentes do yum e Zypper e a versão 0.10.2 de chef do rubygems.

JSON
"rpm" : { "epel" : "http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm" }, "yum" : { "httpd" : [], "php" : [], "wordpress" : [] }, "rubygems" : { "chef" : [ "0.10.2" ] }, "zypper" : { "git" : [] }
YAML
rpm: epel: "http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm" yum: httpd: [] php: [] wordpress: [] rubygems: chef: - "0.10.2" zypper: git: []

Pacote MSI

O trecho a seguir especifica um URL para um pacote MSI:

JSON
"msi" : { "awscli" : "https://s3.amazonaws.com/aws-cli/AWSCLI64.msi" }
YAML
msi: awscli: "https://s3.amazonaws.com/aws-cli/AWSCLI64.msi"

Serviços

Você pode usar a chave de serviços para definir quais serviços devem ser habilitados ou desabilitados quando a instância for executada. Em sistemas Linux, essa chave tem suporte usando sysvinit ou systemd. Em sistemas Windows, ele tem compatibilidade usando o gerenciador de serviços do Windows.

A chave de serviço também permite que você especifique dependências de origens, pacotes e arquivos, de forma que, se uma reinicialização for necessária devido a arquivos que estão sendo instalados, o cfn-init cuidará da reinicialização do serviço. Por exemplo, se você fizer download do pacote Apache HTTP Server, a instalação do pacote iniciará automaticamente o Apache HTTP Server durante o processo de criação da pilha. No entanto, se a configuração do Apache HTTP Server for atualizada posteriormente no processo de criação da pilha, a atualização não terá efeito, a menos que o servidor Apache seja reiniciado. Você pode usar a chave de serviços para garantir que o serviço do Apache HTTP seja reiniciado.

A tabela a seguir lista as chaves com suporte.

Chave Descrição

ensureRunning

Defina como true para garantir que o serviço esteja em execução quando o cfn-init for concluído.

Defina como false para garantir que o serviço não esteja em execução quando o cfn-init for concluído.

Omita essa chave para não fazer nenhuma alteração no estado do serviço.

habilitado

Defina como true para garantir que o serviço seja iniciado automaticamente na inicialização.

Defina como false para garantir que o serviço não seja iniciado automaticamente na inicialização.

Omita essa chave para não fazer nenhuma alteração nessa propriedade.

files

Uma lista de arquivos. Se cfn-init alterar um diretamente por meio do bloco de arquivos, esse serviço será reiniciado.

sources

Uma lista de diretórios. Se o cfn-init expandir um arquivo em um desses diretórios, esse serviço será reiniciado.

packages

Um mapa do gerenciador de pacotes para a lista de nomes de pacotes. Se o cfn-init instalar ou atualizar um desses pacotes, esse serviço será reiniciado.

comandos

Uma lista de nomes de comandos. Se o cfn-init executar o comando especificado, esse serviço será reiniciado.

Exemplos

Linux

O trecho do Linux a seguir configura os serviços da seguinte forma:

  • O serviço nginx será reiniciado se um /etc/nginx/nginx.conf ou /var/www/html for modificado pelo cfn-init.

  • O serviço php-fastcgi será reiniciado se cfn-init instalar ou atualizar o php ou o spawn-fcgi usando yum.

  • O serviço sendmail será interrompido e desabilitado usando systemd.

JSON
"services" : { "sysvinit" : { "nginx" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["/etc/nginx/nginx.conf"], "sources" : ["/var/www/html"] }, "php-fastcgi" : { "enabled" : "true", "ensureRunning" : "true", "packages" : { "yum" : ["php", "spawn-fcgi"] } } }, "systemd": { "sendmail" : { "enabled" : "false", "ensureRunning" : "false" } } }
YAML
services: sysvinit: nginx: enabled: "true" ensureRunning: "true" files: - "/etc/nginx/nginx.conf" sources: - "/var/www/html" php-fastcgi: enabled: "true" ensureRunning: "true" packages: yum: - "php" - "spawn-fcgi" systemd: sendmail: enabled: "false" ensureRunning: "false"

Para utilizar systemd com um serviço, este deve ter um arquivo de unidade systemd configurado. O seguinte arquivo de unidade permite que systemd inicie e interrompa o daemon cfn-hup no destino de serviço multiusuário:

[Unit] Description=cfn-hup daemon [Service] ExecStart=/usr/bin/cfn-hup -v PIDFile=/var/run/cfn-hup.pid [Install] WantedBy=multi-user.target

Essa configuração pressupõe que cfn-hup esteja instalado no diretório /usr/bin. Porém, o local real de instalação de cfn-hup pode variar dependendo da plataforma. É possível substituir essa configuração criando um arquivo de substituição em /etc/systemd/system/cfn-hup.service.d/override.conf, da seguinte maneira:

# In this example, cfn-hup executable is available under /usr/local/bin [Service] ExecStart= ExecStart=/usr/local/bin/cfn-hup -v

Windows

O trecho do Windows a seguir iniciará o serviço cfn-hup, definirá o serviço como automático e reiniciará o serviço se o cfn-init modificar os arquivos de configuração especificados:

JSON
"services" : { "windows" : { "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", "files" : ["c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"] } } }
YAML
services: windows: cfn-hup: enabled: "true" ensureRunning: "true" files: - "c:\\cfn\\cfn-hup.conf" - "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"

Origens

Você pode usar as chaves de origem para fazer download de um arquivo morto e desempacotá-lo em um diretório de destino na instância EC2. Essa chave tem suporte total nos sistemas Linux e Windows.

Formatos com compatibilidade

Os formatos com suporte são:

  • tar

  • tar+gzip

  • tar+bz2

  • zip

Exemplos

GitHub

Se usar o GitHub como um sistema de controle de origem, você poderá usar o cfn-init e o mecanismo de pacotes de origem para extrair uma versão específica de seu aplicativo. O GitHub permite que você crie um .zip ou um .tar a partir de uma versão específica por meio de um URL da seguinte forma:

https://github.com/<your directory>/(zipball|tarball)/<version>

Por exemplo, o trecho a seguir extrai a versão principal como um arquivo .tar.

JSON
"sources" : { "/etc/puppet" : "https://github.com/user1/cfn-demo/tarball/main" }
YAML
sources: /etc/puppet: "https://github.com/user1/cfn-demo/tarball/main"

S3 Bucket

O exemplo a seguir baixa um tarball de um bucket do S3 e o descompacta em /etc/myapp.

nota

Você pode usar credenciais de autenticação para uma origem. No entanto, você não pode colocar uma chave de autenticação no bloco de origens. Em vez disso, inclua uma chave de buckets no seu bloco S3AccessCreds. Para obter mais informações sobre as credenciais de autenticação do Amazon S3, consulte AWS::CloudFormation::Authentication.

Para obter um exemplo, consulte o modelo de exemplo.

JSON
"sources" : { "/etc/myapp" : "https://s3.amazonaws.com/mybucket/myapp.tar.gz" }
YAML
sources: /etc/myapp: "https://s3.amazonaws.com/mybucket/myapp.tar.gz"

Usuários

Você pode usar a chave de usuários para criar usuários Linux/UNIX na instância EC2. A chave de usuários não tem suporte em sistemas Windows.

A tabela a seguir lista as chaves com suporte.

Chave Descrição

uid

Um ID de usuário. Haverá falha no processo de criação se o nome do usuário existir com outro ID de usuário. Se o ID de usuário já estiver atribuído a um usuário existente, o sistema operacional poderá rejeitar a solicitação de criação.

groups

Uma lista de nomes de grupos. O usuário será adicionado a cada grupo na lista.

homeDir

O diretório base de usuário.

Exemplo

Os usuários são criados como usuários do sistema não interativos com um shell de /sbin/nologin. Este é o design e não pode ser modificado.

JSON

"users" : { "myUser" : { "groups" : ["groupOne", "groupTwo"], "uid" : "50", "homeDir" : "/tmp" } }

YAML

users: myUser: groups: - "groupOne" - "groupTwo" uid: "50" homeDir: "/tmp"