Agile DevOps: Faça Versão de Tudo

Saiba por que todas as partes de um sistema de software deve usar controle de versão

Você deve criar versão de que tipos de artefatos do sistema de software? Nesta parte do artigo Agile DevOps , o especialista em DevOps Paul Duvall recomenda que as equipes de DevOps criem versão de código do aplicativo, infraestrutura, configuração, dados e, até mesmo, de artefatos do sistema interno para ter capacidade de entregar software a usuários de forma rápida e frequente.

Paul Duvall, CTO, Stelligent

Paul DuvallPaul Duvall é CTO da Stelligent. Palestrante de destaque em muitas conferências importantes sobre software, trabalhou em praticamente todas as funções em projetos de software: desenvolvedor, gerente de projeto, arquiteto e testador. É o autor principal de Continuous Integration: Improving Software Quality and Reducing Risk (Addison-Wesley, 2007) e Vencedor do 2008 Jolt Award. É autor também de Startup@Cloud e DevOps in the Cloud LiveLessons (Pearson Education, junho de 2012). Também contribuiu para diversos outros livros. Paul foi o autor da série com 20 artigos Automation for the people no developerWorks. Ele tem paixão por fornecer software de alta qualidade para usuários mais rapidamente e mais frequentemente por meio de entrega contínua e nuvem. Leia seu blog em Stelligent.com.



31/Jul/2013

Sobre esta Série

Desenvolvedores podem aprender muito de operações e operações podem aprender muito dos desenvolvedores. Esta série de artigos é dedicada a explorar os usos práticos de aplicar uma mentalidade de operações a desenvolvimento e vice-versa — e de considerar produtos de software como entidades holísticas que podem ser entregues com mais agilidade e frequência do que jamais foi feito antes.

Crie versão de tudo. Sim, tudo: infraestrutura, configuração, código do aplicativo e seu banco de dados. Se fizer isso, você terá uma fonte isolada de verdade que permite visualizar o sistema de software — e tudo que é necessário para criar o software — como uma unidade holística. Equipes que criar versão de tudo não estão constantemente tentando descobrir qual versão do código do aplicativo se encaixa com qual banco de dados e qual versão do aplicativo de software funciona com qual ambiente. Os arquivos de origem que formar o sistema de software não estão em servidores compartilhados, ocultos em pastas em um laptop ou integrados a um banco de dados sem versão.

Se você criar versão de tudo, qualquer membro autorizado da equipe deve ser capaz de recriar qualquer versão do sistema de software — o código do aplicativo, a configuração, a infraestrutura e os dados — a qualquer momento. Você deve ser capaz de criar todo o sistema de software usando somente artefatos não binários (com a exceção de bibliotecas que você não modifica) que são vinculados a um repositório de controle de versão (como Subversion, Git, CVS ou Rational ClearCase, só para citar alguns exemplos).

Em minha experiência, a ideia de criar versão de tudo é simples de entender, mas raramente a vejo totalmente aplicada. É claro que você verá criação de versão do código do aplicativo, de parte da configuração e, possivelmente, dos dados. Algumas equipes usam repositórios e ferramentas de dependência (Nexus, por exemplo) para gerenciar bibliotecas que usam no desenvolvimento do software. Outras equipes usam uma combinação de unidades compartilhadas e sistemas de controle de versão. No entanto, é menos comum ver as empresas criarem versão de toda a configuração, de todos os seus componentes dependentes (por exemplo, de repositórios de pacotes, como yum, apt-get e rpm) e de todos os scripts necessários para criar o banco de dados e os dados que formam o banco de dados.

Para determinar se você está criando versão de tudo, a pergunta simples que deve ser feita é: "Posso recriar uma versão específica de todo o sistema de software — com infraestrutura, dados, software e configuração — executando um comando que obtém uma revisão específica de meu sistema de controle de versão?" Se não puder, você não está criando versão de tudo.

Diversos Repositórios

