@@ -2,8 +2,11 @@ package baremetal
22
33import (
44 "context"
5+ "encoding/base64"
56 "encoding/json"
7+ "errors"
68 "fmt"
9+ "os"
710
811 "github.com/hashicorp/go-cty/cty"
912 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -297,6 +300,13 @@ If this behaviour is wanted, please set 'reinstall_on_ssh_key_changes' argument
297300 },
298301 },
299302 },
303+ "cloud_init" : {
304+ Type : schema .TypeString ,
305+ Optional : true ,
306+ Computed : true ,
307+ Description : "Configuration data to pass to cloud-init such as a YAML cloud config data or a user-data script" ,
308+ ValidateFunc : validation .StringLenBetween (0 , 127998 ),
309+ },
300310 },
301311 CustomizeDiff : customdiff .Sequence (
302312 customDiffOffer (),
@@ -367,6 +377,14 @@ func ResourceServerCreate(ctx context.Context, d *schema.ResourceData, m any) di
367377 Protected : d .Get ("protected" ).(bool ),
368378 }
369379
380+ if cloudInit , ok := d .GetOk ("cloud_init" ); ok {
381+ userData , err := LoadUserDataBase64 (cloudInit )
382+ if err != nil {
383+ return diag .FromErr (err )
384+ }
385+ req .UserData = & userData
386+ }
387+
370388 partitioningSchema := baremetal.Schema {}
371389
372390 if file , ok := d .GetOk ("partitioning" ); ok || ! d .Get ("install_config_afterward" ).(bool ) {
@@ -457,6 +475,21 @@ func ResourceServerCreate(ctx context.Context, d *schema.ResourceData, m any) di
457475 return ResourceServerRead (ctx , d , m )
458476}
459477
478+ func LoadUserDataBase64 (cloudInit interface {}) ([]byte , error ) {
479+ value := cloudInit .(string )
480+ var content []byte
481+ if data , err := os .ReadFile (value ); errors .Is (err , os .ErrNotExist ) {
482+ content = []byte (value )
483+ } else if err == nil {
484+ content = data
485+ } else {
486+ return nil , err
487+ }
488+ encoded := base64 .StdEncoding .EncodeToString (content )
489+ userData := []byte (encoded )
490+ return userData , nil
491+ }
492+
460493func ResourceServerRead (ctx context.Context , d * schema.ResourceData , m any ) diag.Diagnostics {
461494 api , zonedID , err := NewAPIWithZoneAndID (m , d .Id ())
462495 if err != nil {
@@ -514,6 +547,7 @@ func ResourceServerRead(ctx context.Context, d *schema.ResourceData, m any) diag
514547 _ = d .Set ("ipv4" , flattenIPv4s (server .IPs ))
515548 _ = d .Set ("ipv6" , flattenIPv6s (server .IPs ))
516549 _ = d .Set ("protected" , server .Protected )
550+ _ = d .Set ("cloud_init" , server .UserData )
517551
518552 if server .Install != nil {
519553 _ = d .Set ("os" , zonal .NewIDString (server .Zone , os .ID ))
@@ -696,6 +730,16 @@ func ResourceServerUpdate(ctx context.Context, d *schema.ResourceData, m any) di
696730
697731 hasChanged := false
698732
733+ if d .HasChange ("cloud_init" ) {
734+ cloudInit := d .Get ("cloud_init" ).(string )
735+ userData , err := LoadUserDataBase64 (cloudInit )
736+ if err != nil {
737+ return diag .FromErr (err )
738+ }
739+ req .UserData = & userData
740+ hasChanged = true
741+ }
742+
699743 if d .HasChange ("name" ) {
700744 req .Name = types .ExpandUpdatedStringPtr (d .Get ("name" ))
701745 hasChanged = true
0 commit comments