diff --git a/Pulumi.infra.yaml b/Pulumi.infra.yaml index b4f53c9..2930dcf 100644 --- a/Pulumi.infra.yaml +++ b/Pulumi.infra.yaml @@ -1,7 +1,7 @@ config: - flow:domain: - description: A sub-domain for the Flow infrastructure. - name: flow.dananglin.me.uk - soaEmail: d.n.i.anglin@gmail.com - tags: - - flow + flow:records: + codeflow: codeflow + root: . + workflow: workflow + flow:region: eu-west + flow:rootDomain: dananglin.me.uk diff --git a/domain.go b/domain.go deleted file mode 100644 index 12563fa..0000000 --- a/domain.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "github.com/pulumi/pulumi-linode/sdk/v3/go/linode" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" -) - -type Domain struct { - Name string - Description string - SoaEmail string - Tags []string -} - -func domain(ctx *pulumi.Context) error { - var d Domain - - cfg := config.New(ctx, "") - - cfg.RequireObject("domain", &d) - - domainArgs := linode.DomainArgs{ - Description: pulumi.String(d.Description), - Type: pulumi.String("master"), - Domain: pulumi.String(d.Name), - SoaEmail: pulumi.String(d.SoaEmail), - Tags: pulumi.ToStringArray(d.Tags), - } - - _, err := linode.NewDomain(ctx, d.Name, &domainArgs, pulumi.Protect(true)) - if err != nil { - return err - } - return nil -} diff --git a/firewall.go b/firewall.go deleted file mode 100644 index 4acce80..0000000 --- a/firewall.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "github.com/pulumi/pulumi-linode/sdk/v3/go/linode" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" -) - -func firewall(ctx *pulumi.Context) error { - allowHttp := linode.FirewallInboundArgs{ - Label: pulumi.String("accept-inbound-tcp-80"), - Action: pulumi.String("ACCEPT"), - Protocol: pulumi.String("TCP"), - Ports: pulumi.String("80"), - Ipv4s: pulumi.StringArray{ - pulumi.String("0.0.0.0/0"), - }, - Ipv6s: pulumi.StringArray{ - pulumi.String("::/0"), - }, - } - - allowHttps := linode.FirewallInboundArgs{ - Label: pulumi.String("accept-inbound-tcp-443"), - Action: pulumi.String("ACCEPT"), - Protocol: pulumi.String("TCP"), - Ports: pulumi.String("443"), - Ipv4s: pulumi.StringArray{ - pulumi.String("0.0.0.0/0"), - }, - Ipv6s: pulumi.StringArray{ - pulumi.String("::/0"), - }, - } - - tags := []string{"flow"} - - label := "fireflow" - - firewallArgs := linode.FirewallArgs{ - Label: pulumi.String(label), - Tags: pulumi.ToStringArray(tags), - InboundPolicy: pulumi.String("DROP"), - Inbounds: linode.FirewallInboundArray{ - &allowHttp, - &allowHttps, - }, - OutboundPolicy: pulumi.String("ACCEPT"), - } - - _, err := linode.NewFirewall(ctx, label, &firewallArgs) - - if err != nil { - return err - } - - return nil -} diff --git a/infra.go b/infra.go new file mode 100644 index 0000000..6e774d1 --- /dev/null +++ b/infra.go @@ -0,0 +1,181 @@ +package main + +import ( + "fmt" + "strconv" + + "github.com/pulumi/pulumi-linode/sdk/v3/go/linode" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" +) + +type instanceOutput struct { + ipv4 pulumi.StringOutput + id pulumi.IntOutput +} + +func instance(ctx *pulumi.Context) (instanceOutput, error) { + var output instanceOutput + + cfg := config.New(ctx, "") + + region := cfg.Require("region") + tags := []string{"flow"} + instanceLabelID := "flow-platform" + instanceType := "g6-standard-1" + + // TODO: finish instance arguments to completion + instanceArgs := linode.InstanceArgs{ + BackupsEnabled: pulumi.Bool(false), + Label: pulumi.String(instanceLabelID), + PrivateIp: pulumi.Bool(false), + Region: pulumi.String(region), + Tags: pulumi.ToStringArray(tags), + SwapSize: pulumi.Int(512), + Type: pulumi.String(instanceType), + WatchdogEnabled: pulumi.Bool(true), + } + + instance, err := linode.NewInstance(ctx, instanceLabelID, &instanceArgs, pulumi.Protect(true)) + if err != nil { + return output, fmt.Errorf("unable to update instance; %w", err) + } + + instanceID := instance.ID().ToStringOutput().ApplyT(func(id string) (int, error) { + return strconv.Atoi(id) + }).(pulumi.IntOutput) + + output = instanceOutput{ + id: instanceID, + ipv4: instance.IpAddress, + } + + return output, nil +} + +func volume(ctx *pulumi.Context, instanceID pulumi.IntInput) error { + volumeLabelID := "flow-platform-volume" + + cfg := config.New(ctx, "") + + region := cfg.Require("region") + + tags := []string{"flow"} + + volumeArgs := linode.VolumeArgs{ + Label: pulumi.String(volumeLabelID), + LinodeId: instanceID, + Region: pulumi.String(region), + Size: pulumi.Int(10), + Tags: pulumi.ToStringArray(tags), + } + + _, err := linode.NewVolume(ctx, volumeLabelID, &volumeArgs, pulumi.Protect(true)) + if err != nil { + return fmt.Errorf("unable to update volume; %w", err) + } + + return nil +} + +func firewall(ctx *pulumi.Context, instanceID pulumi.IntOutput) error { + allowHttp := linode.FirewallInboundArgs{ + Label: pulumi.String("accept-inbound-tcp-80"), + Action: pulumi.String("ACCEPT"), + Protocol: pulumi.String("TCP"), + Ports: pulumi.String("80"), + Ipv4s: pulumi.StringArray{ + pulumi.String("0.0.0.0/0"), + }, + Ipv6s: pulumi.StringArray{ + pulumi.String("::/0"), + }, + } + + allowHttps := linode.FirewallInboundArgs{ + Label: pulumi.String("accept-inbound-tcp-443"), + Action: pulumi.String("ACCEPT"), + Protocol: pulumi.String("TCP"), + Ports: pulumi.String("443"), + Ipv4s: pulumi.StringArray{ + pulumi.String("0.0.0.0/0"), + }, + Ipv6s: pulumi.StringArray{ + pulumi.String("::/0"), + }, + } + + tags := []string{"flow"} + + label := "fireflow" + + firewallArgs := linode.FirewallArgs{ + Label: pulumi.String(label), + Tags: pulumi.ToStringArray(tags), + InboundPolicy: pulumi.String("DROP"), + Inbounds: linode.FirewallInboundArray{ + &allowHttp, + &allowHttps, + }, + OutboundPolicy: pulumi.String("ACCEPT"), + Linodes: pulumi.IntArray{ + instanceID, + }, + } + + _, err := linode.NewFirewall(ctx, label, &firewallArgs) + + if err != nil { + return fmt.Errorf("unable to update the firewall; %w", err) + } + + return nil +} + +func records(ctx *pulumi.Context, ipv4 pulumi.StringOutput) error { + cfg := config.New(ctx, "") + + rootDomainName := cfg.Require("rootDomain") + + domainArgs := linode.LookupDomainArgs{ + Domain: &rootDomainName, + } + + domain, err := linode.LookupDomain(ctx, &domainArgs, nil) + if err != nil { + return fmt.Errorf("unable to lookup domain %s; %w", rootDomainName, err) + } + + domainID, err := strconv.Atoi(*domain.Id) + if err != nil { + return fmt.Errorf("unable to get the Domain ID; %w", err) + } + + records := make(map[string]string) + + cfg.RequireObject("records", &records) + + for _, r := range records { + args := linode.DomainRecordArgs{ + DomainId: pulumi.Int(domainID), + Name: pulumi.String(r), + RecordType: pulumi.String("A"), + Target: ipv4, + TtlSec: pulumi.Int(300), + } + + var resourceName string + if r == "." { + resourceName = "root-record" + } else { + resourceName = r + "-record" + } + + _, err := linode.NewDomainRecord(ctx, resourceName, &args, nil) + if err != nil { + return fmt.Errorf("unable to update the domain record '%s'; %w", r, err) + } + } + + return nil +} diff --git a/main.go b/main.go index bf74b28..e5d9e80 100644 --- a/main.go +++ b/main.go @@ -9,11 +9,21 @@ func main() { } func infra(ctx *pulumi.Context) error { - if err := domain(ctx); err != nil { + instance, err := instance(ctx) + if err != nil { return err } - if err := firewall(ctx); err != nil { + if err := volume(ctx, instance.id); err != nil { + return err + } + + err = firewall(ctx, instance.id) + if err != nil { + return err + } + + if err := records(ctx, instance.ipv4); err != nil { return err }