Por razões legítimas, pode ser necessário usar diversos repositórios de origem ou repositórios de gerenciamento de dependência e manter itens de configuração em um banco de dados com versão. Uma técnica efetiva neste caso é aplicar um versão lógica aos diversos repositórios como uma maneira de gerar a "lista de materiais" que pode ser usada para identificar cada revisão do sistema de software.

O pré-requisito chave para criar versão de tudo é que todos os artefatos de origem devem estar em um formato de script. Isso se aplica à infraestrutura, aos dados, à configuração e ao código do aplicativo. A única exceção é para bibliotecas e pacotes — arquivos JAR e pacotes RPM, por exemplo — que são usados, mas nunca modificados. Após todos os artefatos de origem serem colocados em script, será possível criar versão dos mesmos facilmente.

Neste artigo, você aprenderá como cada tipo de artefato de software pode ser descrito em código e as abordagens efetivas para usá-los. Diversas listagens de código neste artigo são exemplos de como cada componente é definido como script para execução e criação de versão. Elas não têm a intenção de mostrar como escrever e executar cada tipo de script. Outros artigos desta série Agile DevOps e da série Automation for the people fornecem exemplos mais detalhados para os componentes descritos neste artigo.

Código do Aplicativo

O código do aplicativo é provavelmente a parte mais óbvia do sistema de software que deve ter versão criada. O código na Listagem 1 é uma classe Java simples (chamada UserServiceImpl) que chama um método de um objeto para obter alguns dados:

Listagem 1. Código do Aplicativo Java
...
public Collection findAllStates() {
    UserDao userData = new UserDaoImpl();
    Collection states = userData.findAllStates(UserDao.ALL_STATES);
    return states;
}
...

A Figura 1 ilustra a vinculação de um novo arquivo de origem de código do aplicativo — o UserServiceImpl.java na Listagem 1— ao repositório de controle de versão Git hospedado em GitHub:

Figura 1. Comandos para Vincular e Realizar o Push do Novo Arquivo de Código-Fonte para um Repositório Git
Comandos para Vincular e Realizar o Push do Novo Arquivo de Código-Fonte para um Repositório Git

Todo o código do aplicativo necessário para criar seu aplicativo de software deve ser vinculado a um repositório de controle de versão. O mesmo processo será usado para qualquer outro arquivo de origem — código da infraestrutura, dados ou configuração.


Infraestrutura

Como é possível definir a infraestrutura como código da mesma forma que você faz com seus arquivos de origem do aplicativo (consulte "Agile DevOps: Automação de infraestrutura"), é possível criar a versão de sua infraestrutura em um sistema de controle de versão. Esses scripts podem ter designações como manifestos, módulos e livros de receita, mas são todos scripts baseados em texto que podem ser executados para criar ambientes.

Se a melhor prática for definir sua infraestrutura em código, o que as pessoas geralmente fazem? Um pacote combinado de "trabalhos de arte" em que ambientes são manualmente configurados toda vez ou uma combinação de etapas manuais e execução de scripts automatizados. Cada uma dessas abordagens resulta em um gargalo, pois um engenheiro precisa executar as etapas toda vez. Para remediar isso, alguns irão descrever de forma diligente cada e toda etapa em um conjunto de instruções por escrito. O problema é que instruções podem estar erradas ou ignorar algumas etapas ou o operador que estiver executando as etapas pode não segui-las corretamente. A única solução é descrever completamente sua infraestrutura em código que possa ser executado por meio de um único comando.

Por exemplo, o manifesto Puppet na Listagem 2 descreve etapas para instalar um servidor de banco de dados PostgreSQL em código. Esse código pode ser executado a partir da linha de comandos ou por meio de um servidor Continuous Integration (CI).

Listagem 2. Manifesto Puppet Descrevendo a Instalação de PostgreSQL
class postgresql {
  
  package { "postgresql8-server":
    ensure => installed,
  }
  
