mirror of
https://gitea.com/mcereda/oam.git
synced 2026-02-09 05:44:23 +00:00
feat(pulumi/examples): add generic aws ec2 instance
This commit is contained in:
2
examples/pulumi/aws/ec2 instance/.env.fish
Normal file
2
examples/pulumi/aws/ec2 instance/.env.fish
Normal file
@@ -0,0 +1,2 @@
|
||||
set -x PULUMI_BACKEND_URL 'file://.'
|
||||
set -x PULUMI_CONFIG_PASSPHRASE 'test123'
|
||||
3
examples/pulumi/aws/ec2 instance/.gitignore
vendored
Normal file
3
examples/pulumi/aws/ec2 instance/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/bin/
|
||||
/node_modules/
|
||||
/package-lock.json
|
||||
8
examples/pulumi/aws/ec2 instance/Pulumi.any.yaml
Normal file
8
examples/pulumi/aws/ec2 instance/Pulumi.any.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
encryptionsalt: v1:55yDA5Kuyzs=:v1:+kFXkziA9Bd7nNZQ:OSBtNRAVCGBXwzTtHOGA5Ti9Dz+FTQ==
|
||||
config:
|
||||
aws:region: eu-west-1
|
||||
aws:defaultTags:
|
||||
tags:
|
||||
ManagedByPulumi: true
|
||||
Owner: "somebody@example.com"
|
||||
PulumiProject: ec2-instance
|
||||
9
examples/pulumi/aws/ec2 instance/Pulumi.yaml
Normal file
9
examples/pulumi/aws/ec2 instance/Pulumi.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
name: ec2-instance
|
||||
runtime: nodejs
|
||||
description: AWS EC2 instance example
|
||||
config:
|
||||
pulumi:tags:
|
||||
value:
|
||||
pulumi:template: aws-typescript
|
||||
backend:
|
||||
url: file://.
|
||||
122
examples/pulumi/aws/ec2 instance/index.ts
Normal file
122
examples/pulumi/aws/ec2 instance/index.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import * as aws from "@pulumi/aws";
|
||||
import * as cloudinit from "@pulumi/cloudinit";
|
||||
import * as yaml from "yaml";
|
||||
|
||||
const ami = aws.ec2.getAmiOutput({
|
||||
owners: [ "amazon", ],
|
||||
nameRegex: "^al2023-ami-2023.*",
|
||||
filters: [
|
||||
{
|
||||
name: "architecture",
|
||||
values: [ "arm64" ],
|
||||
},
|
||||
{
|
||||
name: "state",
|
||||
values: [ "available" ],
|
||||
},
|
||||
],
|
||||
mostRecent: true,
|
||||
});
|
||||
const keyPair = aws.ec2.getKeyPairOutput({ keyName: "somebody-ec2Instances" });
|
||||
const subnet = aws.ec2.getSubnetOutput({
|
||||
filters: [{
|
||||
name: "tag:Name",
|
||||
values: [ "Private C" ],
|
||||
}],
|
||||
});
|
||||
|
||||
const securityGroup = new aws.ec2.SecurityGroup(
|
||||
"ec2-instance-example",
|
||||
{
|
||||
name: "Ec2InstanceExample",
|
||||
description: "Regulate communications to and from the EC2 Instance",
|
||||
tags: {
|
||||
Name: "EC2 Instance Example",
|
||||
},
|
||||
},
|
||||
);
|
||||
const role = new aws.iam.Role(
|
||||
"ec2-instance-example",
|
||||
{
|
||||
name: "Ec2InstanceExample",
|
||||
assumeRolePolicy: JSON.stringify({
|
||||
Version: "2012-10-17",
|
||||
Statement: [{
|
||||
Effect: "Allow",
|
||||
Action: "sts:AssumeRole",
|
||||
Principal: {
|
||||
Service: "ec2.amazonaws.com",
|
||||
},
|
||||
}],
|
||||
}),
|
||||
managedPolicyArns: [ "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" ],
|
||||
},
|
||||
);
|
||||
const instanceProfile = new aws.iam.InstanceProfile(
|
||||
"ec2-instance-example",
|
||||
{
|
||||
name: "Ec2InstanceExample",
|
||||
role: role.name,
|
||||
},
|
||||
);
|
||||
const userData = new cloudinit.Config(
|
||||
"ec2-instance-example",
|
||||
{
|
||||
gzip: true,
|
||||
base64Encode: true,
|
||||
parts: [
|
||||
{
|
||||
contentType: "text/cloud-config",
|
||||
content: yaml.stringify({
|
||||
package_upgrade: false,
|
||||
packages: [ "amazon-ssm-agent" ],
|
||||
runcmd: [
|
||||
"systemctl daemon-reload",
|
||||
"systemctl enable --now 'amazon-ssm-agent.service'",
|
||||
]
|
||||
}),
|
||||
filename: "cloud-config.managed-by.ssm.yml",
|
||||
},
|
||||
{
|
||||
contentType: "text/cloud-config",
|
||||
content: yaml.stringify({
|
||||
package_upgrade: false,
|
||||
packages: [ "python" ],
|
||||
}),
|
||||
filename: "cloud-config.managed-by.ansible.yml",
|
||||
mergeType: "dict(recurse_array,no_replace)+list(append)",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
new aws.ec2.Instance(
|
||||
"ec2-instance-example",
|
||||
{
|
||||
ami: ami.apply(ami => ami.id),
|
||||
iamInstanceProfile: instanceProfile.name,
|
||||
instanceType: "t4g.small",
|
||||
keyName: keyPair.apply(keyPair => keyPair.keyName!),
|
||||
rootBlockDevice: {
|
||||
volumeType: "gp3",
|
||||
volumeSize: 10,
|
||||
tags: {
|
||||
Description: "Instance root disk",
|
||||
Name: "EC2 Instance Example",
|
||||
},
|
||||
},
|
||||
subnetId: subnet.apply(subnet => subnet.id),
|
||||
tags: {
|
||||
Name: "EC2 Instance Example",
|
||||
ManagedBySsm: "true",
|
||||
ManagedByAnsible: "true",
|
||||
},
|
||||
userData: userData.rendered,
|
||||
vpcSecurityGroupIds: [ securityGroup.id ],
|
||||
},
|
||||
{
|
||||
ignoreChanges: [
|
||||
// avoid being replaced just because a new version of the base image came out
|
||||
"ami",
|
||||
],
|
||||
}
|
||||
);
|
||||
13
examples/pulumi/aws/ec2 instance/package.json
Normal file
13
examples/pulumi/aws/ec2 instance/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "ec2-instance",
|
||||
"main": "index.ts",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pulumi/aws": "^6.0.0",
|
||||
"@pulumi/cloudinit": "^1.0.0",
|
||||
"yaml": "^2.0.0"
|
||||
}
|
||||
}
|
||||
18
examples/pulumi/aws/ec2 instance/tsconfig.json
Normal file
18
examples/pulumi/aws/ec2 instance/tsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"outDir": "bin",
|
||||
"target": "es2020",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators": true,
|
||||
"pretty": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.ts"
|
||||
]
|
||||
}
|
||||
@@ -267,6 +267,7 @@ Examples:
|
||||
- [Automating DNS-challenge based LetsEncrypt certificates with AWS Route 53]
|
||||
- [Working with DB instance read replicas]
|
||||
- AWS' [CLI]
|
||||
- [Configuring EC2 Disk alert using Amazon CloudWatch]
|
||||
|
||||
### Sources
|
||||
|
||||
@@ -347,6 +348,7 @@ Examples:
|
||||
[automating dns-challenge based letsencrypt certificates with aws route 53]: https://johnrix.medium.com/automating-dns-challenge-based-letsencrypt-certificates-with-aws-route-53-8ba799dd207b
|
||||
[aws config tutorial by stephane maarek]: https://www.youtube.com/watch?v=qHdFoYSrUvk
|
||||
[aws icons]: https://aws-icons.com/
|
||||
[configuring ec2 disk alert using amazon cloudwatch]: https://medium.com/@chandinims001/configuring-ec2-disk-alert-using-amazon-cloudwatch-793807e40d72
|
||||
[date & time policy conditions at aws - 1-minute iam lesson]: https://www.youtube.com/watch?v=4wpKP1HLEXg
|
||||
[introduction to aws iam assumerole]: https://aws.plainenglish.io/introduction-to-aws-iam-assumerole-fbef3ce8e90b
|
||||
[not authorized to perform: sts:assumerole]: https://repost.aws/questions/QUOY5XngCtRyOX4Desaygz8Q/not-authorized-to-perform-sts-assumerole
|
||||
|
||||
@@ -29,22 +29,39 @@ aws ssm start-session \
|
||||
aws ssm send-command \
|
||||
--instance-ids 'i-0123456789abcdef0' \
|
||||
--document-name 'AWS-RunShellScript' \
|
||||
--parameters commands="echo 'hallo!'"
|
||||
--parameters "commands="echo 'hallo'"
|
||||
|
||||
# Wait for commands execution.
|
||||
aws ssm wait command-executed --instance-id 'i-0123456789abcdef0' --command-id 'abcdef01-2345-abcd-6789-abcdef012345'
|
||||
|
||||
# Get commands results.
|
||||
aws ssm get-command-invocation --instance-id 'i-0123456789abcdef0' --command-id 'abcdef01-2345-abcd-6789-abcdef012345'
|
||||
aws ssm get-command-invocation \
|
||||
--instance-id 'i-0123456789abcdef0' --command-id 'abcdef01-2345-abcd-6789-abcdef012345' \
|
||||
--query '{"status": Status, "rc": ResponseCode, "stdout": StandardOutputContent, "stderr": StandardErrorContent}'
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>Real world use cases</summary>
|
||||
|
||||
Also check out the [snippets].
|
||||
|
||||
```sh
|
||||
# Connect to instances if they are available.
|
||||
instance_id='i-08fc83ad07487d72f' \
|
||||
&& eval $(aws ssm get-connection-status --target "$instance_id" --query "Status=='connected'" --output text) \
|
||||
&& eval $(aws ssm get-connection-status --target "$instance_id" --query "Status=='connected'" --output 'text') \
|
||||
&& aws ssm start-session --target "$instance_id" \
|
||||
|| (echo "instance ${instance_id} not available" >&2 && false)
|
||||
|
||||
aws ssm send-command --instance-ids "i-08fc83ad07487d72f" \
|
||||
--document-name "AWS-RunShellScript" --parameters commands="echo 'hallo!'"
|
||||
# Run commands and get their output.
|
||||
instance_id='i-0915612f182914822' \
|
||||
&& command_id=$(aws ssm send-command --instance-ids "$instance_id" \
|
||||
--document-name 'AWS-RunShellScript' --parameters 'commands="echo hallo"' \
|
||||
--query 'Command.CommandId' --output 'text') \
|
||||
&& aws ssm wait command-executed --command-id "$command_id" --instance-id "$instance_id" \
|
||||
&& aws ssm get-command-invocation --command-id "$command_id" --instance-id "$instance_id" \
|
||||
--query '{"status": Status, "rc": ResponseCode, "stdout": StandardOutputContent, "stderr": StandardErrorContent}'
|
||||
```
|
||||
|
||||
</details>
|
||||
@@ -267,6 +284,7 @@ $ sudo ssm-cli get-diagnostics --output 'table'
|
||||
[amazon web services]: README.md
|
||||
[cli]: cli.md
|
||||
[ec2]: ec2.md
|
||||
[snippets]: ../../../snippets/aws.fish
|
||||
|
||||
<!-- Upstream -->
|
||||
[aws_ssm connection plugin notes]: https://docs.ansible.com/ansible/latest/collections/community/aws/aws_ssm_connection.html#notes
|
||||
|
||||
@@ -73,3 +73,26 @@ aws ec2 describe-images --output 'yaml' \
|
||||
aws iam list-instance-profiles | grep -i 'ssm'
|
||||
|
||||
sudo ssm-cli get-diagnostics --output 'table'
|
||||
|
||||
# Check instances are available
|
||||
aws ssm get-connection-status --target "i-0915612ff82914822" --query "Status=='connected'" --output 'text'
|
||||
|
||||
# Connect to instances if they are available
|
||||
instance_id='i-08fc83ad07487d72f' \
|
||||
&& eval $(aws ssm get-connection-status --target "$instance_id" --query "Status=='connected'" --output 'text') \
|
||||
&& aws ssm start-session --target "$instance_id" \
|
||||
|| (echo "instance ${instance_id} not available" >&2 && false)
|
||||
|
||||
# Send commands
|
||||
aws ssm send-command --instance-ids 'i-08fc83ad07487d72f' --document-name 'AWS-RunShellScript' --parameters "commands='echo hallo'"
|
||||
aws ssm wait command-executed --command-id 'e5f7ca0e-4d74-4316-84be-9ccaf3ae1f70' --instance-id 'i-08fc83ad07487d72f'
|
||||
aws ssm get-command-invocation --command-id 'e5f7ca0e-4d74-4316-84be-9ccaf3ae1f70' --instance-id 'i-08fc83ad07487d72f'
|
||||
|
||||
# Run commands and get their output.
|
||||
set instance_id 'i-0915612f182914822' \
|
||||
&& set command_id (aws ssm send-command --instance-ids "$instance_id" \
|
||||
--document-name 'AWS-RunShellScript' --parameters 'commands="echo hallo"' \
|
||||
--query 'Command.CommandId' --output 'text') \
|
||||
&& aws ssm wait command-executed --command-id "$command_id" --instance-id "$instance_id" \
|
||||
&& aws ssm get-command-invocation --command-id "$command_id" --instance-id "$instance_id" \
|
||||
--query '{"status": Status, "rc": ResponseCode, "stdout": StandardOutputContent, "stderr": StandardErrorContent}'
|
||||
|
||||
@@ -2,3 +2,8 @@
|
||||
|
||||
sudo systemctl enable --now 'gitlab-runner'
|
||||
sudo journalctl -xefu 'gitlab-runner'
|
||||
|
||||
sudo hostnamectl
|
||||
sudo hostnamectl status --static
|
||||
|
||||
sudo hostnamectl set-hostname --pretty 'prometheus'
|
||||
|
||||
Reference in New Issue
Block a user