Na minha organização, temos várias AMIs básicas simples de usar para diferentes serviços, como ECS e Docker. Como muitos de nossos projetos envolvem o CloudFormation, estamos usando o cfn-bootstrap
, que consiste em alguns scripts e um serviço executado na inicialização para instalar determinados pacotes e executar determinadas tarefas de gerenciamento de configuração para nós.
Na inicialização de um sistema, um script equivalente ao seguinte deve ser executado:
#!/bin/bash
# capture stderr only
output="$(cfn-init -s $STACK_NAME -r $RESOURCE_NAME --region $REGION >/dev/null)"
# if it failed, signal to CloudFormation that it failed and include a reason
returncode=$?
if [[ $returncode == 0]]; then
cfn-signal -e $returncode -r "$output"
exit $returncode
fi
# otherwise, signal success
cfn-signal -s
Eu estava pensando em executar isso como um serviço systemd oneshot
que executa After=network.target
e WantedBy=multi-user.target
.
O único problema é que eu gostaria que minha AMI fosse flexível e só a executasse se um determinado arquivo existir. Em vez de incorporar o script acima nos dados do usuário do EC2, posso fazer com que os dados do usuário definam apenas um arquivo de ambiente que define as variáveis necessárias e execute apenas meu serviço único se esse arquivo de ambiente existir:
#cloud-init
write_files:
- path: /etc/sysconfig/cloudformation
# ...
content: |
CFN_STACK_NAME="stack-name"
CFN_RESOURCE="resource-name"
CFN_REGION="region"
Existe uma maneira de fazer com que o systemd execute apenas um serviço se uma determinada condição for atendida?
O systemd fornece uma ampla variedade de condições que você pode testar . Por exemplo, você pode usar
ConditionPathExists=
para testar a existência de um arquivo.Eu me deparei com essa questão procurando maneiras de iniciar um serviço systemd usando uma condição. Existem muitos caminhos:
ConditionArchitecture=, ConditionVirtualization=, ConditionHost=, ConditionKernelCommandLine=, ConditionSecurity=, ConditionCapability=, ConditionACPower=, ConditionNeedsUpdate=, ConditionFirstBoot=, ConditionPathExists=, ConditionPathExistsGlob=, ConditionPathIsDirectory=, ConditionPathIsSymbolicLink=, ConditionPathIsMountPoint=, ConditionPathIsReadWrite=, ConditionDirectoryNotEmpty=, ConditionFileNotEmpty=, ConditionFileIsExecutable=
Eu queria iniciar o serviço com base em um nome de host específico.
ConditionHost
= pode ser usado para corresponder ao nome do host ou ID da máquina do host. Isso leva uma string de nome de host (opcionalmente com globs de estilo shell) que é testada contra o nome de host definido localmente conforme retornado por gethostname(2) ou uma ID de máquina formatada como string (consulte machine-id(5)). O teste pode ser anulado adicionando um ponto de exclamação.Mais sobre isso aqui .