mirror of
https://gitea.com/mcereda/oam.git
synced 2026-02-09 05:44:23 +00:00
chore(letsencrypt): create valid certificates
This commit is contained in:
95
examples/ansible/letsencrypt.create-certificate.yml
Normal file
95
examples/ansible/letsencrypt.create-certificate.yml
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
|
||||
- name: Create and validate an HTTPS certificate
|
||||
hosts: all
|
||||
|
||||
vars:
|
||||
common_name: service.example.org
|
||||
|
||||
pre_tasks:
|
||||
|
||||
- name: Generate private keys for an account and the certificate
|
||||
community.crypto.openssl_privatekey:
|
||||
path: "{{ item }}"
|
||||
type: RSA
|
||||
size: 4096
|
||||
with_items:
|
||||
- /tmp/{{ common_name }}.key
|
||||
- /tmp/letsencrypt.account.key.pem
|
||||
|
||||
# - name: Generate private keys for an account and the certificate - OpenSSH alternative
|
||||
# community.crypto.openssh_keypair:
|
||||
# path: "{{ item }}"
|
||||
# type: rsa
|
||||
# size: 4096
|
||||
# with_items:
|
||||
# - /tmp/{{ common_name }}.key
|
||||
# - /tmp/letsencrypt.account.key.pem
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Generate the CRS for the certificate
|
||||
community.crypto.openssl_csr:
|
||||
path: /tmp/{{ common_name }}.crs
|
||||
privatekey_path: /tmp/{{ common_name }}.key
|
||||
common_name: "{{ common_name }}"
|
||||
|
||||
- name: Create the DNS challenge for '{{ common_name }}'
|
||||
community.crypto.acme_certificate:
|
||||
challenge: dns-01
|
||||
acme_version: 2
|
||||
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
||||
account_key_src: /tmp/letsencrypt.account.key.pem
|
||||
account_email: someone@example.org
|
||||
csr: /tmp/{{ common_name }}.crs
|
||||
cert: /tmp/{{ common_name }}.crt
|
||||
terms_agreed: true
|
||||
remaining_days: 21
|
||||
register: dns_challenge
|
||||
notify: Create TXT records for challenge validation
|
||||
|
||||
handlers:
|
||||
|
||||
- name: Create TXT records for challenge validation
|
||||
when: common_name in dns_challenge.challenge_data
|
||||
amazon.aws.route53:
|
||||
zone: example.org
|
||||
record: "{{ dns_challenge.challenge_data[common_name]['dns-01'].record }}"
|
||||
type: TXT
|
||||
ttl: 60
|
||||
state: present
|
||||
overwrite: true
|
||||
wait: true
|
||||
value:
|
||||
# Value should be enclosed in quotation marks
|
||||
>-
|
||||
{{
|
||||
dns_challenge.challenge_data[common_name]['dns-01'].resource_value
|
||||
| regex_replace('^(.*)$', '"\1"')
|
||||
}}
|
||||
notify: Validate the challenge and create the certificate
|
||||
|
||||
- name: Validate the challenge and create the certificate
|
||||
community.crypto.acme_certificate:
|
||||
challenge: dns-01
|
||||
acme_version: 2
|
||||
acme_directory: https://acme-v02.api.letsencrypt.org/directory
|
||||
account_key_src: /tmp/letsencrypt.account.key.pem
|
||||
account_email: someone@example.org
|
||||
csr: /tmp/{{ common_name }}.crs
|
||||
cert: /tmp/{{ common_name }}.crt
|
||||
remaining_days: 21
|
||||
terms_agreed: true
|
||||
data: "{{ dns_challenge }}"
|
||||
|
||||
post_tasks:
|
||||
- name: Delete TXT records for challenge validation
|
||||
vars:
|
||||
validation_record: "{{ ['_acme-challenge', common_name] | join('.') }}"
|
||||
when: query('community.dns.lookup', validation_record, type='TXT') != []
|
||||
amazon.aws.route53:
|
||||
zone: example.org
|
||||
record: "{{ validation_record }}"
|
||||
type: TXT
|
||||
state: absent
|
||||
wait: true
|
||||
1
examples/pulumi/letsencrypt-certificate.dns01/.env
Normal file
1
examples/pulumi/letsencrypt-certificate.dns01/.env
Normal file
@@ -0,0 +1 @@
|
||||
export PULUMI_CONFIG_PASSPHRASE=test123
|
||||
1
examples/pulumi/letsencrypt-certificate.dns01/.env.fish
Normal file
1
examples/pulumi/letsencrypt-certificate.dns01/.env.fish
Normal file
@@ -0,0 +1 @@
|
||||
set -x 'PULUMI_CONFIG_PASSPHRASE' 'test123'
|
||||
2
examples/pulumi/letsencrypt-certificate.dns01/.gitignore
vendored
Normal file
2
examples/pulumi/letsencrypt-certificate.dns01/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/bin/
|
||||
/node_modules/
|
||||
@@ -0,0 +1,4 @@
|
||||
encryptionsalt: v1:rsWIsa8WSik=:v1:D517hSFtoEVILMBz:wB9tX0Bu0Y0WqsXEYenywicAjnTHJw==
|
||||
|
||||
config:
|
||||
acme:serverUrl: https://acme-v02.api.letsencrypt.org/directory
|
||||
@@ -0,0 +1,9 @@
|
||||
name: letsencrypt-certificate.dns01
|
||||
runtime: nodejs
|
||||
description: DNS01 challenge with ACME leveraging Let's Encrypt
|
||||
config:
|
||||
pulumi:tags:
|
||||
value:
|
||||
pulumi:template: typescript
|
||||
backend:
|
||||
url: file://.
|
||||
82
examples/pulumi/letsencrypt-certificate.dns01/index.ts
Normal file
82
examples/pulumi/letsencrypt-certificate.dns01/index.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import * as acme from '@pulumiverse/acme';
|
||||
import * as cloudinit from "@pulumi/cloudinit";
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as tls from "@pulumi/tls";
|
||||
import * as yaml from "yaml";
|
||||
|
||||
|
||||
/**
|
||||
* LetsEncrypt certificate - start
|
||||
* -------------------------------------
|
||||
* Leverage the DNS challenge to keep the instance private at all times.
|
||||
**/
|
||||
|
||||
const privateKey = new tls.PrivateKey(
|
||||
"privateKey",
|
||||
{ algorithm: "RSA" },
|
||||
);
|
||||
const registration = new acme.Registration(
|
||||
"registration",
|
||||
{
|
||||
accountKeyPem: privateKey.privateKeyPem,
|
||||
emailAddress: "example@company.com",
|
||||
},
|
||||
);
|
||||
const certificate = new acme.Certificate(
|
||||
"certificate",
|
||||
{
|
||||
accountKeyPem: registration.accountKeyPem,
|
||||
commonName: "gitlab.company.com",
|
||||
dnsChallenges: [{
|
||||
provider: "route53",
|
||||
}],
|
||||
},
|
||||
);
|
||||
|
||||
/* LetsEncrypt certificate - end */
|
||||
|
||||
|
||||
/**
|
||||
* Instance - start
|
||||
* -------------------------------------
|
||||
* https://serverfault.com/questions/62496/ssl-certificate-location-on-unix-linux#722646
|
||||
**/
|
||||
|
||||
const userData = new cloudinit.Config(
|
||||
"cloudConfig",
|
||||
{
|
||||
gzip: true,
|
||||
base64Encode: true,
|
||||
parts: [
|
||||
{
|
||||
contentType: "text/cloud-config",
|
||||
content: pulumi.all([
|
||||
certificate.certificateDomain.apply(v => v),
|
||||
certificate.certificatePem.apply(v => v),
|
||||
certificate.privateKeyPem.apply(v => v),
|
||||
]).apply(([domain, certificate, privateKey]) => yaml.stringify({
|
||||
write_files: [
|
||||
{
|
||||
path: `/etc/pki/tls/certs/${domain}.crt`,
|
||||
content: btoa(certificate),
|
||||
permissions: "0o600",
|
||||
encoding: "base64",
|
||||
defer: true,
|
||||
},
|
||||
{
|
||||
path: `/etc/pki/tls/private/${domain}.key`,
|
||||
content: btoa(privateKey),
|
||||
permissions: "0o600",
|
||||
encoding: "base64",
|
||||
defer: true,
|
||||
},
|
||||
],
|
||||
})),
|
||||
filename: "cloud-config.letsencrypt.certificate.yml",
|
||||
mergeType: "dict(recurse_array,no_replace)+list(append)",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
/* Instance - end */
|
||||
3127
examples/pulumi/letsencrypt-certificate.dns01/package-lock.json
generated
Normal file
3127
examples/pulumi/letsencrypt-certificate.dns01/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
14
examples/pulumi/letsencrypt-certificate.dns01/package.json
Normal file
14
examples/pulumi/letsencrypt-certificate.dns01/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "letsencrypt-certificate.dns01",
|
||||
"main": "index.ts",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pulumi/cloudinit": "1.4.3",
|
||||
"@pulumi/pulumi": "3.115.2",
|
||||
"@pulumi/tls": "5.0.3",
|
||||
"@pulumiverse/acme": "0.0.1",
|
||||
"yaml": "2.4.2"
|
||||
}
|
||||
}
|
||||
18
examples/pulumi/letsencrypt-certificate.dns01/tsconfig.json
Normal file
18
examples/pulumi/letsencrypt-certificate.dns01/tsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"outDir": "bin",
|
||||
"target": "es2020",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"pretty": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user