  exec { "initdb":
    unless => "[ -d /var/lib/postgresql/data ]",
    command => "service postgresql initdb",
    require => Package["postgresql8-server"]
  }
...

O manifesto completo faz download, instala e executa o servidor. Usando manifestos adicionais, é possível descrever todo seu ambiente em scripts. Esses scripts podem ter registro de entrada em seu repositório de controle de versão para que cada revisão em sua infraestrutura seja controlada, melhorando o gerenciamento de mudanças.


Configuração

A configuração define as informações que variam entre os ambientes. Exemplos incluem locais de diretórios e arquivos, nomes de hosts, endereços IP e portas de servidores, conforme mostrado na Listagem 3. Scripts usam essa configuração ao criarem ambientes, executarem desenvolvimentos e implementações e executarem testes:

Listagem 3. Configuração Definida em um Arquivo de Propriedades
jboss.home=/usr/local/jboss
jboss.server.hostname=jenkins.example.com
jboss.server.port=8080
jboss.server.name=default

O código na Listagem 4 é um script Ruby que carrega itens de configuração em um banco de dados NoSQL:

Listagem 4. Gravando Itens de Configuração Dinâmica em um Banco de Dados NoSQL
AWS::SimpleDB.consistent_reads do
  domain = sdb.domains["stacks"]
  item = domain.items["#{opts[:itemname]}"]
  
