mirror of
https://codeberg.org/scottslowe/learning-tools.git
synced 2026-03-11 09:04:37 +00:00
Add Go program illustrating use of an SSH-based Docker provider Signed-off-by: Scott Lowe <scott.lowe@scottlowe.org>
188 lines
6.3 KiB
Go
188 lines
6.3 KiB
Go
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-docker/sdk/v4/go/docker"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
|
|
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
|
|
"github.com/pulumiverse/pulumi-time/sdk/go/time"
|
|
)
|
|
|
|
func main() {
|
|
pulumi.Run(func(ctx *pulumi.Context) error {
|
|
// Set up maps that are used later
|
|
channelNames := []string{"stable", "beta", "alpha", "lts"}
|
|
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 == "x86_64" || instanceCpuArch == "x64" {
|
|
instanceCpuArch = "amd64"
|
|
}
|
|
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(channelNames, channel) {
|
|
channel = "stable"
|
|
}
|
|
userSuppliedKeyPair := config.Require(ctx, "keypair")
|
|
userSuppliedPrivateKeyFile := config.Require(ctx, "privatekeyfile")
|
|
|
|
// Create a new VPC, subnets, and associated infrastructure
|
|
dockerVpc, err := awsx.NewVpc(ctx, "docker-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
|
|
dockerSg, err := ec2.NewSecurityGroup(ctx, "docker-sg", &ec2.SecurityGroupArgs{
|
|
VpcId: dockerVpc.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")},
|
|
},
|
|
ec2.SecurityGroupIngressArgs{
|
|
Protocol: pulumi.String("tcp"),
|
|
FromPort: pulumi.Int(2379),
|
|
ToPort: pulumi.Int(2380),
|
|
Description: pulumi.String("Allow etcd traffic from this security group"),
|
|
Self: pulumi.Bool(true),
|
|
},
|
|
ec2.SecurityGroupIngressArgs{
|
|
Protocol: pulumi.String("tcp"),
|
|
FromPort: pulumi.Int(4001),
|
|
ToPort: pulumi.Int(4001),
|
|
Description: pulumi.String("Allow etcd traffic from this security group"),
|
|
Self: pulumi.Bool(true),
|
|
},
|
|
ec2.SecurityGroupIngressArgs{
|
|
Protocol: pulumi.String("tcp"),
|
|
FromPort: pulumi.Int(7001),
|
|
ToPort: pulumi.Int(7001),
|
|
Description: pulumi.String("Allow etcd traffic from this security group"),
|
|
Self: pulumi.Bool(true),
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
log.Printf("error creating security group: %s", err.Error())
|
|
}
|
|
|
|
// Get AMI ID for Flatcar Linux instance
|
|
amiName := fmt.Sprintf("Flatcar-%s-*", channel)
|
|
flatcarAmi, err := ec2.LookupAmi(ctx, &ec2.LookupAmiArgs{
|
|
Owners: []string{"075585003325"},
|
|
MostRecent: pulumi.BoolRef(true),
|
|
Filters: []ec2.GetAmiFilter{
|
|
{Name: "name", Values: []string{amiName}},
|
|
{Name: "root-device-type", Values: []string{"ebs"}},
|
|
{Name: "virtualization-type", Values: []string{"hvm"}},
|
|
{Name: "architecture", Values: []string{instanceCpuArch}},
|
|
},
|
|
})
|
|
if err != nil {
|
|
log.Printf("error looking up AMI: %s", err.Error())
|
|
}
|
|
|
|
// Launch an instance using Flatcar Linux AMI
|
|
flatcarInstance, err := ec2.NewInstance(ctx, "flatcar-instance", &ec2.InstanceArgs{
|
|
Ami: pulumi.String(flatcarAmi.Id),
|
|
InstanceType: pulumi.String(instanceType),
|
|
AssociatePublicIpAddress: pulumi.Bool(true),
|
|
KeyName: pulumi.StringPtr(userSuppliedKeyPair),
|
|
SubnetId: dockerVpc.PublicSubnetIds.Index(pulumi.Int(0)),
|
|
VpcSecurityGroupIds: pulumi.StringArray{dockerSg.ID()},
|
|
Tags: pulumi.StringMap{
|
|
"Name": pulumi.String("flatcar-instance"),
|
|
},
|
|
})
|
|
if err != nil {
|
|
log.Printf("error launching instance: %s", err.Error())
|
|
}
|
|
|
|
// Sleep for 15 seconds to allow instance to boot
|
|
instanceBootDelay, err := time.NewSleep(ctx, "instance-boot-delay", &time.SleepArgs{
|
|
CreateDuration: pulumi.String("20s"),
|
|
}, pulumi.DependsOn([]pulumi.Resource{flatcarInstance}))
|
|
if err != nil {
|
|
log.Printf("error generating delay: %s", err.Error())
|
|
}
|
|
|
|
// Create a new Docker provider
|
|
remoteDocker, err := docker.NewProvider(ctx, "remote-docker", &docker.ProviderArgs{
|
|
Host: pulumi.Sprintf("ssh://core@%s", flatcarInstance.PublicIp),
|
|
SshOpts: pulumi.StringArray{
|
|
pulumi.String("-i"), pulumi.String(userSuppliedPrivateKeyFile),
|
|
pulumi.String("-o"), pulumi.String("StrictHostKeyChecking=no"),
|
|
pulumi.String("-o"), pulumi.String("UserKnownHostsFile=/dev/null"),
|
|
},
|
|
}, pulumi.DependsOn([]pulumi.Resource{instanceBootDelay}))
|
|
if err != nil {
|
|
log.Printf("error creating provider: %s", err.Error())
|
|
}
|
|
|
|
// Pull down a container image on the remote host
|
|
nginxImage, err := docker.NewRemoteImage(ctx, "nginx-image", &docker.RemoteImageArgs{
|
|
Name: pulumi.String("nginx:1.17.4-alpine"),
|
|
}, pulumi.Provider(remoteDocker))
|
|
if err != nil {
|
|
log.Printf("error pulling remote image: %s", err.Error())
|
|
}
|
|
|
|
// Launch a container on the remote host
|
|
_, err = docker.NewContainer(ctx, "nginx-container", &docker.ContainerArgs{
|
|
Image: nginxImage.ImageId,
|
|
}, pulumi.Provider(remoteDocker))
|
|
if err != nil {
|
|
log.Printf("error creating remote container: %s", err.Error())
|
|
}
|
|
|
|
// Export some values as stack outputs
|
|
ctx.Export("instanceId", flatcarInstance.ID())
|
|
ctx.Export("instancePublicIpAddress", flatcarInstance.PublicIp)
|
|
ctx.Export("instancePrivateIpAddress", flatcarInstance.PrivateIp)
|
|
|
|
return nil
|
|
})
|
|
}
|