Skip to content

Commit

Permalink
Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
krystian-panek-vmltech committed Nov 17, 2023
1 parent 37f6b7d commit f5b2c90
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 49 deletions.
21 changes: 21 additions & 0 deletions internal/provider/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Adobe Experience Manager (AEM) Terraform Provider

This provider allows developers and development teams to easily set up [Adobe Experience Manager (AEM)](https://business.adobe.com/products/experience-manager/adobe-experience-manager.html) instances on virtual machines in the cloud or bare metal machines.
It's based on the [AEM Compose](https://github.com/wttech/aemc) tool and aims to simplify the process of creating AEM environments without requiring deep DevOps knowledge.
Only basic AWS, Azure, or any other cloud knowledge about VMs is required.

## Purpose

The main purpose of this provider is to enable users to:

- Set up as many AEM environments as needed with minimal effort
- Eliminate the need for deep DevOps knowledge
- Allow for seamless integration with popular cloud platforms such as AWS and Azure
- Provide a simple and efficient way to manage AEM instances

## Features

- Easy configuration and management of AEM instances
- Support for multiple cloud platforms and bare metal machines
- Seamless integration with Terraform for infrastructure provisioning
- Based on the powerful [AEM Compose](https://github.com/wttech/aemc) tool
2 changes: 1 addition & 1 deletion internal/provider/instance_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (ic *InstanceClient) launch() error {
if err := ic.applyConfig(); err != nil {
return err
}
if err := ic.runScript("launch", ic.data.Compose.Launch, ic.dataDir()); err != nil {
if err := ic.runScript("configure", ic.data.Compose.Configure, ic.dataDir()); err != nil {
return err
}
tflog.Info(ic.ctx, "Launched AEM instance(s)")
Expand Down
67 changes: 38 additions & 29 deletions internal/provider/instance_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ type InstanceResourceModel struct {
Bootstrap InstanceScript `tfsdk:"bootstrap"`
} `tfsdk:"system"`
Compose struct {
Download types.Bool `tfsdk:"download"`
Version types.String `tfsdk:"version"`
Config types.String `tfsdk:"config"`
Create InstanceScript `tfsdk:"create"`
Launch InstanceScript `tfsdk:"launch"`
Delete InstanceScript `tfsdk:"delete"`
Download types.Bool `tfsdk:"download"`
Version types.String `tfsdk:"version"`
Config types.String `tfsdk:"config"`
Create InstanceScript `tfsdk:"create"`
Configure InstanceScript `tfsdk:"configure"`
Delete InstanceScript `tfsdk:"delete"`
} `tfsdk:"compose"`
Instances types.List `tfsdk:"instances"`
}
Expand Down Expand Up @@ -105,9 +105,10 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
MarkdownDescription: "AEM Instance resource",
Blocks: map[string]schema.Block{
"client": schema.SingleNestedBlock{
MarkdownDescription: "Connection settings used to access the machine on which the AEM instance will be running.",
Attributes: map[string]schema.Attribute{
"type": schema.StringAttribute{
MarkdownDescription: "Type of connection to use to connect to the machine on which AEM instance will be running",
MarkdownDescription: "Type of connection to use to connect to the machine on which AEM instance will be running.",
Required: true,
},
"settings": schema.MapAttribute{
Expand All @@ -124,9 +125,10 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
},
},
"system": schema.SingleNestedBlock{
MarkdownDescription: "Operating system configuration for the machine on which AEM instance will be running.",
Attributes: map[string]schema.Attribute{
"bootstrap": schema.SingleNestedAttribute{
MarkdownDescription: "Script executed once upon instance connection, often for mounting on VM data volumes from attached disks (e.g., AWS EBS, Azure Disk Storage). This script runs only once, even during instance recreation, as changes are typically persistent and system-wide. If re-execution is needed, it is recommended to set up a new VM.",
MarkdownDescription: "Script executed once upon instance connection, often for mounting on VM data volumes from attached disks (e.g., AWS EBS, Azure Disk Storage). This script runs only once, even during instance recreation, as changes are typically persistent and system-wide. If re-execution is needed, it is recommended to set up a new machine.",
Optional: true,
Attributes: map[string]schema.Attribute{
"inline": schema.ListAttribute{
Expand All @@ -141,20 +143,20 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
},
},
"data_dir": schema.StringAttribute{
MarkdownDescription: "Remote root path in which AEM Compose files and unpacked instances will be stored",
MarkdownDescription: "Remote root path in which AEM Compose files and unpacked AEM instances will be stored.",
Computed: true,
Optional: true,
Default: stringdefault.StaticString("/mnt/aemc"),
PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()},
},
"work_dir": schema.StringAttribute{
MarkdownDescription: "Remote root path in which AEM Compose TF provider temporary files will be stored",
MarkdownDescription: "Remote root path where provider-related files will be stored.",
Computed: true,
Optional: true,
Default: stringdefault.StaticString("/tmp/aemc"),
Default: stringdefault.StaticString("/var/aemc"),
},
"service_config": schema.StringAttribute{
MarkdownDescription: "Contents of the AEM 'systemd' service definition file",
MarkdownDescription: "Contents of the AEM system service definition file (systemd).",
Optional: true,
Computed: true,
Default: stringdefault.StaticString(instance.ServiceConf),
Expand All @@ -167,7 +169,7 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
Default: stringdefault.StaticString(""),
},
"env": schema.MapAttribute{
MarkdownDescription: "Environment variables for AEM instances",
MarkdownDescription: "Environment variables for AEM instances.",
ElementType: types.StringType,
Computed: true,
Optional: true,
Expand All @@ -176,7 +178,7 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
},
},
"compose": schema.SingleNestedBlock{
MarkdownDescription: "AEM Compose CLI configuration",
MarkdownDescription: "AEM Compose CLI configuration. See [documentation](https://github.com/wttech/aemc#configuration).",
Attributes: map[string]schema.Attribute{
"download": schema.BoolAttribute{
MarkdownDescription: "Toggle automatic AEM Compose CLI wrapper download. If set to false, assume the wrapper is present in the data directory.",
Expand All @@ -185,7 +187,7 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
Default: booldefault.StaticBool(true),
},
"version": schema.StringAttribute{
MarkdownDescription: "Version of AEM Compose tool to use on remote AEM machine.",
MarkdownDescription: "Version of AEM Compose tool to use on remote machine.",
Computed: true,
Optional: true,
Default: stringdefault.StaticString("1.5.9"),
Expand All @@ -197,7 +199,7 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
Default: stringdefault.StaticString(instance.ConfigYML),
},
"create": schema.SingleNestedAttribute{
MarkdownDescription: "Creates the instance or restores from backup, typically customized to provide AEM library files (quickstart.jar, license.properties, service packs) from alternative sources (e.g., AWS S3, Azure Blob Storage). Instance recreation is forced if changed.",
MarkdownDescription: "Script(s) for creating an instance or restoring it from a backup. Typically customized to provide AEM library files (quickstart.jar, license.properties, service packs) from alternative sources (e.g., AWS S3, Azure Blob Storage). Instance recreation is forced if changed.",
Optional: true,
Computed: true,
Default: instanceScriptSchemaDefault(instance.CreateScriptInline, nil),
Expand All @@ -217,8 +219,8 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
},
},
},
"launch": schema.SingleNestedAttribute{
MarkdownDescription: "Configures launched instance. Must be idempotent as it is executed always when changed. Typically used for installing AEM service packs, setting up replication agents, etc.",
"configure": schema.SingleNestedAttribute{
MarkdownDescription: "Script(s) for configuring a launched instance. Must be idempotent as it is executed always when changed. Typically used for installing AEM service packs, setting up replication agents, etc.",
Optional: true,
Computed: true,
Default: instanceScriptSchemaDefault(instance.LaunchScriptInline, nil),
Expand All @@ -237,7 +239,7 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques
},
},
"delete": schema.SingleNestedAttribute{
MarkdownDescription: "Deletes the instance.",
MarkdownDescription: "Script(s) for deleting a stopped instance.",
Optional: true,
Computed: true,
Default: instanceScriptSchemaDefault(instance.DeleteScriptInline, nil),
Expand All @@ -261,35 +263,42 @@ func (r *InstanceResource) Schema(ctx context.Context, req resource.SchemaReques

Attributes: map[string]schema.Attribute{
"files": schema.MapAttribute{
MarkdownDescription: "Files or directories to be copied into the machine",
MarkdownDescription: "Files or directories to be copied into the machine.",
ElementType: types.StringType,
Computed: true,
Optional: true,
Default: mapdefault.StaticValue(types.MapValueMust(types.StringType, map[string]attr.Value{})),
},
"instances": schema.ListNestedAttribute{
Computed: true,
MarkdownDescription: "Current state of the configured AEM instances.",
Computed: true,
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
MarkdownDescription: "Unique identifier of AEM instance defined in the configuration.",
Computed: true,
},
"url": schema.StringAttribute{
Computed: true,
MarkdownDescription: "The machine-internal HTTP URL address used for communication with the AEM instance.",
Computed: true,
},
"aem_version": schema.StringAttribute{
Computed: true,
MarkdownDescription: "Version of the AEM instance. Reflects service pack installations.",
Computed: true,
},
"attributes": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
MarkdownDescription: "A brief description of the state details for a specific AEM instance. Possible states include 'created', 'uncreated', 'running', 'unreachable', 'up-to-date', and 'out-of-date'.",
ElementType: types.StringType,
Computed: true,
},
"run_modes": schema.ListAttribute{
ElementType: types.StringType,
Computed: true,
MarkdownDescription: "A list of run modes for a specific AEM instance.",
ElementType: types.StringType,
Computed: true,
},
"dir": schema.StringAttribute{
Computed: true,
MarkdownDescription: "Remote path in which AEM instance is stored.",
Computed: true,
},
},
},
Expand Down
26 changes: 7 additions & 19 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package provider

import (
"context"
_ "embed"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/provider/schema"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/wttech/terraform-provider-aem/internal/client"
)

// Ensure AEMProvider satisfies various provider interfaces.
var _ provider.Provider = &AEMProvider{}

//go:embed description.md
var DescriptionMD string

// AEMProvider defines the provider implementation.
type AEMProvider struct {
// version is set to the provider version on release, "dev" when the
Expand All @@ -21,42 +24,27 @@ type AEMProvider struct {
version string
}

// AEMProviderModel describes the provider data model.
type AEMProviderModel struct {
Endpoint types.String `tfsdk:"endpoint"`
}
type AEMProviderModel struct{}

func (p *AEMProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
resp.TypeName = "aem"
resp.TypeName = "AEM"
resp.Version = p.version
}

func (p *AEMProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"endpoint": schema.StringAttribute{
MarkdownDescription: "Example provider attribute",
Optional: true,
},
},
MarkdownDescription: DescriptionMD,
}
}

func (p *AEMProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
var data AEMProviderModel

resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)

if resp.Diagnostics.HasError() {
return
}

// Configuration values are now available.
// if data.Endpoint.IsNull() { /* ... */ }

// Example client configuration for data sources and resources
clientManager := client.ClientManagerDefault

resp.DataSourceData = clientManager
resp.ResourceData = clientManager
}
Expand Down

0 comments on commit f5b2c90

Please sign in to comment.