  file.each_line do|line|
    key,value = line.split '='
    item.attributes.set(
      "#{key}" => "#{value}")
  end
end

Como toda a configuração na Listagem 4— como endereços IP, nomes de domínios e imagens de máquina — pode ser obtida dinamicamente, nenhuma parte da configuração é codificada permanentemente. Pode ser que não seja possível tornar toda sua configuração dinâmica, mas, ao usar a nuvem, é possível reduzir drasticamente a quantia de configuração codificada permanentemente que é frequentemente a maldição da maioria dos sistemas de entrega de software.


Dados

Criar script e versão não dá muito trabalho?

Quando descrevi o conceito de criar script de banco de dados, dados e mudanças recentemente, alguém respondeu: "Isso parece muito trabalho!" Minha resposta foi que é muito mais trabalho, e arriscado, manter um banco de dados cujo estado você nunca realmente conhece. Quando um banco de dados é uma "caixa preta", as únicas pessoas que podem mantê-lo são alguns DBAs de um projeto que dependem de sua memória para manter o banco de dados em execução — porque nenhuma mudança de dados tem versão.

A estrutura de um banco de dados relacional pode ser definida em scripts de Linguagem de Definição de Dados (DDL). Isso inclui a criação do banco de dados, tabelas, procedimentos etc. — tudo, exceto dos dados. Os dados são definidos nos scripts de Linguagem de Manipulação de Dados (DML), incluindo instruções de inserção, atualização e exclusão.

O script DDL parcial mostrado na Listagem 5 executa as etapas para criar o banco de dados:

Listagem 5. DDL para Criar Tabelas de Banco de Dados
CREATE SEQUENCE hibernate_sequence START WITH 1 INCREMENT BY 1 NO MINVALUE \
NO MAXVALUE CACHE 1;
ALTER TABLE public.hibernate_sequence OWNER TO cd_user;

CREATE TABLE note ( id bigint NOT NULL, version bigint NOT NULL, cd_id bigint NOT NULL, \
note character varying(10000) NOT NULL, note_date_time timestamp without time zone \
NOT NULL);
ALTER TABLE public.note OWNER TO cd_user;
...

A Listagem 6 mostra uma parte de um script XML Liquibase. Liquibase é uma domain-specific language (DSL) de software livre para gerenciamento de mudanças do banco de dados.

Listagem 6. Script Liquibase para Alterar uma Coluna em um Banco de Dados Existente
<changeSet id="9" author="jayne">
  <addColumn tableName="distributor">
    <column name="phonenumber" type="varchar(255)"/>
  </addColumn> 
</changeSet>
...

É possível definir a criação do banco de dados, dos dados e as mudanças em scripts. Esses scripts são executados como parte de seu processo de desenvolvimento e todos eles têm versão criada e, seu repositório de controle de versão.


Desenvolvimento e Implementação

Um desenvolvimento compila e empacota todos os arquivos de origem em uma distribuição. Para o código do aplicativo, essa distribuição é frequentemente um binário, como um arquivo WAR. Um desenvolvimento pode executar scripts de infraestrutura para criar um ambiente. Esse ambiente pode ser uma instância virtual ou uma imagem que pode definir uma instância. Um desenvolvimento também pode produzir um banco de dados a partir de scripts do banco de dados. Desenvolvimentos usam a configuração definida em arquivos de configuração ou banco de dados. A Listagem 7 mostra uma parte de um script de desenvolvimento Maven que define diretórios e configuração para um desenvolvimento:

Listagem 7. Listagem Parcial de um Script de Desenvolvimento em Maven
...
<build>
  <finalName>embeddedTomcatSample</finalName>
  <plugins>
      <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>appassembler-maven-plugin</artifactId>
          <version>1.1.1</version>
          <configuration>
              <assembleDirectory>target</assembleDirectory>
              <programs>
                  <program>
                      <mainClass>launch.Main</mainClass>
                      <name>webapp</name>
                  </program>
              </programs>
          </configuration>
          <executions>
              <execution>
                  <phase>package</phase>
                  <goals>
                      <goal>assemble</goal>
                  </goals>
              </execution>
          </executions>
      </plugin>
  </plugins>
</build>
...

Diversos fornecedores fornecem as chamadas "ferramentas de automação de implementação". A denominação é um pouco incorreta. Essas ferramentas provavelmente orquestram a implementação, não a automatizam. Elas ajudam a descrever as etapas e ordem da implementação, mas a implementação em si é feita por uma série de scripts e/ou processos manuais. Raramente são encontradas ferramentas que suportam a criação de versão dos artefatos de implementação e do fluxo de trabalho. Apesar de diversas dessas ferramentas fornecerem criação de versão interna, isso é de pouco uso quando se está procurando uma única revisão de seu sistema de software, a menos que você sempre use essa ferramenta — e, ainda assim, ela segrega a criação de versão da implementação e de outros artefatos de origem. Não precisa ser assim — mesmo se você estiver usando as ferramentas de um desses fornecedores. Uma abordagem alternativa é descrever sua implementação inteira em uma DSL de automação de implementação, como Capistrano. Dessa maneira, será possível criar versão de sua implementação. Deve ser possível executar toda a implementação com um comando. A implementação automatizada deve ser acoplada a testes automatizados. A ferramenta de orquestração executa o script de implementação.

Capistrano é uma DSL para descrever implementações em diversas plataformas. Com Capistrano, é possível definir tarefas, como parar servidores, copiar arquivos e aplicar um fluxo de trabalho para implementações em diversos nós e funções do ambiente. A Listagem 8 mostra uma parte de um script Capistrano:

Listagem 8. Script de Implementação Parcial em Capistrano
namespace :deploy do
  task :setup do
    run "sudo chown -R tomcat:tomcat #{deploy_to}"
    run "sudo service httpd stop"
    run "sudo service tomcat6 stop"
  end

...

Usar uma DSL é uma maneira efetiva de descrever suas implementações. Como todas as etapas para implementação são scripts e não são fortemente acopladas a uma ferramenta proprietária, o método alinha-se bem com equipes que estão implementando um pipeline de entrega contínua. Após suas implementações serem definidas como scripts, elas podem ter versão criada da mesma maneira que qualquer outro componente de seu pipeline de entrega.


Sistemas

Há um consenso crescente entre equipes progressivas de que criação de versão da infraestrutura, configuração, dados e código do aplicativo é desejável. Um componente adicional que também pode ter versão criada é sistemas internos — por exemplo, a configuração para definir seus ambientes CI. A pergunta a ser feita é: O que ocorre em seu sistema de software se os ambientes usados para criar partes de seu sistema de entrega de software não estiverem mais funcionando? Após criar scripts para todos os ambientes para seu sistema de software, é possível criar script de todos os ambientes para criar seu sistema de entrega de software com ferramentas de automação de infraestrutura. Esse código de infraestrutura e as mudanças em sua configuração CI — como configuração de tarefa CI — têm versão criada. Um exemplo de criação de versão de servidor Jenkins e configurações de tarefas é mostrado na Listagem 9:

Listagem 9. Script bash Simples para Criação de Versão de Mudanças de Configuração do Servidor Jenkins
#!/bin/bash -v

# Change into your jenkins home.
cd /usr/share/tomcat6/.jenkins

# Add any new conf files, jobs, users, and content.
git add *.xml jobs/*/config.xml plugins/*.hpi .gitignore

# Ignore things we don't care about
cat > .gitignore <<EOF
log
*.log
*.tmp
*.old
*.bak
*.jar
.*
updates/
jobs/*/builds
jobs/*/last*
jobs/*/next*
jobs/*/*.csv
jobs/*/*.txt
jobs/*/*.log
jobs/*/workspace
EOF

# Remove anything from git that no longer exists in jenkins.
git status --porcelain | grep '^ D ' | awk '{print $2;}' | xargs -r git rm

# And finally, commit and push
git commit -m 'Automated commit of jenkins configuration' -a
git push

Assim como é possível fazer com qualquer outra parte de seu sistema de software, é possível criar versão desse script em seu repositório de controle de versão.


Crie Versão disto

Participe

Biblioteca técnica do Transformação Agile fornece notícias, discussões e treinamento para ajudar a você e à sua organização a desenvolver uma base em princípios de desenvolvimento agile.

Neste artigo, você aprendeu que tudo pode e tem versão criada quando desenvolvedores e equipes de operações colaboram na criação de uma plataforma de entrega contínua de liberação de software em qualquer momento. Você viu que quando toda a infraestrutura, dados e recursos de aplicativos têm versão criada, também é possível criar versão dos componentes que formam os sistemas que executam a entrega de software para seus sistemas de software. Após cada recurso para os sistemas de software desenvolvidos para usuários e os sistemas internos usados para fornecer esses sistemas de software a usuários serem colocados em script, tudo pode ter versão criada.

No próximo artigo, você aprenderá sobre gerenciamento de configuração dinâmica: uma abordagem para eliminar o uso de propriedades específicas do ambiente estático para configuração.

Recursos

Aprender

Obter produtos e tecnologias

