'Is getting Ansible to work with Pulumi possible?
I wish to create several droplets (DigitalOcean) in a loop and then run Ansible afterwards on the droplets to setup the required software and security measures. Is this possible like terraform? If so, how would this look in javascript/typescript code?
There isn't anything in google that has any examples to create this or any mention of Pulumi with Ansible.
Solution 1:[1]
Yes, this is possible.
You can do it one of 2 ways:
You can specify your ansible run inside the userdata of the DigitalOcean droplet. This works across all language SDKs.
Alternatively, if you want to have similar functionality to Terraform's remote-exec provisioner, you can use Pulumi's dynamic providers to create a provisioner.
Dynamic Providers are currently available in the TypeScript and Python SDKs. You can find python example here and a TypeScript example here
Solution 2:[2]
Here is an example of how you can use it to deploy wordpress via a playbook using local.Command provider and letting ansible provision on a remote host
import * as command from '@pulumi/command'
import * as pulumi from '@pulumi/pulumi'
import * as fs from 'fs'
import {URL} from 'url'
import YAML from 'yaml'
const __dirname = new URL('.', import.meta.url).pathname
nunjucks.configure(`${__dirname}/templates`)
export interface WordPressArgs {
fqdn: pulumi.Input<string>
ip: pulumi.Input<string>
sshPort: pulumi.Input<number>
sshPrivateKey: pulumi.Input<string>
sshUser: pulumi.Input<string>
domainUser: pulumi.Input<string>
domainUserHomeDir?: pulumi.Input<string>
domainUserDocumentRootDir?: pulumi.Input<string>
nginxUser?: pulumi.Input<string>
wordpressLanguage?: pulumi.Input<string>
wordpressDbName: pulumi.Input<string>
wordpressDbUser: pulumi.Input<string>
wordpressDbPassword: pulumi.Input<string>
wordpressDbHost?: pulumi.Input<string>
wordpressTitle?: pulumi.Input<string>
wordpressAdminUser?: pulumi.Input<string>
wordpressAdminPassword: pulumi.Input<string>
wordpressAdminEmail?: pulumi.Input<string>
deploymentEnvironment?: pulumi.Input<'production' | 'staging' | 'testing'>
}
export class WordPress extends pulumi.ComponentResource {
private readonly wordPressInstallCommand: pulumi.Output<string>
constructor(
name: string,
args: WordPressArgs,
opts?: pulumi.ComponentResourceOptions
) {
super('system:virtualmin:wordpress', name, {}, opts)
const cmd = pulumi
.all(
[
args.fqdn,
args.ip,
args.sshPort,
args.sshUser,
args.sshPrivateKey,
args.domainUser,
args.nginxUser,
args.wordpressLanguage,
args.wordpressDbHost,
args.wordpressDbName,
args.wordpressDbUser,
args.wordpressDbPassword,
args.wordpressTitle,
args.wordpressAdminUser,
args.wordpressAdminPassword,
args.wordpressAdminEmail,
args.deploymentEnvironment]
)
.apply((
[
fqdn,
ip,
sshPort,
sshUser,
sshPrivateKey,
domainUser,
nginxUser,
wordpressLanguage,
wordpressDbHost,
wordpressDbName,
wordpressDbUser,
wordpressDbPassword,
wordpressTitle,
wordpressAdminUser,
wordpressAdminPassword,
wordpressAdminEmail,
deploymentEnvironment]
) => {
fs.writeFileSync(
`/tmp/ansible.pem`,
sshPrivateKey.toString(),
{mode: 0o600}
)
fs.writeFileSync(
'/tmp/inventory',
YAML.stringify(
{
all: {
hosts: {
remote: {
ansible_host: ip,
ansible_port: sshPort,
ansible_user: sshUser,
ansible_private_key_file: '/tmp/ansible.pem',
ansible_host_key_checking: false
}
}
}
}),
{mode: 0o600}
)
const playbookVars = pulumi.interpolate`${JSON.stringify({
fqdn,
deployment_environment: deploymentEnvironment || 'staging',
domain_user: domainUser,
nginx_user: nginxUser || 'www-data',
wordpress_language: wordpressLanguage || 'en_US',
wordpress_db_host: wordpressDbHost || 'localhost:3306',
wordpress_db_name: wordpressDbName,
wordpress_db_user: wordpressDbUser,
wordpress_db_password: wordpressDbPassword,
wordpress_title: wordpressTitle || 'Just a WordPress site',
wordpress_admin_user: wordpressAdminUser || 'admin',
wordpress_admin_password: wordpressAdminPassword,
wordpress_admin_email: wordpressAdminEmail,
ssl_cert_dir: '/etc/ssl/certs',
ssl_key_dir: '/etc/ssl/private'
})}`
return {create: pulumi.interpolate`ANSIBLE_STDOUT_CALLBACK=json ansible-playbook -i /tmp/inventory ${__dirname}/playbooks/install-wordpress.yaml -e '${playbookVars}'`}
}
)
this.wordPressInstallCommand = cmd.create
const wordPressInstallation = new command.local.Command(
'wordpress-installation',
{
create: this.wordPressInstallCommand,
},
{parent: this}
)
this.registerOutputs()
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | jaxxstorm |
Solution 2 | Abukamel |