mirror of
https://codeberg.org/scottslowe/learning-tools.git
synced 2026-03-11 09:04:37 +00:00
Add Fedora CoreOS program
Add Pulumi program to stand up Fedora CoreOS on AWS Signed-off-by: Scott Lowe <scott.lowe@scottlowe.org>
This commit is contained in:
parent
2811b034d8
commit
585c4438c9
4 changed files with 284 additions and 0 deletions
3
coreos/fcos-pulumi-aws/Pulumi.yaml
Normal file
3
coreos/fcos-pulumi-aws/Pulumi.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
name: fcos-pulumi-aws
|
||||
runtime: go
|
||||
description: A Go Pulumi program to stand up a Fedora CoreOS (FCOS) instance on AWS
|
||||
47
coreos/fcos-pulumi-aws/README.md
Normal file
47
coreos/fcos-pulumi-aws/README.md
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Fedora CoreOS on AWS Using Pulumi
|
||||
|
||||
These files were created to allow users to quickly and easily deploy a Fedora CoreOS instance on Amazon EC2 using [Pulumi](https://www.pulumi.com). This Pulumi program was written in [Go](https://go.dev).
|
||||
|
||||
While not complex, the Pulumi program here does illustrate a few things that might be useful for newer users:
|
||||
|
||||
* Use of the `slices` library to verify that a configuration value passed in from the user is in an allowed list of values
|
||||
* Supporting both X86_64/AMD64- as well as ARM64-based configurations
|
||||
* Dynamically looking up an AMI
|
||||
* Modifying the default values for an AWSX VPC to create only public subnets
|
||||
* Creating an SSH key (and associated AWS key pair)
|
||||
|
||||
## Contents
|
||||
|
||||
* `go.mod`: This file contains dependencies used by this Go program.
|
||||
|
||||
* `go.sum`: This file contains checksums for each of the direct and indirect dependencies. The checksum is used to validate that none of them has been modified.
|
||||
|
||||
* `main.go`: This Go file is the Pulumi program executed by the `pulumi` CLI, and contains the resource definitions to create a VPC with only public subnets, a security group to allow SSH access, and a Debian-based EC2 instance in one of the public subnets.
|
||||
|
||||
* `Pulumi.yaml`: This is the Pulumi project file.
|
||||
|
||||
* `README.md`: This file you're currently reading.
|
||||
|
||||
## Instructions
|
||||
|
||||
These instructions assume you've already installed and configured Pulumi and all necessary dependencies (Go, for this example). Please refer to the Pulumi documentation for more details on installation or configuration.
|
||||
|
||||
1. Copy the contents of this directory down to a directory on your system, or clone the entire repository and then change into the directory where this section of the cloned repository resides.
|
||||
|
||||
1. Run `pulumi stack init` to create a new stack.
|
||||
|
||||
1. Run `pulumi config set aws:region <region-name>` to set the AWS region where the Pulumi program should create resources. _This is a required configuration value; CLI operations will fail if you don't set this value._
|
||||
|
||||
1. (Optional) Run `pulumi config set` to set configuration values that affect the behavior of the Pulumi program. The optional configuration values are:
|
||||
|
||||
* `architecture`: Set this to "amd64" or "arm64". The values "x86_64" and "x64" are also supported and will have the same effect as "amd64". The default value is "arm64".
|
||||
* `networkcidr`: Set this to control the CIDR that will be used when the VPC is created. The default value is "10.0.0.0/16".
|
||||
* `channel`: Set this to "stable", "testing", or "next" to control the release stream deployed on EC2. The default value is "stable".
|
||||
|
||||
1. Run `pulumi up` to instantiate the resources.
|
||||
|
||||
Enjoy! When you're finished, run `pulumi destroy` to tear down all the provisioned resources.
|
||||
|
||||
## License
|
||||
|
||||
This content is licensed under the MIT License.
|
||||
91
coreos/fcos-pulumi-aws/go.mod
Normal file
91
coreos/fcos-pulumi-aws/go.mod
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
module ubuntu-pulumi-aws
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/pulumi/pulumi-aws/sdk/v6 v6.8.0
|
||||
github.com/pulumi/pulumi-awsx/sdk/v2 v2.1.1
|
||||
github.com/pulumi/pulumi-tls/sdk/v4 v4.11.1
|
||||
github.com/pulumi/pulumi/sdk/v3 v3.91.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/charmbracelet/bubbles v0.16.1 // indirect
|
||||
github.com/charmbracelet/bubbletea v0.24.2 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.7.1 // indirect
|
||||
github.com/cheggaaa/pb v1.0.29 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
github.com/djherbis/times v1.5.0 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.4.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.6.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/glog v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.17.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||
github.com/mitchellh/go-ps v1.0.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.1 // indirect
|
||||
github.com/opentracing/basictracer-go v1.1.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/term v1.1.0 // indirect
|
||||
github.com/pulumi/esc v0.5.6 // indirect
|
||||
github.com/pulumi/pulumi-docker/sdk/v4 v4.4.3 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.1.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/texttheater/golang-levenshtein v1.0.1 // indirect
|
||||
github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/zclconf/go-cty v1.13.2 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/term v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
|
||||
google.golang.org/grpc v1.57.1 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
lukechampine.com/frand v1.4.2 // indirect
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20211028080628-e2786a622600 // indirect
|
||||
)
|
||||
143
coreos/fcos-pulumi-aws/main.go
Normal file
143
coreos/fcos-pulumi-aws/main.go
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
|
||||
"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/ec2"
|
||||
awsx "github.com/pulumi/pulumi-awsx/sdk/v2/go/awsx/ec2"
|
||||
"github.com/pulumi/pulumi-tls/sdk/v4/go/tls"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
||||
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
pulumi.Run(func(ctx *pulumi.Context) error {
|
||||
// Set up maps that are used later
|
||||
streams := []string{"stable", "testing", "next"}
|
||||
typeMap := map[string]string{"amd64": "t3a.small", "arm64": "t4g.small", "x86_64": "t3a.small", "x64": "t3a.small"}
|
||||
|
||||
// Retrieve configuration values
|
||||
instanceCpuArch, err := config.Try(ctx, "architecture")
|
||||
if err != nil {
|
||||
instanceCpuArch = "arm64"
|
||||
}
|
||||
instanceType, ok := typeMap[instanceCpuArch]
|
||||
if !ok {
|
||||
instanceCpuArch = "arm64"
|
||||
instanceType = "t4g.small"
|
||||
}
|
||||
if instanceCpuArch == "amd64" || instanceCpuArch == "x64" {
|
||||
instanceCpuArch = "x86_64"
|
||||
}
|
||||
vpcNetworkCidr, err := config.Try(ctx, "networkcidr")
|
||||
if err != nil {
|
||||
vpcNetworkCidr = "10.0.0.0/16"
|
||||
}
|
||||
channel, err := config.Try(ctx, "channel")
|
||||
if err != nil {
|
||||
channel = "stable"
|
||||
}
|
||||
if !slices.Contains(streams, channel) {
|
||||
channel = "stable"
|
||||
}
|
||||
|
||||
// Create a new VPC, subnets, and associated infrastructure
|
||||
fcosVpc, err := awsx.NewVpc(ctx, "fcos-vpc", &awsx.VpcArgs{
|
||||
CidrBlock: &vpcNetworkCidr,
|
||||
EnableDnsHostnames: pulumi.Bool(true),
|
||||
EnableDnsSupport: pulumi.Bool(true),
|
||||
NatGateways: &awsx.NatGatewayConfigurationArgs{
|
||||
Strategy: awsx.NatGatewayStrategyNone,
|
||||
},
|
||||
SubnetSpecs: []awsx.SubnetSpecArgs{
|
||||
{
|
||||
Type: awsx.SubnetTypePublic,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error creating VPC: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create a Security Group that we can use to connect to our instance
|
||||
fcosSg, err := ec2.NewSecurityGroup(ctx, "fcos-sg", &ec2.SecurityGroupArgs{
|
||||
VpcId: fcosVpc.VpcId,
|
||||
Egress: ec2.SecurityGroupEgressArray{
|
||||
ec2.SecurityGroupEgressArgs{
|
||||
Protocol: pulumi.String("-1"),
|
||||
FromPort: pulumi.Int(0),
|
||||
ToPort: pulumi.Int(0),
|
||||
CidrBlocks: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
|
||||
},
|
||||
},
|
||||
Ingress: ec2.SecurityGroupIngressArray{
|
||||
ec2.SecurityGroupIngressArgs{
|
||||
Protocol: pulumi.String("tcp"),
|
||||
FromPort: pulumi.Int(22),
|
||||
ToPort: pulumi.Int(22),
|
||||
CidrBlocks: pulumi.StringArray{pulumi.String("0.0.0.0/0")},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error creating security group: %s", err.Error())
|
||||
}
|
||||
|
||||
// Get AMI ID for Fedora CoreOS instance
|
||||
descValue := fmt.Sprintf("*%s*", channel)
|
||||
fcosAmi, err := ec2.LookupAmi(ctx, &ec2.LookupAmiArgs{
|
||||
Owners: []string{"125523088429"},
|
||||
MostRecent: pulumi.BoolRef(true),
|
||||
Filters: []ec2.GetAmiFilter{
|
||||
{Name: "name", Values: []string{"fedora-coreos-*"}},
|
||||
{Name: "root-device-type", Values: []string{"ebs"}},
|
||||
{Name: "virtualization-type", Values: []string{"hvm"}},
|
||||
{Name: "architecture", Values: []string{instanceCpuArch}},
|
||||
{Name: "description", Values: []string{descValue}},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error looking up AMI: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create an SSH key
|
||||
sshKey, err := tls.NewPrivateKey(ctx, "ssh-key", &tls.PrivateKeyArgs{
|
||||
Algorithm: pulumi.String("ED25519"),
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error creating SSH key: %s", err.Error())
|
||||
}
|
||||
|
||||
// Create an AWS key pair
|
||||
fcosKeyPair, err := ec2.NewKeyPair(ctx, "fcos-key-pair", &ec2.KeyPairArgs{
|
||||
PublicKey: sshKey.PublicKeyOpenssh,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error creating AWS key pair: %s", err.Error())
|
||||
}
|
||||
|
||||
// Launch an instance using Fedora CoreOS AMI
|
||||
fcosInstance, err := ec2.NewInstance(ctx, "fcos-instance", &ec2.InstanceArgs{
|
||||
Ami: pulumi.String(fcosAmi.Id),
|
||||
InstanceType: pulumi.String(instanceType),
|
||||
AssociatePublicIpAddress: pulumi.Bool(true),
|
||||
KeyName: fcosKeyPair.KeyName,
|
||||
SubnetId: fcosVpc.PublicSubnetIds.Index(pulumi.Int(0)),
|
||||
VpcSecurityGroupIds: pulumi.StringArray{fcosSg.ID()},
|
||||
Tags: pulumi.StringMap{
|
||||
"Name": pulumi.String("fcos-instance"),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("error launching instance: %s", err.Error())
|
||||
}
|
||||
ctx.Export("instanceId", fcosInstance.ID())
|
||||
ctx.Export("instancePublicIpAddress", fcosInstance.PublicIp)
|
||||
ctx.Export("instancePrivateIpAddress", fcosInstance.PrivateIp)
|
||||
ctx.Export("privateKey", sshKey.PrivateKeyOpenssh)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Loading…
Reference in a new issue