  • Rational ClearCase: O Rational ClearCase fornece controle de versão sofisticado, gerenciamento da área de trabalho, suporte a desenvolvimento paralelo e auditoria de desenvolvimento para melhorar a produtividade.
  • IBM Tivoli Provisioning Manager: O Tivoli Provisioning Manager permite uma infraestrutura dinâmica automatizando o gerenciamento de servidores físicos, servidores virtuais, software, armazenamento e redes.
  • IBM Tivoli System Automation for Multiplatforms: O Tivoli System Automation for Multiplatforms fornece alta disponibilidade e automação para aplicativos corporativos e serviços de TI.
  • Avalie os produtos IBM da maneira que for melhor para você: faça download da versão de teste de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na Sandbox da SOA aprendendo a implementar Arquitetura Orientada a Serviços de modo eficiente.

Discutir

  • Participe da comunidade do developerWorks. Conecte-se a outros usuários do developerWorks enquanto estiver explorando os blogs, fóruns, grupos e wikis direcionados a desenvolvedores.
  • A comunidade Agile Transformation do developerWorks fornece notícias, discussões e treinamento para ajudar a você e à sua organização a desenvolver uma base em princípios de desenvolvimento agile.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre, Tecnologia Java
ArticleID=939251
ArticleTitle=Agile DevOps: Faça Versão de Tudo
publish-date=07312013